### Install PyFebio from Source with uv
Source: https://github.com/febiosoftware/pyfebio/blob/main/README.md
Guide to installing pyfebio directly from its source repository using the 'uv' package manager. This method requires cloning the repository and then using 'uv sync' to set up the environment and install dependencies.
```bash
git clone https://github.com/CompOrthoBiomech/pyfebio.git
cd pyfebio
# Install uv from https://docs.astral.sh/uv/getting-started/installation/
uv sync
```
--------------------------------
### Install pyfebio with pip (Bash)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/introduction.rst
Installs pyfebio using pip. It includes steps for creating and activating a virtual environment, installing the package in editable mode, and installing development dependencies for testing.
```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
pip install . --group dev
```
--------------------------------
### Install PyFebio from PyPI
Source: https://github.com/febiosoftware/pyfebio/blob/main/README.md
Instructions for installing the pyfebio package using pip. This involves creating and activating a Python virtual environment before running the pip install command. Ensure you have a compatible Python version.
```bash
/path/to/compatible-python -m venv .venv
source .venv/bin/activate
pip install pyfebio
```
--------------------------------
### Install pyfebio with uv (Bash)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/introduction.rst
Installs pyfebio and its dependencies using the 'uv' package manager. This command should be run from the top-level repository directory.
```bash
uv sync
```
--------------------------------
### Biphasic Analysis with pyfebio (Python)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/examples.rst
Demonstrates setting up a biphasic analysis in pyfebio. It involves creating a BiphasicModel, assigning a BiphasicMaterial with NeoHookean solid phase and ConstantIsoPerm permeability, and applying boundary conditions for fluid pressure and displacement.
```python
import pyfebio as pf
import meshio
import numpy as np
# Convert gmsh to meshio object
mesh = meshio.read("mesh.gmsh")
# Translate meshio object to pyfebio mesh
elem_list, surf_list, node_set_list = pf.meshio_to_pyfebio(mesh)
# Instantiate BiphasicModel
model = pf.BiphasicModel(mesh=pf.Mesh(elements=elem_list, surfaces=surf_list), analysis="TRANSIENT", solver_type="biphasic")
# Assign biphasic material
model.set_material(pf.BiphasicMaterial(solid=pf.NeoHookean(), permeability=pf.ConstantIsoPerm()))
# Assign boundary conditions
model.add_boundary_condition(pf.BCZeroDisplacement(node_sets=node_set_list["bottom"], dof=None))
model.add_boundary_condition(pf.BCZeroFluidPressure(surfaces=surf_list["top"]))
model.add_boundary_condition(pf.BCPrescribedDisplacement(surfaces=surf_list["top"], magnitude=0.5, direction=np.array([0.0, 0.0, 1.0]), time=np.array([0.0, 0.1, 10.0])))
```
--------------------------------
### Verify pyfebio Installation (Python)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/introduction.rst
A simple Python command to verify that pyfebio has been installed correctly by attempting to import it.
```python
python -c "import pyfebio"
```
--------------------------------
### FEBio Input File Structure (XML)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/introduction.rst
An example of the basic structure of an FEBio input file, showing the top-level XML elements like Module, Globals, Control, Material, Mesh, and Step.
```xml
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
```
--------------------------------
### Sliding Contact Simulation with pyfebio (Python)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/examples.rst
This example sets up a sliding contact simulation in pyfebio. It defines a SurfacePair and a SlidingElastic contact, enforcing the contact constraint using the augmented Lagrange multiplier method and enabling two-pass for reduced penetration.
```python
import pyfebio as pf
import meshio
import numpy as np
# Convert gmsh to meshio object
mesh = meshio.read("mesh.gmsh")
# Translate meshio object to pyfebio mesh
elem_list, surf_list, node_set_list = pf.meshio_to_pyfebio(mesh)
# Instantiate pyfebio Model
model = pf.Model(mesh=pf.Mesh(elements=elem_list, surfaces=surf_list), defaults=True)
# Define surface pair for contact
surface_pair = pf.SurfacePair(surf1=surf_list["contact_surface_1"], surf2=surf_list["contact_surface_2"])
# Add sliding contact definition
model.add_contact(pf.SlidingElastic(surface_pair=surface_pair, laugon="AUGLAG", two_pass=1))
```
--------------------------------
### Three Cylinder Joint Simulation with Rigid Connectors (Python)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/examples.rst
This example showcases the use of rigid connectors in pyfebio to model a three-cylinder linkage, a common approach for simulating joint dynamics. It allows for the enforcement of specific rotations and translations.
```python
import pyfebio as pf
import meshio
import numpy as np
# Convert gmsh to meshio object
mesh = meshio.read("mesh.gmsh")
# Translate meshio object to pyfebio mesh
elem_list, surf_list, node_set_list = pf.meshio_to_pyfebio(mesh)
# Instantiate pyfebio Model
model = pf.Model(mesh=pf.Mesh(elements=elem_list, surfaces=surf_list), defaults=True)
# Define rigid bodies (assuming they are part of the mesh or defined separately)
# rigid_body_A = ...
# rigid_body_B = ...
# Add rigid connectors for joint dynamics
# Example: Flexion-extension joint
model.add_rigid_connector(pf.RigidConnector(rigid_bodies=[rigid_body_A, rigid_body_B], type="hinge", axis=np.array([1.0, 0.0, 0.0])))
# Example: Inferior-superior translation joint
model.add_rigid_connector(pf.RigidConnector(rigid_bodies=[rigid_body_A, rigid_body_B], type="slider", axis=np.array([0.0, 0.0, 1.0])))
# Apply boundary conditions to control the joints
# model.add_boundary_condition(pf.BCRigidMotion(rigid_bodies=[rigid_body_A], rotation=np.array([0.0, np.pi/2.0, 0.0])))
# model.add_boundary_condition(pf.BCRigidMotion(rigid_bodies=[rigid_body_B], translation=np.array([0.0, 0.0, 1.0])))
```
--------------------------------
### Convert GMSH to pyfebio Mesh and Apply Material/Boundary Conditions (Python)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/examples.rst
Demonstrates converting a GMSH mesh to a pyfebio mesh, creating Elements and Surfaces from sets, instantiating a pyfebio Model, assigning NeoHookean material and SolidDomain to parts, and applying BCZeroDisplacement and BCRigidDeformation boundary conditions.
```python
import pyfebio as pf
import meshio
import numpy as np
# Convert gmsh to meshio object
mesh = meshio.read("mesh.gmsh")
# Translate meshio object to pyfebio mesh
# Element and surface sets are translated to lists of pyfebio Elements and Surfaces.
# Node sets are created from the surfaces.
elem_list, surf_list, node_set_list = pf.meshio_to_pyfebio(mesh)
# Instantiate pyfebio Model
model = pf.Model(mesh=pf.Mesh(elements=elem_list, surfaces=surf_list), defaults=True)
# Assign material and domain to each part
for part in model.parts:
part.set_material(pf.NeoHookean())
part.set_domain(pf.SolidDomain())
# Assign boundary condition to bottom node sets
model.add_boundary_condition(pf.BCZeroDisplacement(node_sets=node_set_list["bottom"], dof=None))
# Twist the top face
model.add_boundary_condition(pf.BCRigidDeformation(surfaces=surf_list["top"], pos=np.array([0.0, 0.0, 0.0]), rot=np.array([0.0, 0.0, np.pi])))
```
--------------------------------
### Run PyFebio Tests
Source: https://github.com/febiosoftware/pyfebio/blob/main/README.md
Command to execute the test suite for the pyfebio package. The tests depend on having FEBio installed and accessible in your system's PATH. Tests requiring FEBio simulations are run in a temporary directory.
```bash
cd src
pytest
```
--------------------------------
### Create a Basic FEBio Model with PyFebio
Source: https://github.com/febiosoftware/pyfebio/blob/main/README.md
Example demonstrating how to construct a simple FEBio model using the pyfebio library. This involves defining nodes, elements (hex8), node sets, a material (CoupledMooneyRivlin), a solid domain, boundary conditions (fixed bottom, prescribed displacement on top), and a load curve. The model is then saved to a .feb file.
```python
import 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")
```
--------------------------------
### Example XML Output for LoadCurve
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/introduction.rst
This XML snippet represents the structure of a LoadCurve object after instantiation and adding a new point. It shows how the 'id' attribute and nested 'points' elements with 'pt' tags are rendered.
```xml
0.0,0.0
0.1,1.0
1.0,1.0
2.0,2.0
```
--------------------------------
### Adaptive Remeshing for Stress Error Reduction (Python)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/examples.rst
Demonstrates adaptive remeshing in pyfebio, specifically an adaptor designed to refine a hex8 mesh to minimize stress error in the bottom layer. This helps improve simulation accuracy in critical areas.
```python
import pyfebio as pf
import meshio
# Convert gmsh to meshio object
mesh = meshio.read("mesh.gmsh")
# Translate meshio object to pyfebio mesh
elem_list, surf_list, node_set_list = pf.meshio_to_pyfebio(mesh)
# Instantiate pyfebio Model
model = pf.Model(mesh=pf.Mesh(elements=elem_list, surfaces=surf_list), defaults=True)
# Add adaptive remeshing adaptor
model.add_adaptor(pf.MeshAdaptor(target_error="stress", refine_layer="bottom"))
```
--------------------------------
### Create Fiber Materials and Solid Mixtures
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
Demonstrates the creation of anisotropic materials with fiber reinforcement and solid mixtures. Includes examples for Transversely isotropic material with fiber direction, a solid mixture of NeoHookean and FiberExponentialPower, and Continuous Fiber Distribution.
```python
import pyfebio
model = pyfebio.model.Model()
# Transversely isotropic material with fiber direction
trans_iso = pyfebio.material.TransIsoMooneyRivlinUC(
id=1,
name="ligament",
c1=pyfebio.material.MaterialParameter(text=13.85),
c2=pyfebio.material.MaterialParameter(text=0.0),
c3=pyfebio.material.MaterialParameter(text=2.07),
c4=pyfebio.material.MaterialParameter(text=61.44),
c5=pyfebio.material.MaterialParameter(text=640.7),
lam_max=pyfebio.material.MaterialParameter(text=1.03),
k=pyfebio.material.MaterialParameter(text=100.0),
fiber=pyfebio.material.FiberVector(text="1.0,0.0,0.0")
)
model.material_.add_material(trans_iso)
# Solid mixture with multiple components
mixture = pyfebio.material.SolidMixture(id=2, name="composite")
mixture.add_solid(pyfebio.material.NeoHookean(
E=pyfebio.material.MaterialParameter(text=1.0),
v=pyfebio.material.MaterialParameter(text=0.3)
))
mixture.add_solid(pyfebio.material.FiberExponentialPower(
ksi=pyfebio.material.MaterialParameter(text=5.0),
alpha=pyfebio.material.MaterialParameter(text=20.0),
beta=pyfebio.material.MaterialParameter(text=2.0),
lam0=pyfebio.material.MaterialParameter(text=1.0),
fiber=pyfebio.material.FiberVector(text="1.0,0.0,0.0")
))
model.material_.add_material(mixture)
# Continuous fiber distribution
cfd = pyfebio.material.ContinuousFiberDistribution(
fibers=pyfebio.material.FiberNaturalNeoHookean(
ksi=pyfebio.material.MaterialParameter(text=1.0),
lam0=pyfebio.material.MaterialParameter(text=1.0)
),
distribution=pyfebio.material.CFDSpherical(),
scheme=pyfebio.material.GaussKronrodTrapezoidalIntegration(nph=15, nth=31)
)
```
--------------------------------
### Run FEBio Model Simulation in Python
Source: https://github.com/febiosoftware/pyfebio/blob/main/README.md
This Python code snippet demonstrates how to execute an FEBio model simulation using the pyfebio library. It requires the pyfebio library to be installed and a valid .feb file as input. The function returns the result of the simulation, typically a status code or output object.
```python
import pyfebio
pyfebio.model.run_model("my_model.feb")
```
--------------------------------
### Define XML Element with pydantic-xml (Python)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/introduction.rst
Example of a Python class using pydantic-xml to define an XML element, specifically 'BCZeroDisplacement'. It demonstrates the use of 'attr' for attributes and 'element' for sub-elements, along with type validation.
```python
from typing import Literal
from pydantic_xml import BaseXmlModel, attr, element
class BCZeroDisplacement(BaseXmlModel, validate_assignment=True):
type: Literal["zero displacement"] = attr(default="zero displacement", frozen=True)
node_set: str = attr()
x_dof: Literal[0, 1] = element(default=0)
y_dof: Literal[0, 1] = element(default=0)
z_dof: Literal[0, 1] = element(default=0)
```
--------------------------------
### Define Hyperelastic and Biphasic Materials using PyFEBio
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
This snippet illustrates how to define various material models within an FEBio simulation using PyFEBio. It includes examples for coupled Mooney-Rivlin, Neo-Hookean, and biphasic materials, demonstrating parameter validation and assignment to mesh domains.
```python
import pyfebio
model = pyfebio.model.Model()
# Coupled Mooney-Rivlin material with validation
cartilage = 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),
density=pyfebio.material.MaterialParameter(text=1.0)
)
model.material_.add_material(cartilage)
# Neo-Hookean uncoupled material
tissue = pyfebio.material.NeoHookean(
id=2,
name="tissue",
E=pyfebio.material.MaterialParameter(text=1.0),
v=pyfebio.material.MaterialParameter(text=0.3)
)
model.material_.add_material(tissue)
# Biphasic material for poroelasticity
biphasic_mat = pyfebio.material.BiphasicMaterial(
id=3,
name="cartilage_biphasic",
fluid_density=pyfebio.material.MaterialParameter(text=1.0),
phi0=pyfebio.material.MaterialParameter(text=0.2),
solid=pyfebio.material.NeoHookean(
E=pyfebio.material.MaterialParameter(text=1.0),
v=pyfebio.material.MaterialParameter(text=0.3)
),
permeability=pyfebio.material.ConstantIsoPerm(
perm=pyfebio.material.MaterialParameter(text=1e-3)
)
)
model.material_.add_material(biphasic_mat)
# Assign material to domain
solid_domain = pyfebio.meshdomains.SolidDomain(name="box", mat="cartilage")
model.meshdomains_.add_solid_domain(solid_domain)
```
--------------------------------
### Import External Mesh using PyFEBio and Meshio
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
This example demonstrates how to import external mesh files (e.g., VTK) into PyFEBio using the meshio library. It converts the meshio object into a PyFEBio-compatible mesh structure, allowing for seamless integration with FEBio models. Specific handling for shell elements is supported via the `shell_sets` parameter.
```python
import pyfebio
import meshio
# Read mesh from file (supports many formats via meshio)
mesh_obj = meshio.read("mesh.vtk")
# Convert to FEBio format
# Automatically detects solid vs shell elements based on topology
febio_mesh = pyfebio.mesh.translate_meshio(
mesh_obj,
nodeoffset=0,
elementoffset=0,
surfaceoffset=0,
shell_sets=["shell_part"] # Specify which sets are shells
)
# Add to model
model = pyfebio.model.Model()
model.mesh_ = febio_mesh
```
--------------------------------
### Configure Mesh Adaptation
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
Sets up adaptive remeshing configurations for simulations using pyfebio. Examples include MMG3D remesher with a stress criterion and Hex refinement with a stress criterion. These adaptors are added to the model's mesh adaptor collection.
```python
import pyfebio
model = pyfebio.model.Model()
# MMG3D remesher with stress criterion
remesher = pyfebio.meshadaptor.MMG3DRemesher(
max_iters=5,
max_elem_size=0.5,
min_elem_size=0.1,
mesh_criterion=pyfebio.meshadaptor.RelativeErrorCriterion(
max_error=0.05,
var="stress"
)
)
model.meshadaptor_.add_mesh_adaptor(remesher)
# Hex refinement
hex_refine = pyfebio.meshadaptor.HexRefine(
max_iters=3,
max_level=2,
criterion=pyfebio.meshadaptor.StressCriterion(
max_value=10.0
)
)
model.meshadaptor_.add_mesh_adaptor(hex_refine)
```
--------------------------------
### Define Viscoelastic Materials with Prony Series in pyfebio
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
This snippet shows how to define a viscoelastic material using the Prony series expansion in pyfebio. It includes parameters for relaxation times (`t1`, `t2`, `t3`) and relaxation moduli (`g0`, `g1`, `g2`, `g3`), along with an underlying elastic model (NeoHookean in this example).
```python
import pyfebio
model = pyfebio.model.Model()
# Viscoelastic material with Prony series
viscoelastic = pyfebio.material.ViscoelasticMaterial(
id=1,
name="visco_tissue",
g0=pyfebio.material.MaterialParameter(text=1.0),
g1=pyfebio.material.MaterialParameter(text=0.5),
g2=pyfebio.material.MaterialParameter(text=0.3),
g3=pyfebio.material.MaterialParameter(text=0.0),
t1=pyfebio.material.MaterialParameter(text=1.0),
t2=pyfebio.material.MaterialParameter(text=10.0),
t3=pyfebio.material.MaterialParameter(text=100.0),
elastic=pyfebio.material.NeoHookean(
E=pyfebio.material.MaterialParameter(text=1.0),
v=pyfebio.material.MaterialParameter(text=0.3)
)
)
model.material_.add_material(viscoelastic)
```
--------------------------------
### Clone pyfebio Repository (Bash)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/introduction.rst
Instructions for cloning the pyfebio repository using either HTTPS or SSH protocols. This is the first step to setting up the project locally.
```bash
git clone https://github.com/CompOrthoBiomech/pyfebio.git
```
```bash
git clone git@github.com:CompOrthoBiomech/pyfebio.git
```
--------------------------------
### Create and Run Basic FEBio Model using PyFEBio
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
This snippet demonstrates how to create a basic FEBio model from scratch using PyFEBio. It defines nodes and elements for a hex8 element, saves the model to an XML file, and executes it using the `febio4` solver. Requires `febio4` to be in the system's PATH.
```python
import pyfebio
# Create model with default empty sections
my_model = pyfebio.model.Model()
# Define nodes for a hex8 element
nodes = pyfebio.mesh.Nodes(name="nodes")
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],
]
for i, node in enumerate(nodes_list):
nodes.add_node(pyfebio.mesh.Node(id=i + 1, text=",".join(map(str, node))))
# Define elements
elements = pyfebio.mesh.Elements(name="box", type="hex8")
elements.add_element(pyfebio.mesh.Hex8Element(id=1, text="1,2,3,4,5,6,7,8"))
# Add to model mesh
my_model.mesh_.nodes.append(nodes)
my_model.mesh_.elements.append(elements)
# Save and run
my_model.save("model.feb")
pyfebio.model.run_model("model.feb") # Requires febio4 in PATH
```
--------------------------------
### Apply Displacement and Constraint Boundary Conditions in pyfebio
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
This snippet demonstrates how to apply various boundary conditions, including fixed nodes, prescribed displacements, zero fluid pressure, and rigid body constraints, using the pyfebio library. It initializes a model and adds different BC objects to it.
```python
import pyfebio
model = pyfebio.model.Model()
# Fix nodes (1 = active constraint)
fixed_bc = pyfebio.boundary.BCZeroDisplacement(
node_set="bottom",
x_dof=1,
y_dof=1,
z_dof=1
)
model.boundary_.add_bc(fixed_bc)
# Prescribed displacement with load curve
displacement_value = pyfebio.boundary.Value(lc=1, text=-0.2)
prescribed_bc = pyfebio.boundary.BCPrescribedDisplacement(
node_set="top",
dof="z",
value=displacement_value,
relative=0
)
model.boundary_.add_bc(prescribed_bc)
# Zero fluid pressure for biphasic
pressure_bc = pyfebio.boundary.BCZeroFluidPressure(node_set="surface_nodes")
model.boundary_.add_bc(pressure_bc)
# Rigid body boundary condition
rigid_bc = pyfebio.boundary.BCRigid(node_set="rigid_nodes", rb="rigid_body_1")
model.boundary_.add_bc(rigid_bc)
```
--------------------------------
### Instantiate and Generate XML from pyfebio Class (Python/XML)
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/introduction.rst
Demonstrates how to instantiate a Python class representing an FEBio XML element ('BCZeroDisplacement') and the resulting XML output. It highlights how Python attributes map to XML attributes and elements.
```python
fixed_displacment = BCZeroDisplacement(node_set="my_node_set", x_dof=1)
print(fixed_displacment.to_xml())
```
```xml
1
0
0
```
--------------------------------
### Set Analysis Control Parameters
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
Configures the analysis control parameters for a simulation. This includes setting the analysis type (STATIC, TRANSIENT, STEADY-STATE), time stepping parameters, and solver settings. It also shows a placeholder for a Biphasic model.
```python
import pyfebio
model = pyfebio.model.Model()
# Configure solver control
model.control_ = pyfebio.control.Control(
analysis="STATIC", # or "TRANSIENT", "STEADY-STATE"
time_steps=100,
step_size=0.01,
time_stepper=pyfebio.control.TimeStepper(
dtmin=pyfebio.control.TimeStepValue(text=0.001),
dtmax=pyfebio.control.TimeStepValue(text=0.1),
max_retries=5,
opt_iter=10
),
solver=pyfebio.control.Solver(
type="solid", # or "biphasic", "multiphasic"
symmetric_stiffness=1,
equation_scheme="staggered",
equation_order="default",
optimize_bw=0,
lstol=0.9,
lsmin=0.01,
lsiter=5,
max_refs=15,
check_zero_diagonal=0,
zero_diagonal_tol=0.0,
force_partition=0,
reform_each_time_step=1,
reform_augment=0,
diverge_reform=1,
min_residual=1e-20,
max_residual=1e20,
dtol=0.001,
etol=0.01,
rtol=0.0,
alpha=1.0,
beta=0.25,
gamma=0.5,
logSolve=0,
arc_length=0,
arc_length_scale=0.0
)
)
# Biphasic model with specific settings
biphasic_model = pyfebio.model.BiphasicModel()
# Pre-configured with biphasic module and solver
```
--------------------------------
### Create Meshes and Node Sets using PyFEBio
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
This code snippet shows how to construct mesh components like nodes, elements, node sets, surfaces, and element sets programmatically with PyFEBio. It supports various element types and facilitates the organization of mesh entities for defining boundary conditions and material assignments.
```python
import pyfebio
model = pyfebio.model.Model()
# Create nodes
nodes = pyfebio.mesh.Nodes(name="part1")
for i in range(8):
x, y, z = i % 2, (i // 2) % 2, i // 4
nodes.add_node(pyfebio.mesh.Node(id=i + 1, text=f"{x},{y},{z}"))
model.mesh_.nodes.append(nodes)
# Create elements (supports tet4, tet10, hex8, hex20, hex27, penta6)
elements = pyfebio.mesh.Elements(name="part1", type="hex8")
elements.add_element(pyfebio.mesh.Hex8Element(id=1, text="1,2,3,4,5,6,7,8"))
model.mesh_.elements.append(elements)
# Create node sets for boundary conditions
top_nodes = pyfebio.mesh.NodeSet(name="top", text="5,6,7,8")
bottom_nodes = pyfebio.mesh.NodeSet(name="bottom", text="1,2,3,4")
model.mesh_.node_sets.append(top_nodes)
model.mesh_.node_sets.append(bottom_nodes)
# Create surface from quad4 elements
surface = pyfebio.mesh.Surface(name="top_surface")
surface.add_quad4(pyfebio.mesh.Quad4Element(id=1, text="5,6,7,8"))
model.mesh_.surfaces.append(surface)
# Create element set
elem_set = pyfebio.mesh.ElementSet(name="all_elements", text="1")
model.mesh_.element_sets.append(elem_set)
```
--------------------------------
### Generate Rigid Bodies Programmatically in pyfebio
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
This code demonstrates two methods for creating rigid bodies in pyfebio: `add_simple_rigid_body` for quick creation with a specified origin, and manual creation of a `RigidBody` material object with detailed properties like center of mass, elastic moduli, and density.
```python
import pyfebio
model = pyfebio.model.Model()
# Add simple rigid body (creates tet4 automatically)
model.add_simple_rigid_body(
origin=(0.0, 0.0, 5.0),
name="rigid_body_1"
)
# Manual rigid body material
rigid_mat = pyfebio.material.RigidBody(
id=1,
name="rigid_body_2",
center_of_mass="1.0,2.0,3.0",
E=pyfebio.material.MaterialParameter(text=1.0),
v=pyfebio.material.MaterialParameter(text=0.3),
density=pyfebio.material.MaterialParameter(text=1.0)
)
model.material_.add_material(rigid_mat)
```
--------------------------------
### Create and Manipulate LoadCurve Object in Python
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/introduction.rst
Demonstrates the creation of a LoadCurve object with initial points and how to add a new point using the 'add_point' method. This showcases the dynamic nature of the pyfebio models.
```python
load_curve = LoadCurve(id=1, points=CurvePoints(points=["0.0,0.0", "0.1,1.0", "1.0,1.0"]))
load_curve.points.add_point("2.0,2.0")
```
--------------------------------
### Define Time-Dependent Loading Curves and Controllers in pyfebio
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
This code defines various time-dependent load curves and controllers, including linear and step functions, PID controllers, and math-based controllers, using pyfebio. It shows how to create `LoadCurve` objects with different interpolation and extension types, as well as `PIDController` and `MathController`.
```python
import pyfebio
model = pyfebio.model.Model()
# Linear load curve
curve_points = pyfebio.loaddata.CurvePoints(points=["0.0,0.0", "1.0,1.0"])
load_curve = pyfebio.loaddata.LoadCurve(
id=1,
interpolate="LINEAR", # or "STEP", "SMOOTH"
extend="CONSTANT", # or "EXTRAPOLATE", "REPEAT", "REPEAT OFFSET"
points=curve_points
)
model.loaddata_.add_load_curve(load_curve)
# Step function
step_points = pyfebio.loaddata.CurvePoints(points=["0.0,0.0", "0.5,0.0", "0.5,1.0", "1.0,1.0"])
step_curve = pyfebio.loaddata.LoadCurve(id=2, interpolate="STEP", points=step_points)
model.loaddata_.add_load_curve(step_curve)
# PID controller
pid = pyfebio.loaddata.PIDController(
id=3,
var="fluid_pressure",
target=0.1,
Kp=1.0,
Kd=0.5,
Ki=0.1
)
model.loaddata_.add_pid_controller(pid)
# Math controller
math_ctrl = pyfebio.loaddata.MathController(
id=4,
math="sin(2*pi*t)"
)
model.loaddata_.add_math_controller(math_ctrl)
```
--------------------------------
### Define Surface-to-Surface Contact Mechanics in pyfebio
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
This snippet illustrates how to define contact interactions between surfaces in pyfebio. It includes creating `SurfacePair` objects and adding different types of contact definitions, such as sliding elastic, tied elastic, and sliding biphasic contact, to the model.
```python
import pyfebio
model = pyfebio.model.Model()
# Create surface pair
surface_pair = pyfebio.mesh.SurfacePair(
name="contact_pair",
primary="primary_surface",
secondary="secondary_surface"
)
model.mesh_.surface_pairs.append(surface_pair)
# Sliding elastic contact
sliding_contact = pyfebio.contact.SlidingElastic(
name="contact1",
surface_pair="contact_pair",
laugon="AUGLAG",
penalty=1.0,
auto_penalty=1,
tolerance=0.01,
fric_coeff=0.1,
two_pass=1,
symmetric_stiffness=1
)
model.contact_.add_contact(sliding_contact)
# Tied contact
tied_contact = pyfebio.contact.TiedElastic(
name="tie1",
surface_pair="tie_pair",
penalty=1.0,
tolerance=0.01
)
model.contact_.add_contact(tied_contact)
# Biphasic contact
biphasic_contact = pyfebio.contact.SlidingBiphasic(
name="biphasic_contact",
surface_pair="contact_pair",
penalty=1.0,
pressure_penalty=1.0,
fric_coeff=0.0,
contact_frac=0.0
)
model.contact_.add_contact(biphasic_contact)
```
--------------------------------
### Define Uncoupled Viscoelastic Material
Source: https://context7.com/febiosoftware/pyfebio/llms.txt
Defines an uncoupled viscoelastic material using pyfebio.material.ViscoelasticMaterialUC. It includes parameters for stiffness, relaxation, and a Mooney-Rivlin elastic component. The material is added to the model's material collection.
```python
visco_uncoupled = pyfebio.material.ViscoelasticMaterialUC(
id=2,
name="visco_uncoupled",
k=pyfebio.material.MaterialParameter(text=100.0),
g0=pyfebio.material.MaterialParameter(text=1.0),
g1=pyfebio.material.MaterialParameter(text=0.4),
t1=pyfebio.material.MaterialParameter(text=5.0),
elastic=pyfebio.material.MooneyRivlinUC(
c1=pyfebio.material.MaterialParameter(text=10.0),
c2=pyfebio.material.MaterialParameter(text=1.0),
k=pyfebio.material.MaterialParameter(text=1000.0)
)
)
model.material_.add_material(visco_uncoupled)
```
--------------------------------
### Define CurvePoints XML Model in Python
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/introduction.rst
Defines a CurvePoints class to hold a list of points for a load curve. It inherits from BaseXmlModel and specifies that 'points' is a list of StringFloatVec2, with each item mapped to a 'pt' tag in the XML. An 'add_point' method is included for convenience.
```python
class CurvePoints(BaseXmlModel, tag="points", validate_assignment=True):
points: list[StringFloatVec2] = element(default=[], tag="pt")
def add_point(self, new_point: StringFloatVec2):
self.points.append(new_point)
```
--------------------------------
### Define LoadCurve XML Model in Python
Source: https://github.com/febiosoftware/pyfebio/blob/main/docs/introduction.rst
Defines a LoadCurve class inheriting from BaseXmlModel to represent an XML load controller. It includes attributes like 'id', 'type', and elements for interpolation, extension, and curve points. The 'validate_assignment=True' ensures type checking during assignment.
```python
class LoadCurve(BaseXmlModel, tag="load_controller", validate_assignment=True):
id: int = attr()
type: Literal["loadcurve"] = attr(default="loadcurve", frozen=True)
interpolate: Literal["LINEAR", "STEP", "SMOOTH"] = element(default="LINEAR")
extend: Literal["CONSTANT", "EXTRAPOLATE", "REPEAT", "REPEAT OFFSET"] = element(default="CONSTANT")
points: CurvePoints = element()
```