This is a Python package for generating FEBio input files and converting XPLT files to HDF5. We rely heavily on pydantic and pydantic-xml for type validation and XML serialization. Many of FEBio's features are covered, but not all.
With pip:
Create a virtual environment:
/path/to/compatible-python -m venv .venvwhere /path/to/compatible-python is the path to a compatible python executable.
Activate the virtual environment:
On Linux or macOS:
source .venv/bin/activateOn Windows (cmd):
.\.venv\Scripts\activate.batOn Windows (powershell):
.\.venv\Scripts\Activate.ps1Install the package:
pip install pyfebioClone with https:
git clone https://github.com/CompOrthoBiomech/pyfebio.gitOr,
Clone with ssh:
git clone git@github.com:CompOrthoBiomech/pyfebio.gitInstall uv:
Install uv from here
Sync the uv environment
In top-level repository directory:
uv syncThis will create a virtual environment and install the package.
We rely on FEBio to check our generated models are valid. Therefore, you will need to have FEBio installed and available in your PATH.
To run all the tests, execute the following command:
cd src
pytestFor tests that depend on running finite element simulations, you can find them in the pytest tmp_path directory, which varies by operating system.
For the latest run:
on Linux,
cd /tmp/pytest-of-[USER]/pytest-current/[TEST_FUNCTION_NAME]currentimport pyfebio
# Instantiate a model tree with default values
# This contains empty mesh, material, loads, boundary, etc. sections
my_model = pyfebio.model.Model()
# Let's create a single hex8 element explicitly
# Normally, you would use the meshio functions to import
nodes_list = [
[0.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[1.0, 1.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
[1.0, 0.0, 1.0],
[1.0, 1.0, 1.0],
[0.0, 1.0, 1.0],
]
elements_list = [[1, 2, 3, 4, 5, 6, 7, 8]]
# Add Nodes to an pyfebio.Nodes object
nodes = pyfebio.mesh.Nodes(name="nodes")
for i, node in enumerate(nodes_list):
nodes.add_node(pyfebio.mesh.Node(id=i + 1, text=",".join(map(str, node))))
# Add Elements to an pyfebio.Elements object
elements = pyfebio.mesh.Elements(name="box", type="hex8")
for i, element in enumerate(elements_list):
elements.add_element(pyfebio.mesh.Hex8Element(id=i + 1, text=",".join(map(str, element))))
# Append nodes and elements to the model's mesh section
my_model.mesh_.nodes.append(nodes)
my_model.mesh_.elements.append(elements)
# Let's make a node set for top and bottom
bottom_nodes = [1, 2, 3, 4]
top_nodes = [5, 6, 7, 8]
top_node_set = pyfebio.mesh.NodeSet(name="top", text=",".join(map(str, top_nodes)))
bottom_node_set = pyfebio.mesh.NodeSet(name="bottom", text=",".join(map(str, bottom_nodes)))
# Append the node sets to the model's mesh section
my_model.mesh_.node_sets.append(top_node_set)
my_model.mesh_.node_sets.append(bottom_node_set)
# We need a material
# the use of pyfebio.material.MaterialParameter is our solution
# to handle mapped, math, or directly specified values
my_material = pyfebio.material.CoupledMooneyRivlin(
id=1,
name="cartilage",
c1=pyfebio.material.MaterialParameter(text=10.0),
c2=pyfebio.material.MaterialParameter(text=1.0),
k=pyfebio.material.MaterialParameter(text=1000.0),
)
# Define a solid domain for the box to assign the material
solid_domain = pyfebio.meshdomains.SolidDomain(name="box", mat="cartilage")
# add the solid domain
my_model.meshdomains_.add_solid_domain(solid_domain)
# add the material
my_model.material_.add_material(my_material)
# Fix the bottom nodes (1 means BC DoF is active)
fixed_bottom = pyfebio.boundary.BCZeroDisplacement(node_set="bottom", x_dof=1, y_dof=1, z_dof=1)
# Displace the top nodes in z
# We need to create a boundary.Value object that references a load curve
displacement_value = pyfebio.boundary.Value(lc=1, text=-0.2)
move_top = pyfebio.boundary.BCPrescribedDisplacement(node_set="top", dof="z", value=displacement_value)
# Add boundary conditions
my_model.boundary_.add_bc(fixed_bottom)
my_model.boundary_.add_bc(move_top)
# Now, create the loadcurve 1 we referenced
curve_points = pyfebio.loaddata.CurvePoints(points=["0.0,0.0", "1.0,1.0"])
load_curve1 = pyfebio.loaddata.LoadCurve(id=1, points=curve_points)
# And, add it to model
my_model.loaddata_.add_load_curve(load_curve1)
# Save the model to disk
my_model.save("my_model.feb")
# And run it
pyfebio.model.run_model("my_model.feb")Brief overview, see module documentation for more details. Unchecked are not yet implemented.
β Implemented and tested
βοΈ Implemented but untested
β Not yet implemented
- Control
- β All control settings
- Mesh Section
- β Nodes
- β
Solid Elements:
- tet4, tet10, hex8, hex20, hex27, penta6
- βοΈ Shell Elements:
- tri3, tri6, quad4, quad8, quad9, q4ans, q4eas
- βοΈ Beam Elements:
- line2, line3
- β Node, Element, Surface Sets
- MeshDomain
- β Solid Domain
- βοΈ Shell Domain
- βοΈ Beam Domain
- βοΈ Granular control for integration schemes, etc.
- MeshData Section
- βοΈ Node Data
- βοΈ Scalar
- βοΈ Vector3
- βοΈ Element Data
- βοΈ Scalar
- βοΈ Vector3
- β Surface Data
- β Scalar
- β Vector3
- MeshAdaptor
- βοΈ Erosion
- β MMG3d Remeshing
- β hex_refine
- β hex_refine2d
- βοΈ Criteria
- βοΈ element selection
- βοΈ math
- βοΈ min-max filter
- β relative error
- β stress
- βοΈ contact gap
- βοΈ damage
- βοΈ max variable
- Material
- β Most Unconstrained Formulation Materials
- β Most Uncoupled Formulation Materials
- βοΈ Prestrain Material
- βοΈ Fiber models
- β
Material Axis
- β Vector Definition
- β Fiber Vector
- βοΈ Continuous Fiber Distributions
- βοΈ Integration Schemes
- βοΈ Element-wise, mapped, or math parameter defintion
- β Biphasic Materials
- β Viscoelastic Materials
- β Multiphasic Materials
- β Biphasic-solute Materials
- β Chemical Reactions
- β Active Contraction Materials
- β Damage Materials
- β First-order Homogenization
- Rigid
- βοΈ Fixed Displacement and Rotation
- βοΈ Prescribed Displacement and Rotation
- βοΈ Precribed Rotation about Vector
- βοΈ Prescribed Euler Rotation
- βοΈ All Connectors
- βοΈ Follower Loads
- Initial
- βοΈ Initial Velocity
- βοΈ Initial Pre-strain
- Loads
- βοΈ Nodal Loads
- βοΈ Traction Loads (surface)
- βοΈ Pressure Loads (surface)
- βοΈ Fluid Flux (surface)
- βοΈ Fluid Pressure (surface)
- LoadData
- β
Load Curves
- βοΈ All Options
- βοΈ PID Controllers
- βοΈ Math Controllers
- β
Load Curves
- Boundary
- β Fixed Displacement (solid)
- β Prescribed Displacement (solid)
- βοΈ Fixed Displacement (shell)
- βοΈ Prescribed Displacement (shell)
- βοΈ Precribed Deformation Gradient
- βοΈ Displacement Along Normals
- βοΈ Fix to Rigid Body
- β Rigid Node Set Deformation (rotation about axis)
- β Zero Fluid Pressure
- βοΈ Prescribed Fluid Pressure
- Constraints
- βοΈ Symmetry Plane
- βοΈ Prestrain
- βοΈ In-Situ Stretch
- Contact
- βοΈ Sliding
- βοΈ Elastic
- βοΈ Facet-Facet
- βοΈ Node-Facet
- βοΈ Biphasic
- βοΈ Sliding2
- βοΈ Contact Potential Formulation
- βοΈ Tie
- βοΈ Elastic
- βοΈ Facet-Facet
- βοΈ Node-Facet
- βοΈ Biphasic
- Step
- βοΈ Multistep Analysis
- Output
- βοΈ Log File Configuration
- βοΈ Plot File Configuration
- βοΈ Node Variables
- βοΈ Element Variables
- βοΈ Rigid Body Variables
- βοΈ Rigid Connector Variables
- XPLT
- β Convert XPLT to HDF5
