pyfebio 0.1.0__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.

Potentially problematic release.


This version of pyfebio might be problematic. Click here for more details.

pyfebio/rigid.py ADDED
@@ -0,0 +1,275 @@
1
+ from typing import Literal
2
+
3
+ from pydantic_xml import BaseXmlModel, attr, element
4
+
5
+ from ._types import (
6
+ StringFloatVec3,
7
+ )
8
+
9
+
10
+ class Value(BaseXmlModel, validate_assignment=True):
11
+ lc: int = attr()
12
+ text: float = 1.0
13
+
14
+
15
+ class RigidFixed(BaseXmlModel, tag="rigid_bc", validate_assignment=True):
16
+ """ """
17
+
18
+ type: Literal["rigid_fixed"] = attr(default="rigid_fixed", frozen=True)
19
+ rb: str = element()
20
+ Rx_dof: Literal[0, 1] = element(default=0)
21
+ Ry_dof: Literal[0, 1] = element(default=0)
22
+ Rz_dof: Literal[0, 1] = element(default=0)
23
+ Ru_dof: Literal[0, 1] = element(default=0)
24
+ Rv_dof: Literal[0, 1] = element(default=0)
25
+ Rw_dof: Literal[0, 1] = element(default=0)
26
+
27
+
28
+ class RigidPrescribed(BaseXmlModel, tag="rigid_bc", validate_assignment=True):
29
+ type: Literal["rigid_displacement", "rigid_rotation"] = attr(default="rigid_displacement", frozen=True)
30
+ rb: str = element()
31
+ dof: Literal["x", "y", "z", "Ru", "Rv", "Rw"] = element()
32
+ relative: Literal[0, 1] = element(default=0)
33
+ value: Value = element()
34
+
35
+
36
+ class RigidBodyRotationVector(BaseXmlModel, tag="rigid_bc", validate_assignment=True):
37
+ class X(BaseXmlModel, tag="vx", validate_assignment=True):
38
+ lc: int = attr()
39
+ text: float = 0.0
40
+
41
+ class Y(BaseXmlModel, tag="vy", validate_assignment=True):
42
+ lc: int = attr()
43
+ text: float = 0.0
44
+
45
+ class Z(BaseXmlModel, tag="vz", validate_assignment=True):
46
+ lc: int = attr()
47
+ text: float = 0.0
48
+
49
+ type: Literal["rigid_rotation_vector"] = attr(default="rigid_rotation_vector", frozen=True)
50
+ rb: str = element()
51
+ vx: X = element()
52
+ vy: Y = element()
53
+ vz: Z = element()
54
+
55
+
56
+ class RigidBodyEulerAngle(BaseXmlModel, tag="rigid_bc", validate_assignment=True):
57
+ class X(BaseXmlModel, tag="Ex", validate_assignment=True):
58
+ lc: int = attr()
59
+ text: float = 0.0
60
+
61
+ class Y(BaseXmlModel, tag="Ey", validate_assignment=True):
62
+ lc: int = attr()
63
+ text: float = 0.0
64
+
65
+ class Z(BaseXmlModel, tag="Ez", validate_assignment=True):
66
+ lc: int = attr()
67
+ text: float = 0.0
68
+
69
+ type: Literal["rigid_euler_vector"] = attr(default="rigid_euler_vector", frozen=True)
70
+ rb: str = element()
71
+ Ex: X = element()
72
+ Ey: Y = element()
73
+ Ez: Z = element()
74
+
75
+
76
+ class RigidForceLoad(BaseXmlModel, tag="rigid_load", validate_assignment=True):
77
+ type: Literal["rigid_force"] = attr(default="rigid_force", frozen=True)
78
+ rb: str = element()
79
+ dof: Literal["Rx", "Ry", "Rz"] = element()
80
+ relative: Literal[0, 1] = element(default=0)
81
+ load_type: Literal[0, 1, 2] = element(default=1)
82
+ value: Value = element()
83
+
84
+
85
+ class RigidFollowerForceLoad(BaseXmlModel, tag="rigid_load", validate_assignment=True):
86
+ type: Literal["rigid_follower_force"] = attr(default="rigid_follower_force", frozen=True)
87
+ rb: str = element()
88
+ insertion: StringFloatVec3 = element()
89
+ relative: Literal[0, 1] = element(default=0)
90
+ force: StringFloatVec3 = element()
91
+
92
+
93
+ class RigidMomentLoad(BaseXmlModel, tag="rigid_load", validate_assignment=True):
94
+ type: Literal["rigid_moment"] = attr(default="rigid_moment", frozen=True)
95
+ rb: str = element()
96
+ dof: Literal["Ru", "Rv", "Rw"] = element()
97
+ relative: Literal[0, 1] = element(default=0)
98
+ value: Value = element()
99
+
100
+
101
+ class RigidFollowerMomentLoad(BaseXmlModel, tag="rigid_load", validate_assignment=True):
102
+ type: Literal["rigid_follower_moment"] = attr(default="rigid_follower_moment", frozen=True)
103
+ rb: str = element()
104
+ relative: Literal[0, 1] = element(default=0)
105
+ moment: StringFloatVec3 = element()
106
+
107
+
108
+ class RigidCableLoad(BaseXmlModel, tag="rigid_load", validate_assignment=True):
109
+ class CablePoint(BaseXmlModel, tag="rigid_cable_point", validate_assignment=True):
110
+ rigid_body_id: str = element()
111
+ position: StringFloatVec3 = element()
112
+
113
+ type: Literal["rigid_cable"] = attr(default="rigid_cable", frozen=True)
114
+ force_direction: StringFloatVec3 = element()
115
+ relative: Literal[0, 1] = element(default=1)
116
+ force: Value = element()
117
+ rigid_cable_point: list[CablePoint] = element(default=[])
118
+
119
+
120
+ class RigidConnector(
121
+ BaseXmlModel,
122
+ tag="rigid_connector",
123
+ validate_assignment=True,
124
+ ):
125
+ """ """
126
+
127
+ name: str = attr()
128
+ body_a: str = element()
129
+ body_b: str = element()
130
+ tolerance: float = element(default=0.1)
131
+ minaug: int = element(default=0)
132
+ maxaug: int = element(default=10)
133
+ gaptol: Literal[0] | float = element(default=0)
134
+ angtol: Literal[0] | float = element(default=0)
135
+ force_penalty: float = element(default=1)
136
+ moment_penalty: float = element(default=1)
137
+ auto_penalty: Literal[0, 1] = element(default=1)
138
+
139
+
140
+ class Free(BaseXmlModel, validate_assignment=True):
141
+ text: Literal[0] = 0
142
+
143
+
144
+ class RigidSphericalJoint(RigidConnector):
145
+ type: Literal["rigid spherical joint"] = attr(default="rigid spherical joint", frozen=True)
146
+ joint_origin: StringFloatVec3 = element(default="0.0,0.0,0.0")
147
+ prescribed_rotation: Literal[0, 1] = element(default=0)
148
+ rotation_x: Value | Free = element(default=Free())
149
+ rotation_y: Value | Free = element(default=Free())
150
+ rotation_z: Value | Free = element(default=Free())
151
+ moment_x: Value | Free = element(default=Free())
152
+ moment_y: Value | Free = element(default=Free())
153
+ moment_z: Value | Free = element(default=Free())
154
+
155
+
156
+ class RigidRevoluteJoint(RigidConnector):
157
+ class Free(BaseXmlModel):
158
+ text: Literal[0] = 0
159
+
160
+ type: Literal["rigid revolute joint"] = attr(default="rigid revolute joint", frozen=True)
161
+ laugon: Literal[0, 1] = element(default=0)
162
+ joint_origin: StringFloatVec3 = element(default="0.0,0.0,0.0")
163
+ prescribed_rotation: Literal[0, 1] = element(default=0)
164
+ rotation_axis: StringFloatVec3 = element(default="0.0,0.0,1.0")
165
+ moment: Value | Free = element(default=Free())
166
+ rotation: Value | Free = element(default=Free())
167
+
168
+
169
+ class RigidPrismaticJoint(RigidConnector):
170
+ type: Literal["rigid prismatic joint"] = attr(default="rigid prismatic joint", frozen=True)
171
+ joint_origin: StringFloatVec3 = element(default="0.0,0.0,0.0")
172
+ prescribed_translation: Literal[0, 1] = element(default=0)
173
+ translation: Value | Free = element(default=Free())
174
+ force: Value | Free = element(default=Free())
175
+
176
+
177
+ class RigidCylindricalJoint(RigidConnector):
178
+ type: Literal["rigid cylindrical joint"] = attr(default="rigid cylindrical joint", frozen=True)
179
+ laugon: Literal["PENALTY", "AUGLAG", "LAGMULT"] = element(default="PENALTY")
180
+ joint_origin: StringFloatVec3 = element(default="0.0,0.0,0.0")
181
+ joint_axis: StringFloatVec3 = element(default="0.0,0.0,0.0")
182
+ transverse_axis: StringFloatVec3 = element(default="0.0,0.0,0.0")
183
+ prescribed_rotation: Literal[0, 1] = element(default=0)
184
+ prescribed_translation: Literal[0, 1] = element(default=0)
185
+ translation: Value | Free = element(default=Free())
186
+ force: Value | Free = element(default=Free())
187
+ rotation: Value | Free = element(default=Free())
188
+ moment: Value | Free = element(default=Free())
189
+
190
+
191
+ class RigidPlanarJoint(RigidConnector):
192
+ type: Literal["rigid planar joint"] = attr(default="rigid planar joint", frozen=True)
193
+ joint_origin: StringFloatVec3 = element(default="0.0,0.0,0.0")
194
+ rotation_axis: StringFloatVec3 = element(default="0.0,0.0,0.0")
195
+ translation_axis_1: StringFloatVec3 = element(default="0.0,0.0,0.0")
196
+ translation_axis_2: StringFloatVec3 = element(default="0.0,0.0,0.0")
197
+ prescribed_rotation: Literal[0, 1] = element(default=0)
198
+ prescribed_translation_1: Literal[0, 1] = element(default=0)
199
+ prescribed_translation_2: Literal[0, 1] = element(default=0)
200
+ rotation: Value | Free = element(default=Free())
201
+ translation_1: Value | Free = element(default=Free())
202
+ translation_2: Value | Free = element(default=Free())
203
+
204
+
205
+ class RigidLock(RigidConnector):
206
+ type: Literal["rigid lock"] = attr(default="rigid lock", frozen=True)
207
+ joint_origin: StringFloatVec3 = element(default="0.0,0.0,0.0")
208
+ first_axis: StringFloatVec3 = element(default="1.0,0.0,0.0")
209
+ second_axis: StringFloatVec3 = element(default="0.0,1.0,0.0")
210
+
211
+
212
+ class RigidSpring(RigidConnector):
213
+ type: Literal["rigid spring"] = attr(default="rigid spring", frozen=True)
214
+ k: float = element(default=1)
215
+ insertion_a: StringFloatVec3 = element(default="0.0,0.0,0.0")
216
+ insertion_b: StringFloatVec3 = element(default="1.0,0.0,0.0")
217
+ free_length: Literal[0] | float = element(default=0)
218
+
219
+
220
+ class RigidDamper(RigidConnector):
221
+ type: Literal["rigid damper"] = attr(default="rigid damper", frozen=True)
222
+ c: float = element(default=1e-7)
223
+ insertion_a: StringFloatVec3 = element(default="0.0,0.0,0.0")
224
+ insertion_b: StringFloatVec3 = element(default="1.0,0.0,0.0")
225
+
226
+
227
+ class RigidAngularDamper(RigidConnector):
228
+ type: Literal["rigid angular damper"] = attr(default="rigid angular damper", frozen=True)
229
+ c: float = element(default=1e-7)
230
+
231
+
232
+ class RigidContractileForce(RigidConnector):
233
+ type: Literal["rigid damper"] = attr(default="rigid damper", frozen=True)
234
+ insertion_a: StringFloatVec3 = element(default="0.0,0.0,0.0")
235
+ insertion_b: StringFloatVec3 = element(default="1.0,0.0,0.0")
236
+ f0: Value = element()
237
+
238
+
239
+ RigidBCType = RigidFixed | RigidPrescribed | RigidBodyRotationVector | RigidBodyEulerAngle
240
+
241
+ RigidLoadType = RigidForceLoad | RigidFollowerForceLoad | RigidMomentLoad | RigidFollowerMomentLoad
242
+
243
+ RigidConnectorType = (
244
+ RigidSphericalJoint
245
+ | RigidRevoluteJoint
246
+ | RigidCylindricalJoint
247
+ | RigidPrismaticJoint
248
+ | RigidPlanarJoint
249
+ | RigidLock
250
+ | RigidSpring
251
+ | RigidDamper
252
+ | RigidAngularDamper
253
+ | RigidContractileForce
254
+ )
255
+
256
+
257
+ class Rigid(BaseXmlModel, tag="Rigid", validate_assignment=True):
258
+ all_rigid_bcs: list[RigidBCType] = element(default=[], tag="rigid_bc")
259
+ all_rigid_loads: list[RigidLoadType] = element(default=[], tag="rigid_load")
260
+ all_rigid_connectors: list[RigidConnectorType] = element(default=[], tag="rigid_connector")
261
+
262
+ def add_rigid_bc(
263
+ self,
264
+ new_rigid_bc: RigidBCType,
265
+ ):
266
+ self.all_rigid_bcs.append(new_rigid_bc)
267
+
268
+ def add_rigid_load(
269
+ self,
270
+ new_rigid_load: RigidLoadType,
271
+ ):
272
+ self.all_rigid_loads.append(new_rigid_load)
273
+
274
+ def add_rigid_connector(self, new_rigid_connector: RigidConnectorType):
275
+ self.all_rigid_connectors.append(new_rigid_connector)
pyfebio/step.py ADDED
@@ -0,0 +1,28 @@
1
+ from pydantic_xml import BaseXmlModel, attr, element
2
+
3
+ from .boundary import Boundary
4
+ from .constraints import Constraints
5
+ from .contact import Contact
6
+ from .control import Control
7
+ from .initial import Initial
8
+ from .loads import Loads
9
+ from .rigid import Rigid
10
+
11
+
12
+ class StepEntry(BaseXmlModel, validate_assignment=True):
13
+ id: int = attr()
14
+ name: str = attr(default="Step")
15
+ control: Control | None = element(default=None, tag="Control")
16
+ initial: Initial | None = element(default=None, tag="Initial")
17
+ boundary: Boundary | None = element(default=None, tag="Boundary")
18
+ loads: Loads | None = element(default=None, tag="Loads")
19
+ constraints: Constraints | None = element(default=None, tag="Constraints")
20
+ contact: Contact | None = element(default=None, tag="Contact")
21
+ rigid: Rigid | None = element(default=None, tag="Rigid")
22
+
23
+
24
+ class Step(BaseXmlModel, validate_assignment=True):
25
+ all_steps: list[StepEntry] = element(default=[], tag="step")
26
+
27
+ def add_step(self, new_step: StepEntry):
28
+ self.all_steps.append(new_step)
@@ -0,0 +1,336 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyfebio
3
+ Version: 0.1.0
4
+ Summary: A Python API for the FEBio finite element solver.
5
+ Author: Scott Sibole
6
+ Author-email: Scott Sibole <scott.sibole@gmail.com>
7
+ License-Expression: MIT
8
+ Requires-Dist: lxml>=6.0.1
9
+ Requires-Dist: meshio[all]>=5.3.5
10
+ Requires-Dist: pydantic-xml>=2.17.3
11
+ Requires-Python: >=3.13
12
+ Description-Content-Type: text/markdown
13
+
14
+ ## Overview
15
+
16
+ This is a Python package for generating FEBio input files. We rely heavily on pydantic and pydantic-xml
17
+ for type validation and XML serialization. Many of FEBio's features are covered, but not all.
18
+
19
+ ## Getting Started
20
+
21
+ - [Installation](#installation)
22
+ - [Testing](#testing)
23
+ - [Example](#example)
24
+ - [Documentation](https://comporthobiomech.github.io/pyfebio/index.html)
25
+ - [Features](#features)
26
+
27
+ ## Installation
28
+
29
+ We will build PyPi packages later. For now, you can install from source:
30
+
31
+ Clone with https:
32
+
33
+ ```bash
34
+ git clone https://github.com/CompOrthoBiomech/pyfebio.git
35
+ ```
36
+
37
+ Or,
38
+
39
+ Clone with ssh:
40
+
41
+ ```bash
42
+ git clone git@github.com:CompOrthoBiomech/pyfebio.git
43
+ ```
44
+
45
+ **Using uv:**
46
+
47
+ Install uv from [here](https://docs.astral.sh/uv/getting-started/installation/)
48
+
49
+ In top-level repository directory:
50
+
51
+ ```bash
52
+ uv sync
53
+ ```
54
+
55
+ This will create a virtual environment and install the package.
56
+
57
+ **Using pip:**
58
+
59
+ In top-level repository directory:
60
+
61
+ Create a virtual environment:
62
+
63
+ ```bash
64
+ python -m venv .venv
65
+ ```
66
+
67
+ Activate the virtual environment:
68
+
69
+ ```bash
70
+ source .venv/bin/activate
71
+ ```
72
+
73
+ Install the package:
74
+
75
+ ```bash
76
+ pip install .
77
+ ```
78
+
79
+ If you want to run the tests, additionally install the dev group dependencies:
80
+
81
+ ```bash
82
+ pip install . --group dev
83
+ ```
84
+
85
+ ## Testing
86
+
87
+ We rely on FEBio to check our generated models are valid. Therefore, you will need to have FEBio installed and available in your PATH.
88
+
89
+ To run all the tests, execute the following command:
90
+
91
+ ```bash
92
+ cd src
93
+ pytest
94
+ ```
95
+
96
+ For tests that depend on running finite element simulations, you can find them in the pytest tmp_path directory, which varies by operating system.
97
+
98
+ For the latest run:
99
+
100
+ on Linux,
101
+
102
+ ```bash
103
+ cd /tmp/pytest-of-[USER]/pytest-current/[TEST_FUNCTION_NAME]current
104
+ ```
105
+
106
+ ## Example
107
+
108
+ ```python
109
+ import pyfebio
110
+
111
+ # Instantiate a model tree with default values
112
+ # This contains empty mesh, material, loads, boundary, etc. sections
113
+ my_model = pyfebio.model.Model()
114
+
115
+ # Let's create a single hex8 element explicitly
116
+ # Normally, you would use the meshio functions to import
117
+ nodes_list = [
118
+ [0.0, 0.0, 0.0],
119
+ [1.0, 0.0, 0.0],
120
+ [1.0, 1.0, 0.0],
121
+ [0.0, 1.0, 0.0],
122
+ [0.0, 0.0, 1.0],
123
+ [1.0, 0.0, 1.0],
124
+ [1.0, 1.0, 1.0],
125
+ [0.0, 1.0, 1.0],
126
+ ]
127
+
128
+ elements_list = [[1, 2, 3, 4, 5, 6, 7, 8]]
129
+
130
+ # Add Nodes to an pyfebio.Nodes object
131
+ nodes = pyfebio.mesh.Nodes(name="nodes")
132
+ for i, node in enumerate(nodes_list):
133
+ nodes.add_node(pyfebio.mesh.Node(id=i + 1, text=",".join(map(str, node))))
134
+
135
+ # Add Elements to an pyfebio.Elements object
136
+ elements = pyfebio.mesh.Elements(name="box", type="hex8")
137
+ for i, element in enumerate(elements_list):
138
+ elements.add_element(pyfebio.mesh.Hex8Element(id=i + 1, text=",".join(map(str, element))))
139
+
140
+ # Append nodes and elements to the model's mesh section
141
+ my_model.mesh.nodes.append(nodes)
142
+ my_model.mesh.elements.append(elements)
143
+
144
+ # Let's make a node set for top and bottom
145
+ bottom_nodes = [1, 2, 3, 4]
146
+ top_nodes = [5, 6, 7, 8]
147
+ top_node_set = pyfebio.mesh.NodeSet(name="top", text=",".join(map(str, top_nodes)))
148
+ bottom_node_set = pyfebio.mesh.NodeSet(name="bottom", text=",".join(map(str, bottom_nodes)))
149
+
150
+ # Append the node sets to the model's mesh section
151
+ my_model.mesh.node_sets.append(top_node_set)
152
+ my_model.mesh.node_sets.append(bottom_node_set)
153
+
154
+ # We need a material
155
+ # the use of pyfebio.material.MaterialParameter is our solution
156
+ # to handle mapped, math, or directly specified values
157
+ my_material = pyfebio.material.MooneyRivlin(
158
+ id=1,
159
+ name="cartilage",
160
+ c1=pyfebio.material.MaterialParameter(text=10.0),
161
+ c2=pyfebio.material.MaterialParameter(text=1.0),
162
+ k=pyfebio.material.MaterialParameter(text=1000.0),
163
+ )
164
+
165
+ # Define a solid domain for the box to assign the material
166
+ solid_domain = pyfebio.meshdomains.SolidDomain(name="box", mat="cartilage")
167
+
168
+ # add the solid domain
169
+ my_model.mesh_domains.add_solid_domain(solid_domain)
170
+
171
+ # add the material
172
+ my_model.material.add_material(my_material)
173
+
174
+ # Fix the bottom nodes (1 means BC DoF is active)
175
+ fixed_bottom = pyfebio.boundary.BCZeroDisplacement(node_set="bottom",
176
+ x_dof=1,
177
+ y_dof=1,
178
+ z_dof=1)
179
+
180
+ # Displace the top nodes in z
181
+ # We need to create a boundary.Value object that references a load curve
182
+ displacement_value = pyfebio.boundary.Value(lc=1, text=-0.2)
183
+ move_top = pyfebio.boundary.BCPrescribedDisplacement(
184
+ node_set="top", dof="z", value=displacement_value
185
+ )
186
+
187
+ # Add boundary conditions
188
+ my_model.boundary.add_bc(fixed_bottom)
189
+ my_model.boundary.add_bc(move_top)
190
+
191
+ # Now, create the loadcurve 1 we referenced
192
+ curve_points = pyfebio.loaddata.CurvePoints(points=["0.0,0.0", "1.0,1.0"])
193
+ load_curve1 = pyfebio.loaddata.LoadCurve(id=1, points=curve_points)
194
+ # And, add it to model
195
+ my_model.load_data.add_load_curve(load_curve1)
196
+
197
+ # Finally, save the model to disk
198
+ my_model.save("my_model.feb")
199
+ ```
200
+
201
+ Run the model from the CLI (assuming febio4 is on your PATH):
202
+
203
+ ```{bash}
204
+ febio4 -i my_model.feb
205
+ ```
206
+
207
+ ![Short Example Simulation](assets/short_example.gif)
208
+
209
+
210
+ ## Features
211
+
212
+ Brief overview, see module documentation for more details. Unchecked are not yet implemented.
213
+
214
+ :white_check_mark: Implemented and tested
215
+
216
+ :ballot_box_with_check: Implemented but untested
217
+
218
+ :x: Not yet implemented
219
+
220
+ - Control
221
+ - :white_check_mark: All control settings
222
+ - Mesh Section
223
+ - :white_check_mark: Nodes
224
+ - :white_check_mark: Solid Elements:
225
+ - tet4, tet10, hex8, hex20, hex27, penta6
226
+ - :ballot_box_with_check: Shell Elements:
227
+ - tri3, tri6, quad4, quad8, quad9, q4ans, q4eas
228
+ - :ballot_box_with_check: Beam Elements:
229
+ - line2, line3
230
+ - :white_check_mark: Node, Element, Surface Sets
231
+ - MeshDomain
232
+ - :white_check_mark: Solid Domain
233
+ - :ballot_box_with_check: Shell Domain
234
+ - :ballot_box_with_check: Beam Domain
235
+ - :ballot_box_with_check: Granular control for integration schemes, etc.
236
+ - MeshData Section
237
+ - :ballot_box_with_check: Node Data
238
+ - :ballot_box_with_check: Scalar
239
+ - :ballot_box_with_check: Vector3
240
+ - :ballot_box_with_check: Element Data
241
+ - :ballot_box_with_check: Scalar
242
+ - :ballot_box_with_check: Vector3
243
+ - :x: Surface Data
244
+ - :x: Scalar
245
+ - :x: Vector3
246
+ - MeshAdaptor
247
+ - :ballot_box_with_check: Erosion
248
+ - :white_check_mark: MMG3d Remeshing
249
+ - :white_check_mark: hex_refine
250
+ - :white_check_mark: hex_refine2d
251
+ - :ballot_box_with_check: Criteria
252
+ - :ballot_box_with_check: element selection
253
+ - :ballot_box_with_check: math
254
+ - :ballot_box_with_check: min-max filter
255
+ - :white_check_mark: relative error
256
+ - :white_check_mark: stress
257
+ - :ballot_box_with_check: contact gap
258
+ - :ballot_box_with_check: damage
259
+ - :ballot_box_with_check: max variable
260
+ - Material
261
+ - :white_check_mark: Most Unconstrained Formulation Materials
262
+ - :white_check_mark: Most Uncoupled Formulation Materials
263
+ - :ballot_box_with_check: Prestrain Material
264
+ - :ballot_box_with_check: Fiber models
265
+ - :white_check_mark: Material Axis
266
+ - :white_check_mark: Vector Definition
267
+ - :white_check_mark: Fiber Vector
268
+ - :ballot_box_with_check: Continuous Fiber Distributions
269
+ - :ballot_box_with_check: Integration Schemes
270
+ - :ballot_box_with_check: Element-wise, mapped, or math parameter defintion
271
+ - :white_check_mark: Biphasic Materials
272
+ - :white_check_mark: Viscoelastic Materials
273
+ - :x: Multiphasic Materials
274
+ - :x: Biphasic-solute Materials
275
+ - :x: Chemical Reactions
276
+ - :x: Active Contraction Materials
277
+ - :x: Damage Materials
278
+ - :x: First-order Homogenization
279
+ - Rigid
280
+ - :ballot_box_with_check: Fixed Displacement and Rotation
281
+ - :ballot_box_with_check: Prescribed Displacement and Rotation
282
+ - :ballot_box_with_check: Precribed Rotation about Vector
283
+ - :ballot_box_with_check: Prescribed Euler Rotation
284
+ - :ballot_box_with_check: All Connectors
285
+ - :ballot_box_with_check: Follower Loads
286
+ - Initial
287
+ - :ballot_box_with_check: Initial Velocity
288
+ - :ballot_box_with_check: Initial Pre-strain
289
+ - Loads
290
+ - :ballot_box_with_check: Nodal Loads
291
+ - :ballot_box_with_check: Traction Loads (surface)
292
+ - :ballot_box_with_check: Pressure Loads (surface)
293
+ - :ballot_box_with_check: Fluid Flux (surface)
294
+ - :ballot_box_with_check: Fluid Pressure (surface)
295
+ - LoadData
296
+ - :white_check_mark: Load Curves
297
+ - :balloit_box_with_check: All Options
298
+ - :ballot_box_with_check: PID Controllers
299
+ - :ballot_box_with_check: Math Controllers
300
+ - Boundary
301
+ - :white_check_mark: Fixed Displacement (solid)
302
+ - :white_check_mark: Prescribed Displacement (solid)
303
+ - :ballot_box_with_check: Fixed Displacement (shell)
304
+ - :ballot_box_with_check: Prescribed Displacement (shell)
305
+ - :ballot_box_with_check: Precribed Deformation Gradient
306
+ - :ballot_box_with_check: Displacement Along Normals
307
+ - :ballot_box_with_check: Fix to Rigid Body
308
+ - :white_check_mark: Rigid Node Set Deformation (rotation about axis)
309
+ - :white_check_mark: Zero Fluid Pressure
310
+ - :ballot_box_with_check: Prescribed Fluid Pressure
311
+ - Constraints
312
+ - :ballot_box_with_check: Symmetry Plane
313
+ - :ballot_box_with_check: Prestrain
314
+ - :ballot_box_with_check: In-Situ Stretch
315
+ - Contact
316
+ - :ballot_box_with_check: Sliding
317
+ - :ballot_box_with_check: Elastic
318
+ - :ballot_box_with_check: Facet-Facet
319
+ - :ballot_box_with_check: Node-Facet
320
+ - :ballot_box_with_check: Biphasic
321
+ - :ballot_box_with_check: Sliding2
322
+ - :ballot_box_with_check: Contact Potential Formulation
323
+ - :ballot_box_with_check: Tie
324
+ - :ballot_box_with_check: Elastic
325
+ - :ballot_box_with_check: Facet-Facet
326
+ - :ballot_box_with_check: Node-Facet
327
+ - :ballot_box_with_check: Biphasic
328
+ - Step
329
+ - :ballot_box_with_check: Multistep Analysis
330
+ - Output
331
+ - :ballot_box_with_check: Log File Configuration
332
+ - :ballot_box_with_check: Plot File Configuration
333
+ - :ballot_box_with_check: Node Variables
334
+ - :ballot_box_with_check: Element Variables
335
+ - :ballot_box_with_check: Rigid Body Variables
336
+ - :ballot_box_with_check: Rigid Connector Variables
@@ -0,0 +1,26 @@
1
+ pyfebio/__init__.py,sha256=t_4CsqooLVNUaCqvcb_joXCfRjvnMfrhDoo7wrVn6JQ,599
2
+ pyfebio/_types.py,sha256=dNn1A1IR8rVnbAVBE0rfP9jgT6ky0S8NA81ApNApPlY,2326
3
+ pyfebio/boundary.py,sha256=A266CEJrLnF-4UNZZMOlUhwGVdsNKrkjh2rxPmQARAg,3891
4
+ pyfebio/constraints.py,sha256=QHs76vSyOKtZhWy2GoZ8aW9b8VhQwZ1o85TT_dXbPWU,1626
5
+ pyfebio/contact.py,sha256=0FL_TcebZJu7J0GiDeStUcNPGoGZ3WeeUMOrg0HW8UY,6469
6
+ pyfebio/control.py,sha256=uf8sY2771qwEeMRYH_AZa99oh0IPpKtTYiKwaYsgUo8,3255
7
+ pyfebio/discrete.py,sha256=KXac8tldGSBw3bh9Amn80vP8Bb2s36W5uv52vpQnvbY,1404
8
+ pyfebio/globals.py,sha256=33L0YV9pE6huMixHHDYID6N9MrKNYZuoeL3588ZXYc0,389
9
+ pyfebio/include.py,sha256=kyXcwq3h7pJ842GF9KvCXTqHzQmG8aTxAhN-RgzSJBs,124
10
+ pyfebio/initial.py,sha256=krXfiaENs9-b9RhuMHdhqrU-23fbVK_rv9ivgo1zv3w,939
11
+ pyfebio/loaddata.py,sha256=V9M6nMjDnz5c2xPDldg5-k73JHVjNV8ntgcS4EihD4k,1735
12
+ pyfebio/loads.py,sha256=xZdYB9Xg_q56QR1-BBbK6UvnnJIvWEAT_OWuHhv3FTw,1929
13
+ pyfebio/material.py,sha256=nU9gMQCs7ueq1EfyMlXypPCqMAkeEKpwrrGydduGJlU,61139
14
+ pyfebio/mesh.py,sha256=PwSGz7EqJFBkZlhf8_o0MqmsBStXznOeQcVJAFlX43U,12220
15
+ pyfebio/meshadaptor.py,sha256=ok06o6DqngJUJz7OOqC4paPu0y1SAlPkWaSbnLMl6e4,6299
16
+ pyfebio/meshdata.py,sha256=6w0lV98fHt3-HNmcnma0v6ngrGr9Z8JTBaGk-Kvw-hU,1549
17
+ pyfebio/meshdomains.py,sha256=dZjOaiP5kfXy3Ym9AgSetZIKgFSf35GikmGvWOnrsIU,2125
18
+ pyfebio/model.py,sha256=iFPvKvb1f_OzEGUCP0c3OJp4SehenuAJAiLtvCQnjQI,5320
19
+ pyfebio/module.py,sha256=JIJkuou0fHqyBYq_x2UfsW7g0hhZeimZCqdR31z0nP8,374
20
+ pyfebio/output.py,sha256=C-veR4HnVDscdmw4dQH51a0q933w_uawh5hXIe8LAWo,7996
21
+ pyfebio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ pyfebio/rigid.py,sha256=fQSzyX5RdEiRDK0lOFr19ybnjWVkJ8UZkUXiHybR8f0,10359
23
+ pyfebio/step.py,sha256=NGGzajCfO3ZOCJ22y1z3sIrJHyjpMcJ-uSgIKMFxZKU,1053
24
+ pyfebio-0.1.0.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
25
+ pyfebio-0.1.0.dist-info/METADATA,sha256=ndWZwRs1fo3vCLJFyYisGSIMWVdtdWpn-aI7P_jysXg,10275
26
+ pyfebio-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.8.24
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any