warp-lang 1.4.1__py3-none-manylinux2014_aarch64.whl → 1.5.0__py3-none-manylinux2014_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.

Files changed (164) hide show
  1. warp/__init__.py +4 -0
  2. warp/autograd.py +43 -8
  3. warp/bin/warp-clang.so +0 -0
  4. warp/bin/warp.so +0 -0
  5. warp/build.py +21 -2
  6. warp/build_dll.py +23 -6
  7. warp/builtins.py +1920 -111
  8. warp/codegen.py +186 -62
  9. warp/config.py +2 -2
  10. warp/context.py +322 -73
  11. warp/examples/assets/pixel.jpg +0 -0
  12. warp/examples/benchmarks/benchmark_cloth_paddle.py +86 -0
  13. warp/examples/benchmarks/benchmark_gemm.py +121 -0
  14. warp/examples/benchmarks/benchmark_interop_paddle.py +158 -0
  15. warp/examples/benchmarks/benchmark_tile.py +179 -0
  16. warp/examples/core/example_dem.py +2 -1
  17. warp/examples/core/example_mesh_intersect.py +3 -3
  18. warp/examples/fem/example_adaptive_grid.py +37 -10
  19. warp/examples/fem/example_apic_fluid.py +3 -2
  20. warp/examples/fem/example_convection_diffusion_dg.py +4 -5
  21. warp/examples/fem/example_deformed_geometry.py +1 -1
  22. warp/examples/fem/example_diffusion_3d.py +47 -4
  23. warp/examples/fem/example_distortion_energy.py +220 -0
  24. warp/examples/fem/example_magnetostatics.py +127 -85
  25. warp/examples/fem/example_nonconforming_contact.py +5 -5
  26. warp/examples/fem/example_stokes.py +3 -1
  27. warp/examples/fem/example_streamlines.py +12 -19
  28. warp/examples/fem/utils.py +38 -15
  29. warp/examples/optim/example_walker.py +2 -2
  30. warp/examples/sim/example_cloth.py +2 -25
  31. warp/examples/sim/example_jacobian_ik.py +6 -2
  32. warp/examples/sim/example_quadruped.py +2 -1
  33. warp/examples/tile/example_tile_convolution.py +58 -0
  34. warp/examples/tile/example_tile_fft.py +47 -0
  35. warp/examples/tile/example_tile_filtering.py +105 -0
  36. warp/examples/tile/example_tile_matmul.py +79 -0
  37. warp/examples/tile/example_tile_mlp.py +375 -0
  38. warp/fem/__init__.py +8 -0
  39. warp/fem/cache.py +16 -12
  40. warp/fem/dirichlet.py +1 -1
  41. warp/fem/domain.py +44 -1
  42. warp/fem/field/__init__.py +1 -2
  43. warp/fem/field/field.py +31 -19
  44. warp/fem/field/nodal_field.py +101 -49
  45. warp/fem/field/virtual.py +794 -0
  46. warp/fem/geometry/__init__.py +2 -2
  47. warp/fem/geometry/deformed_geometry.py +3 -105
  48. warp/fem/geometry/element.py +13 -0
  49. warp/fem/geometry/geometry.py +165 -5
  50. warp/fem/geometry/grid_2d.py +3 -6
  51. warp/fem/geometry/grid_3d.py +31 -28
  52. warp/fem/geometry/hexmesh.py +3 -46
  53. warp/fem/geometry/nanogrid.py +3 -2
  54. warp/fem/geometry/{quadmesh_2d.py → quadmesh.py} +280 -159
  55. warp/fem/geometry/tetmesh.py +2 -43
  56. warp/fem/geometry/{trimesh_2d.py → trimesh.py} +354 -186
  57. warp/fem/integrate.py +683 -261
  58. warp/fem/linalg.py +404 -0
  59. warp/fem/operator.py +101 -18
  60. warp/fem/polynomial.py +5 -5
  61. warp/fem/quadrature/quadrature.py +45 -21
  62. warp/fem/space/__init__.py +45 -11
  63. warp/fem/space/basis_function_space.py +451 -0
  64. warp/fem/space/basis_space.py +58 -11
  65. warp/fem/space/function_space.py +146 -5
  66. warp/fem/space/grid_2d_function_space.py +80 -66
  67. warp/fem/space/grid_3d_function_space.py +113 -68
  68. warp/fem/space/hexmesh_function_space.py +96 -108
  69. warp/fem/space/nanogrid_function_space.py +62 -110
  70. warp/fem/space/quadmesh_function_space.py +208 -0
  71. warp/fem/space/shape/__init__.py +45 -7
  72. warp/fem/space/shape/cube_shape_function.py +328 -54
  73. warp/fem/space/shape/shape_function.py +10 -1
  74. warp/fem/space/shape/square_shape_function.py +328 -60
  75. warp/fem/space/shape/tet_shape_function.py +269 -19
  76. warp/fem/space/shape/triangle_shape_function.py +238 -19
  77. warp/fem/space/tetmesh_function_space.py +69 -37
  78. warp/fem/space/topology.py +38 -0
  79. warp/fem/space/trimesh_function_space.py +179 -0
  80. warp/fem/utils.py +6 -331
  81. warp/jax_experimental.py +3 -1
  82. warp/native/array.h +55 -40
  83. warp/native/builtin.h +124 -43
  84. warp/native/bvh.h +4 -0
  85. warp/native/coloring.cpp +600 -0
  86. warp/native/cuda_util.cpp +14 -0
  87. warp/native/cuda_util.h +2 -1
  88. warp/native/fabric.h +8 -0
  89. warp/native/hashgrid.h +4 -0
  90. warp/native/marching.cu +8 -0
  91. warp/native/mat.h +14 -3
  92. warp/native/mathdx.cpp +59 -0
  93. warp/native/mesh.h +4 -0
  94. warp/native/range.h +13 -1
  95. warp/native/reduce.cpp +9 -1
  96. warp/native/reduce.cu +7 -0
  97. warp/native/runlength_encode.cpp +9 -1
  98. warp/native/runlength_encode.cu +7 -1
  99. warp/native/scan.cpp +8 -0
  100. warp/native/scan.cu +8 -0
  101. warp/native/scan.h +8 -1
  102. warp/native/sparse.cpp +8 -0
  103. warp/native/sparse.cu +8 -0
  104. warp/native/temp_buffer.h +7 -0
  105. warp/native/tile.h +1857 -0
  106. warp/native/tile_gemm.h +341 -0
  107. warp/native/tile_reduce.h +210 -0
  108. warp/native/volume_builder.cu +8 -0
  109. warp/native/volume_builder.h +8 -0
  110. warp/native/warp.cpp +10 -2
  111. warp/native/warp.cu +369 -15
  112. warp/native/warp.h +12 -2
  113. warp/optim/adam.py +39 -4
  114. warp/paddle.py +29 -12
  115. warp/render/render_opengl.py +137 -65
  116. warp/sim/graph_coloring.py +292 -0
  117. warp/sim/integrator_euler.py +4 -2
  118. warp/sim/integrator_featherstone.py +115 -44
  119. warp/sim/integrator_vbd.py +6 -0
  120. warp/sim/model.py +90 -17
  121. warp/stubs.py +651 -85
  122. warp/tape.py +12 -7
  123. warp/tests/assets/pixel.npy +0 -0
  124. warp/tests/aux_test_instancing_gc.py +18 -0
  125. warp/tests/test_array.py +207 -48
  126. warp/tests/test_closest_point_edge_edge.py +8 -8
  127. warp/tests/test_codegen.py +120 -1
  128. warp/tests/test_codegen_instancing.py +30 -0
  129. warp/tests/test_collision.py +110 -0
  130. warp/tests/test_coloring.py +241 -0
  131. warp/tests/test_context.py +34 -0
  132. warp/tests/test_examples.py +18 -4
  133. warp/tests/test_fabricarray.py +33 -0
  134. warp/tests/test_fem.py +453 -113
  135. warp/tests/test_func.py +48 -1
  136. warp/tests/test_generics.py +52 -0
  137. warp/tests/test_iter.py +68 -0
  138. warp/tests/test_mat_scalar_ops.py +1 -1
  139. warp/tests/test_mesh_query_point.py +5 -4
  140. warp/tests/test_module_hashing.py +23 -0
  141. warp/tests/test_paddle.py +27 -87
  142. warp/tests/test_print.py +191 -1
  143. warp/tests/test_spatial.py +1 -1
  144. warp/tests/test_tile.py +700 -0
  145. warp/tests/test_tile_mathdx.py +144 -0
  146. warp/tests/test_tile_mlp.py +383 -0
  147. warp/tests/test_tile_reduce.py +374 -0
  148. warp/tests/test_tile_shared_memory.py +190 -0
  149. warp/tests/test_vbd.py +12 -20
  150. warp/tests/test_volume.py +43 -0
  151. warp/tests/unittest_suites.py +23 -2
  152. warp/tests/unittest_utils.py +4 -0
  153. warp/types.py +339 -73
  154. warp/utils.py +22 -1
  155. {warp_lang-1.4.1.dist-info → warp_lang-1.5.0.dist-info}/METADATA +33 -7
  156. {warp_lang-1.4.1.dist-info → warp_lang-1.5.0.dist-info}/RECORD +159 -132
  157. {warp_lang-1.4.1.dist-info → warp_lang-1.5.0.dist-info}/WHEEL +1 -1
  158. warp/fem/field/test.py +0 -180
  159. warp/fem/field/trial.py +0 -183
  160. warp/fem/space/collocated_function_space.py +0 -102
  161. warp/fem/space/quadmesh_2d_function_space.py +0 -261
  162. warp/fem/space/trimesh_2d_function_space.py +0 -153
  163. {warp_lang-1.4.1.dist-info → warp_lang-1.5.0.dist-info}/LICENSE.md +0 -0
  164. {warp_lang-1.4.1.dist-info → warp_lang-1.5.0.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