fluxfem 0.1.1a0__py3-none-any.whl → 0.1.4__py3-none-any.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.
- fluxfem/__init__.py +68 -161
- fluxfem/core/__init__.py +59 -31
- fluxfem/core/context_types.py +36 -0
- fluxfem/core/forms.py +5 -1
- fluxfem/core/weakform.py +747 -307
- fluxfem/{helpers_num.py → helpers_ts.py} +1 -1
- fluxfem/helpers_wf.py +6 -0
- fluxfem/mesh/base.py +6 -1
- fluxfem/mesh/hex.py +1 -0
- fluxfem/mesh/io.py +2 -0
- {fluxfem-0.1.1a0.dist-info → fluxfem-0.1.4.dist-info}/METADATA +39 -23
- {fluxfem-0.1.1a0.dist-info → fluxfem-0.1.4.dist-info}/RECORD +14 -13
- {fluxfem-0.1.1a0.dist-info → fluxfem-0.1.4.dist-info}/WHEEL +1 -1
- {fluxfem-0.1.1a0.dist-info/licenses → fluxfem-0.1.4.dist-info}/LICENSE +0 -0
fluxfem/__init__.py
CHANGED
|
@@ -1,159 +1,6 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
FESpacePytree,
|
|
5
|
-
Expr,
|
|
6
|
-
FieldRef,
|
|
7
|
-
ParamRef,
|
|
8
|
-
trial_ref,
|
|
9
|
-
test_ref,
|
|
10
|
-
unknown_ref,
|
|
11
|
-
Params,
|
|
12
|
-
LinearForm,
|
|
13
|
-
BilinearForm,
|
|
14
|
-
ResidualForm,
|
|
15
|
-
MixedWeakForm,
|
|
16
|
-
compile_bilinear,
|
|
17
|
-
compile_linear,
|
|
18
|
-
compile_residual,
|
|
19
|
-
compile_surface_linear,
|
|
20
|
-
compile_mixed_residual,
|
|
21
|
-
sdot,
|
|
22
|
-
dOmega,
|
|
23
|
-
FormContext,
|
|
24
|
-
MixedFormContext,
|
|
25
|
-
FieldPair,
|
|
26
|
-
ElementVector,
|
|
27
|
-
vector_load_form,
|
|
28
|
-
make_space,
|
|
29
|
-
make_space_pytree,
|
|
30
|
-
make_hex_basis,
|
|
31
|
-
make_hex_basis_pytree,
|
|
32
|
-
make_hex_space,
|
|
33
|
-
make_hex_space_pytree,
|
|
34
|
-
make_hex20_basis,
|
|
35
|
-
make_hex20_basis_pytree,
|
|
36
|
-
make_hex20_space,
|
|
37
|
-
make_hex20_space_pytree,
|
|
38
|
-
make_hex27_basis,
|
|
39
|
-
make_hex27_basis_pytree,
|
|
40
|
-
make_hex27_space,
|
|
41
|
-
make_hex27_space_pytree,
|
|
42
|
-
make_tet_basis,
|
|
43
|
-
make_tet_basis_pytree,
|
|
44
|
-
make_tet_space,
|
|
45
|
-
make_tet_space_pytree,
|
|
46
|
-
make_tet10_basis,
|
|
47
|
-
make_tet10_basis_pytree,
|
|
48
|
-
make_tet10_space,
|
|
49
|
-
make_tet10_space_pytree,
|
|
50
|
-
make_element_residual_kernel,
|
|
51
|
-
make_element_jacobian_kernel,
|
|
52
|
-
element_residual,
|
|
53
|
-
element_jacobian,
|
|
54
|
-
make_sparsity_pattern,
|
|
55
|
-
assemble_functional,
|
|
56
|
-
assemble_mass_matrix,
|
|
57
|
-
scalar_body_force_form,
|
|
58
|
-
make_scalar_body_force_form,
|
|
59
|
-
constant_body_force_form,
|
|
60
|
-
vector_body_force_form,
|
|
61
|
-
BaseMeshPytree,
|
|
62
|
-
bbox_predicate,
|
|
63
|
-
plane_predicate,
|
|
64
|
-
axis_plane_predicate,
|
|
65
|
-
slab_predicate,
|
|
66
|
-
HexMesh,
|
|
67
|
-
HexMeshPytree,
|
|
68
|
-
StructuredHexBox,
|
|
69
|
-
SurfaceMesh,
|
|
70
|
-
SurfaceMeshPytree,
|
|
71
|
-
load_gmsh_mesh,
|
|
72
|
-
load_gmsh_hex_mesh,
|
|
73
|
-
load_gmsh_tet_mesh,
|
|
74
|
-
make_surface_from_facets,
|
|
75
|
-
TetMesh,
|
|
76
|
-
TetMeshPytree,
|
|
77
|
-
StructuredTetBox,
|
|
78
|
-
StructuredTetTensorBox,
|
|
79
|
-
tag_axis_minmax_facets,
|
|
80
|
-
HexTriLinearBasis,
|
|
81
|
-
HexTriLinearBasisPytree,
|
|
82
|
-
HexSerendipityBasis20,
|
|
83
|
-
HexSerendipityBasis20Pytree,
|
|
84
|
-
HexTriQuadraticBasis27,
|
|
85
|
-
HexTriQuadraticBasis27Pytree,
|
|
86
|
-
TetLinearBasis,
|
|
87
|
-
TetLinearBasisPytree,
|
|
88
|
-
TetQuadraticBasis10,
|
|
89
|
-
TetQuadraticBasis10Pytree,
|
|
90
|
-
MeshData,
|
|
91
|
-
BasisData,
|
|
92
|
-
SpaceData,
|
|
93
|
-
MeshData,
|
|
94
|
-
BasisData,
|
|
95
|
-
SpaceData,
|
|
96
|
-
lame_parameters,
|
|
97
|
-
isotropic_3d_D,
|
|
98
|
-
spdirect_solve_cpu,
|
|
99
|
-
spdirect_solve_gpu,
|
|
100
|
-
spdirect_solve_jax,
|
|
101
|
-
coo_to_csr,
|
|
102
|
-
SparsityPattern,
|
|
103
|
-
FluxSparseMatrix,
|
|
104
|
-
LinearSolver,
|
|
105
|
-
NonlinearSolver,
|
|
106
|
-
enforce_dirichlet_dense,
|
|
107
|
-
enforce_dirichlet_sparse,
|
|
108
|
-
free_dofs,
|
|
109
|
-
condense_dirichlet_fluxsparse,
|
|
110
|
-
condense_dirichlet_dense,
|
|
111
|
-
expand_dirichlet_solution,
|
|
112
|
-
cg_solve,
|
|
113
|
-
cg_solve_jax,
|
|
114
|
-
NonlinearAnalysis,
|
|
115
|
-
NewtonLoopConfig,
|
|
116
|
-
LoadStepResult,
|
|
117
|
-
NewtonSolveRunner,
|
|
118
|
-
solve_nonlinear,
|
|
119
|
-
LinearAnalysis,
|
|
120
|
-
LinearSolveConfig,
|
|
121
|
-
LinearStepResult,
|
|
122
|
-
LinearSolveRunner,
|
|
123
|
-
newton_solve,
|
|
124
|
-
SurfaceFormField,
|
|
125
|
-
SurfaceFormContext,
|
|
126
|
-
vector_surface_load_form,
|
|
127
|
-
make_vector_surface_load_form,
|
|
128
|
-
assemble_surface_linear_form,
|
|
129
|
-
)
|
|
130
|
-
from .tools.visualizer import write_vtu, write_displacement_vtu
|
|
131
|
-
from .tools.jit import make_jitted_residual, make_jitted_jacobian
|
|
132
|
-
from .physics import (
|
|
133
|
-
linear_elasticity_form,
|
|
134
|
-
vector_body_force_form,
|
|
135
|
-
constant_body_force_vector_form,
|
|
136
|
-
diffusion_form,
|
|
137
|
-
dot,
|
|
138
|
-
ddot,
|
|
139
|
-
transpose_last2,
|
|
140
|
-
sym_grad,
|
|
141
|
-
sym_grad_u,
|
|
142
|
-
right_cauchy_green,
|
|
143
|
-
green_lagrange_strain,
|
|
144
|
-
deformation_gradient,
|
|
145
|
-
pk2_neo_hookean,
|
|
146
|
-
neo_hookean_residual_form,
|
|
147
|
-
make_elastic_point_data,
|
|
148
|
-
write_elastic_vtu,
|
|
149
|
-
make_point_data_displacement,
|
|
150
|
-
write_point_data_vtu,
|
|
151
|
-
interpolate_at_points,
|
|
152
|
-
principal_stresses,
|
|
153
|
-
principal_sum,
|
|
154
|
-
max_shear_stress,
|
|
155
|
-
von_mises_stress,
|
|
156
|
-
)
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import importlib
|
|
157
4
|
|
|
158
5
|
__all__ = [
|
|
159
6
|
"FESpaceBase",
|
|
@@ -175,10 +22,13 @@ __all__ = [
|
|
|
175
22
|
"compile_residual",
|
|
176
23
|
"compile_surface_linear",
|
|
177
24
|
"compile_mixed_residual",
|
|
25
|
+
"outer",
|
|
178
26
|
"sdot",
|
|
179
27
|
"dOmega",
|
|
180
28
|
"FormContext",
|
|
181
29
|
"MixedFormContext",
|
|
30
|
+
"VolumeContext",
|
|
31
|
+
"SurfaceContext",
|
|
182
32
|
"FieldPair",
|
|
183
33
|
"ElementVector",
|
|
184
34
|
"vector_load_form",
|
|
@@ -243,6 +93,7 @@ __all__ = [
|
|
|
243
93
|
"vector_surface_load_form",
|
|
244
94
|
"make_vector_surface_load_form",
|
|
245
95
|
"assemble_surface_linear_form",
|
|
96
|
+
"tag_axis_minmax_facets",
|
|
246
97
|
"load_gmsh_mesh",
|
|
247
98
|
"load_gmsh_hex_mesh",
|
|
248
99
|
"load_gmsh_tet_mesh",
|
|
@@ -307,11 +158,71 @@ __all__ = [
|
|
|
307
158
|
"von_mises_stress",
|
|
308
159
|
]
|
|
309
160
|
|
|
161
|
+
_PHYSICS_EXPORTS = {
|
|
162
|
+
"lame_parameters",
|
|
163
|
+
"isotropic_3d_D",
|
|
164
|
+
"linear_elasticity_form",
|
|
165
|
+
"vector_body_force_form",
|
|
166
|
+
"constant_body_force_vector_form",
|
|
167
|
+
"diffusion_form",
|
|
168
|
+
"dot",
|
|
169
|
+
"ddot",
|
|
170
|
+
"transpose_last2",
|
|
171
|
+
"sym_grad",
|
|
172
|
+
"sym_grad_u",
|
|
173
|
+
"right_cauchy_green",
|
|
174
|
+
"green_lagrange_strain",
|
|
175
|
+
"deformation_gradient",
|
|
176
|
+
"pk2_neo_hookean",
|
|
177
|
+
"neo_hookean_residual_form",
|
|
178
|
+
"make_elastic_point_data",
|
|
179
|
+
"write_elastic_vtu",
|
|
180
|
+
"make_point_data_displacement",
|
|
181
|
+
"write_point_data_vtu",
|
|
182
|
+
"interpolate_at_points",
|
|
183
|
+
"principal_stresses",
|
|
184
|
+
"principal_sum",
|
|
185
|
+
"max_shear_stress",
|
|
186
|
+
"von_mises_stress",
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
_TOOLS_VIS_EXPORTS = {
|
|
190
|
+
"write_vtu",
|
|
191
|
+
"write_displacement_vtu",
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
_TOOLS_JIT_EXPORTS = {
|
|
195
|
+
"make_jitted_residual",
|
|
196
|
+
"make_jitted_jacobian",
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
_CORE_EXPORTS = set(__all__) - _PHYSICS_EXPORTS - _TOOLS_VIS_EXPORTS - _TOOLS_JIT_EXPORTS
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def __getattr__(name: str):
|
|
203
|
+
if name in _PHYSICS_EXPORTS:
|
|
204
|
+
module = importlib.import_module(".physics", __name__)
|
|
205
|
+
elif name in _TOOLS_VIS_EXPORTS:
|
|
206
|
+
module = importlib.import_module(".tools.visualizer", __name__)
|
|
207
|
+
elif name in _TOOLS_JIT_EXPORTS:
|
|
208
|
+
module = importlib.import_module(".tools.jit", __name__)
|
|
209
|
+
elif name in _CORE_EXPORTS:
|
|
210
|
+
module = importlib.import_module(".core", __name__)
|
|
211
|
+
else:
|
|
212
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
213
|
+
|
|
214
|
+
value = getattr(module, name)
|
|
215
|
+
globals()[name] = value
|
|
216
|
+
return value
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def __dir__():
|
|
220
|
+
return sorted(set(globals()) | set(__all__))
|
|
221
|
+
|
|
310
222
|
|
|
311
223
|
try:
|
|
312
224
|
from importlib.metadata import version, PackageNotFoundError
|
|
313
225
|
except ImportError:
|
|
314
|
-
# old python
|
|
315
226
|
from importlib_metadata import version, PackageNotFoundError
|
|
316
227
|
|
|
317
228
|
|
|
@@ -320,21 +231,17 @@ def read_version_from_pyproject():
|
|
|
320
231
|
import re
|
|
321
232
|
|
|
322
233
|
root = pathlib.Path(__file__).resolve().parent.parent
|
|
323
|
-
# while root != root.parent and depth < max_depth:
|
|
324
234
|
pyproject_path = root / "pyproject.toml"
|
|
325
235
|
if pyproject_path.exists():
|
|
326
236
|
content = pyproject_path.read_text()
|
|
327
237
|
match = re.search(r'version\s*=\s*"(.*?)"', content)
|
|
328
238
|
if match:
|
|
329
239
|
return match.group(1)
|
|
330
|
-
# root = root.parent
|
|
331
|
-
# depth += 1
|
|
332
240
|
return "0.0.0"
|
|
333
241
|
|
|
334
242
|
|
|
335
243
|
def get_version(package_name):
|
|
336
244
|
try:
|
|
337
|
-
# print("version-", version(package_name))
|
|
338
245
|
return version(package_name)
|
|
339
246
|
except PackageNotFoundError:
|
|
340
247
|
return read_version_from_pyproject()
|
fluxfem/core/__init__.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from .forms import FormContext, MixedFormContext, FieldPair, ElementVector, vector_load_form
|
|
2
|
+
from .context_types import VolumeContext, SurfaceContext
|
|
2
3
|
from .space import (
|
|
3
4
|
FESpaceBase,
|
|
4
5
|
FESpace,
|
|
@@ -71,6 +72,7 @@ from .weakform import (
|
|
|
71
72
|
compile_mixed_residual,
|
|
72
73
|
grad,
|
|
73
74
|
sym_grad,
|
|
75
|
+
outer,
|
|
74
76
|
dot,
|
|
75
77
|
sdot,
|
|
76
78
|
ddot,
|
|
@@ -86,6 +88,8 @@ from .weakform import (
|
|
|
86
88
|
transpose,
|
|
87
89
|
log,
|
|
88
90
|
transpose_last2,
|
|
91
|
+
matmul,
|
|
92
|
+
matmul_std,
|
|
89
93
|
einsum,
|
|
90
94
|
)
|
|
91
95
|
from ..mesh import (
|
|
@@ -121,39 +125,56 @@ from .basis import (
|
|
|
121
125
|
TetQuadraticBasis10,
|
|
122
126
|
TetQuadraticBasis10Pytree,
|
|
123
127
|
)
|
|
128
|
+
import importlib
|
|
129
|
+
|
|
124
130
|
from ..physics import lame_parameters, isotropic_3d_D
|
|
125
131
|
from .solver import spdirect_solve_cpu, spdirect_solve_gpu, spdirect_solve_jax, coo_to_csr
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
132
|
+
|
|
133
|
+
_SOLVER_EXPORTS = {
|
|
134
|
+
"SparsityPattern",
|
|
135
|
+
"FluxSparseMatrix",
|
|
136
|
+
"LinearSolver",
|
|
137
|
+
"NonlinearSolver",
|
|
138
|
+
"enforce_dirichlet_dense",
|
|
139
|
+
"enforce_dirichlet_sparse",
|
|
140
|
+
"free_dofs",
|
|
141
|
+
"condense_dirichlet_fluxsparse",
|
|
142
|
+
"condense_dirichlet_dense",
|
|
143
|
+
"expand_dirichlet_solution",
|
|
144
|
+
"cg_solve",
|
|
145
|
+
"cg_solve_jax",
|
|
146
|
+
"NonlinearAnalysis",
|
|
147
|
+
"NewtonLoopConfig",
|
|
148
|
+
"LoadStepResult",
|
|
149
|
+
"NewtonSolveRunner",
|
|
150
|
+
"solve_nonlinear",
|
|
151
|
+
"LinearAnalysis",
|
|
152
|
+
"LinearSolveConfig",
|
|
153
|
+
"LinearStepResult",
|
|
154
|
+
"LinearSolveRunner",
|
|
155
|
+
"newton_solve",
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
_SOLVER_BC_EXPORTS = {
|
|
159
|
+
"SurfaceFormField",
|
|
160
|
+
"SurfaceFormContext",
|
|
161
|
+
"vector_surface_load_form",
|
|
162
|
+
"make_vector_surface_load_form",
|
|
163
|
+
"assemble_surface_linear_form",
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def __getattr__(name: str):
|
|
168
|
+
if name in _SOLVER_EXPORTS:
|
|
169
|
+
module = importlib.import_module("..solver", __name__)
|
|
170
|
+
elif name in _SOLVER_BC_EXPORTS:
|
|
171
|
+
module = importlib.import_module("..solver.bc", __name__)
|
|
172
|
+
else:
|
|
173
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
174
|
+
|
|
175
|
+
value = getattr(module, name)
|
|
176
|
+
globals()[name] = value
|
|
177
|
+
return value
|
|
157
178
|
|
|
158
179
|
__all__ = [
|
|
159
180
|
"FESpace",
|
|
@@ -161,6 +182,10 @@ __all__ = [
|
|
|
161
182
|
"FESpacePytree",
|
|
162
183
|
"FormContext",
|
|
163
184
|
"MixedFormContext",
|
|
185
|
+
"VolumeContext",
|
|
186
|
+
"SurfaceContext",
|
|
187
|
+
"VolumeContext",
|
|
188
|
+
"SurfaceContext",
|
|
164
189
|
"FieldPair",
|
|
165
190
|
"ElementVector",
|
|
166
191
|
"vector_load_form",
|
|
@@ -229,6 +254,7 @@ __all__ = [
|
|
|
229
254
|
"compile_mixed_residual",
|
|
230
255
|
"grad",
|
|
231
256
|
"sym_grad",
|
|
257
|
+
"outer",
|
|
232
258
|
"dot",
|
|
233
259
|
"sdot",
|
|
234
260
|
"ddot",
|
|
@@ -244,6 +270,8 @@ __all__ = [
|
|
|
244
270
|
"transpose",
|
|
245
271
|
"log",
|
|
246
272
|
"transpose_last2",
|
|
273
|
+
"matmul",
|
|
274
|
+
"matmul_std",
|
|
247
275
|
"einsum",
|
|
248
276
|
"HexMesh",
|
|
249
277
|
"HexMeshPytree",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Protocol, TypeAlias, runtime_checkable
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@runtime_checkable
|
|
7
|
+
class VolumeContext(Protocol):
|
|
8
|
+
"""Minimum interface for volume weak-form evaluation."""
|
|
9
|
+
|
|
10
|
+
test: Any
|
|
11
|
+
trial: Any
|
|
12
|
+
w: Any
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@runtime_checkable
|
|
16
|
+
class SurfaceContext(Protocol):
|
|
17
|
+
"""Minimum interface for surface weak-form evaluation."""
|
|
18
|
+
|
|
19
|
+
v: Any
|
|
20
|
+
w: Any
|
|
21
|
+
detJ: Any
|
|
22
|
+
normal: Any
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@runtime_checkable
|
|
26
|
+
class FormFieldLike(Protocol):
|
|
27
|
+
"""Minimum interface for form fields used in weak-form evaluation."""
|
|
28
|
+
|
|
29
|
+
N: Any
|
|
30
|
+
gradN: Any
|
|
31
|
+
detJ: Any
|
|
32
|
+
value_dim: int
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
UElement: TypeAlias = Any
|
|
36
|
+
ParamsLike: TypeAlias = Any
|
fluxfem/core/forms.py
CHANGED
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import jax
|
|
4
4
|
import jax.numpy as jnp
|
|
5
5
|
from dataclasses import dataclass
|
|
6
|
+
from typing import TYPE_CHECKING, TypeAlias
|
|
6
7
|
|
|
7
8
|
from .basis import Basis3D
|
|
8
9
|
|
|
@@ -119,7 +120,10 @@ class VectorFormField:
|
|
|
119
120
|
return cls(N, elem_coords, aux["basis"], aux["value_dim"], gradN, detJ)
|
|
120
121
|
|
|
121
122
|
|
|
122
|
-
|
|
123
|
+
if TYPE_CHECKING:
|
|
124
|
+
FormFieldLike: TypeAlias = ScalarFormField | VectorFormField
|
|
125
|
+
else:
|
|
126
|
+
FormFieldLike = object
|
|
123
127
|
|
|
124
128
|
|
|
125
129
|
def vector_load_form(field: FormFieldLike, load_vec: jnp.ndarray) -> jnp.ndarray:
|