AfemeCorePython Python API
AirFrame 0.0.20261017 ·
import AfemeCorePythonAFEME finite element solver Python bindings (C++ API + pybind11)
Module functions
getVersion() -> str
Get AFEME version
getSubversion() -> str
Get AFEME subversion
getBuildDate() -> str
Get AFEME build date (YYYYMMDD)
calculateBeamSectionProperties(coords: Annotated[numpy.ArrayLike, numpy.float64]) -> dict
Calculate properties of a beam cross section the same way the solver does.
The polyline is one outer loop followed by any number of holes, each loop closed by repeating
its first point. Section axes: X (side) and Y (vertical), origin at the element node.
Args:
coords (ndarray): Polyline coordinates, shape (N, 2)
Returns:
dict: area, centroid (x, y), inertiaX, inertiaY, inertiaXY (around centroidal axes parallel to
the section axes), principalAngle (radians), principalInertia1, principalInertia2,
torsionConstant, shearCenter (x, y)
Raises:
AfemeError: If the section is not valid
class AFEME
Finite element solver for structural analysis.
Supports context manager protocol for automatic cleanup:
with AFEME() as solver:
solver.addMaterial(...)
Every failing call raises AfemeError (a RuntimeError) with the solver's description of the error.
Nodes and elements are numbered from 0 in the order they are added.
AFEME() -> None
Create a new AFEME solver instance.
setCallback(callback: object, printProgressBar: bool = True) -> None
Receive the solver's messages in Python instead of on the console.
Args:
callback (callable): callback(kind, text, newLine), kind being 'message', 'warning' or 'error';
None to print to the console again
printProgressBar (bool): Pass progress bar messages too (default True)
getErrorDescription(code: int) -> str
Get the description of a solver error code.
addMaterial(youngModulus: float, poissonRatio: float, density: float) -> int
Add material definition.
Args:
youngModulus (float): Young's modulus (Pa)
poissonRatio (float): Poisson's ratio
density (float): Material density (kg/m^3)
updateMaterial(material: int, youngModulus: float, poissonRatio: float, density: float) -> None
Update material values.
Args:
material (int): Material index
youngModulus (float): Young's modulus
poissonRatio (float): Poisson's ratio
density (float): Material density
addBeamProperty(material: int, coords: Annotated[numpy.ArrayLike, numpy.float64]) -> int
Add beam property.
Args:
material (int): Material index
coords (ndarray): Section polyline, shape (N, 2): one outer loop and any holes, each
closed by repeating its first point (see calculateBeamSectionProperties)
addShellProperty(material: int, thickness: float) -> int
Add shell property.
Args:
material (int): Material index
thickness (float): Shell thickness (m)
addSolidProperty(material: int) -> None
Add solid property.
Args:
material (int): Material index
addPointMassProperty(mass: float, Ixx: float = 0.0, Iyy: float = 0.0, Izz: float = 0.0, Ixy: float = 0.0, Ixz: float = 0.0, Iyz: float = 0.0) -> None
Add point mass property.
Args:
mass (float): Mass
Ixx, Iyy, Izz, Ixy, Ixz, Iyz (float): Inertia tensor at the center of gravity, in the local
axes of the property (products default to 0)
updateShellProperty(property: int, material: int, thickness: float) -> int
Update shell property values.
Args:
property (int): Property index
material (int): Material index
thickness (float): Shell thickness (m)
updateSolidProperty(property: int, material: int) -> int
Update solid property material.
Args:
property (int): Property index
material (int): Material index
allocateNodes(numNodes: int) -> None
Reserve memory for nodes added one at a time (speeds up addNode).
addNode(x: float, y: float, z: float) -> None
Add a node (x, y, z)
storeNodes(xyz: Annotated[numpy.ArrayLike, numpy.float64]) -> None
Store all nodes at once (replaces the nodes added before).
Args:
xyz (ndarray): Node coordinates, shape (N, 3)
getNumNodes() -> int
Get number of nodes.
addBeamElement(property: int, nodeIndices: Annotated[numpy.ArrayLike, numpy.int32], upVector: Annotated[numpy.ArrayLike, numpy.float64]) -> None
Add beam element.
Args:
property (int): Property index
nodeIndices (array): Node indices [n0, n1]
upVector (array): Vector of the section's vertical direction [ux, uy, uz]
addTriaElement(property: int, nodeIndices: Annotated[numpy.ArrayLike, numpy.int32]) -> None
Add triangular shell element.
Args:
property (int): Property index
nodeIndices (array): Node indices [n0, n1, n2]
addQuadElement(property: int, nodeIndices: Annotated[numpy.ArrayLike, numpy.int32]) -> None
Add quadrilateral shell element.
Args:
property (int): Property index
nodeIndices (array): Node indices [n0, n1, n2, n3]
addTetraElement(property: int, nodeIndices: Annotated[numpy.ArrayLike, numpy.int32]) -> None
Add tetrahedral solid element.
Args:
property (int): Property index
nodeIndices (array): Node indices [n0, n1, n2, n3]
addHexaElement(property: int, nodeIndices: Annotated[numpy.ArrayLike, numpy.int32]) -> None
Add hexahedral solid element.
Args:
property (int): Property index
nodeIndices (array): Node indices [n0..n7]
addWedgeElement(property: int, nodeIndices: Annotated[numpy.ArrayLike, numpy.int32]) -> None
Add wedge (triangular prism) solid element.
Args:
property (int): Property index
nodeIndices (array): Node indices [n0..n5]: bottom triangle, then top triangle
addPointMassElement(property: int, node: int, rotation: object = None) -> None
Add point mass element.
Args:
property (int): Point mass property index
node (int): Node index
rotation (ndarray, optional): 3x3 rotation from the property's local axes to global axes
getNumElements() -> int
Get number of elements.
addConstraint(node: int, dof: int) -> int
Add constraint to nodal DOF.
Args:
node (int): Node index
dof (int): DOF index (0-5: Tx,Ty,Tz,Rx,Ry,Rz)
addRigidMpc(masterNode: int, slaveNodes: Annotated[numpy.ArrayLike, numpy.int32], tieRotations: bool = True) -> int
Add rigid multi-point constraint (MPC): slave nodes follow master node as one rigid body.
Args:
masterNode (int): Master node index
slaveNodes (array): Slave node indices (1D array)
tieRotations (bool): Rotations of slave nodes follow master node too (default True)
addAverageMpc(masterNode: int, slaveNodes: Annotated[numpy.ArrayLike, numpy.int32], weights: object = None) -> int
Add average multi-point constraint (MPC): master node follows weighted average motion of slave nodes.
Args:
masterNode (int): Master node index
slaveNodes (array): Slave node indices (1D array)
weights (array): Optional weight of each slave node (1D array, equal weights if not given)
addForce(nodeIndex: int, nodalDofIndex: int, value: float, loadCaseIndex: int = 0) -> int
Apply force to node DOF. In a transient response it stays applied in every following step
(clearLoad() first to change it).
Args:
nodeIndex (int): Node index
nodalDofIndex (int): DOF index (0-5)
value (float): Force value (N)
loadCaseIndex (int): Load case index, linear static only (default: 0)
addPressure(elemIndex: int, faceIndex: int, value: float, loadCaseIndex: int = 0) -> int
Apply pressure to element face. In a transient response it stays applied in every following step
(clearLoad() first to change it).
Args:
elemIndex (int): Element index
faceIndex (int): Face index
value (float): Pressure value (Pa)
loadCaseIndex (int): Load case index, linear static only (default: 0)
getNumLoadCases() -> int
Get number of load cases.
setStorageSystem(storageType: StorageSystem) -> None
Set storage of the system matrices.
setPressureDistributionType(distributionType: PressureDistribution) -> None
Set how pressures are passed to face nodes.
setEigenvaluePerformanceMode(mode: EigenvaluePerformanceMode) -> None
Set eigenvalue solver favoring speed or accuracy.
setNfaNumModes(numModes: int) -> None
Set number of modes of the natural frequencies analysis (0: all within the frequency limits).
getNfaNumModes() -> int
setNfaLowerFreq(frequency: float) -> None
Set lower frequency limit (Hz).
getNfaLowerFreq() -> float
setNfaUpperFreq(frequency: float) -> None
Set upper frequency limit (Hz; 0: no limit, the lowest numModes modes).
getNfaUpperFreq() -> float
setLbaNumModes(numModes: int) -> None
Set number of modes of the buckling analysis (0: all within the eigenvalue limits).
getLbaNumModes() -> int
setLbaLowerEigenvalue(eigenvalue: float) -> None
Set lower eigenvalue (load factor) limit.
getLbaLowerEigenvalue() -> float
setLbaUpperEigenvalue(eigenvalue: float) -> None
Set upper eigenvalue (load factor) limit (0 with a lower limit that is not negative: no limit).
getLbaUpperEigenvalue() -> float
setLbaPressureLoadStiffness(include: bool) -> None
Include the load stiffness of pressures in buckling (default True): a pressure stays normal to its face, so its force turns with the face as the structure deflects. False: pressures act as fixed nodal forces, right for a pressure standing for a load that keeps its direction, such as a contact.
getLbaPressureLoadStiffness() -> bool
setStepSize(stepSize: float) -> None
Set time step of the transient response (s).
getStepSize() -> float
setStructuralDampingCoefficient(coefficient: float) -> None
Set structural damping coefficient of the transient response.
getStructuralDampingCoefficient() -> float
setStructuralDampingConversionFrequency(frequency: float) -> None
Set frequency (Hz) at which structural damping is converted to viscous damping.
getStructuralDampingConversionFrequency() -> float
runLinearStatic() -> None
Run linear static analysis (every load case).
runNaturalFrequencies(numModes: int, frequencyMin: float, frequencyMax: float) -> None
Run natural frequencies (modal) analysis.
Args:
numModes (int): Number of modes to extract (0: all modes within the frequency limits)
frequencyMin (float): Minimum frequency (Hz)
frequencyMax (float): Maximum frequency (Hz) (0: no limit, the lowest numModes modes)
If numModes or frequencyMax is 0, the modes are counted first, which takes
longer than giving both.
runNaturalFrequenciesAnalysis() -> None
Run natural frequencies analysis with the limits set by setNfa*.
runLinearBuckling(numModes: int, eigenvalueMin: float = 0.0, eigenvalueMax: float = 0.0) -> None
Run linear buckling analysis of the load case 0 (the preload).
Args:
numModes (int): Number of modes (0: all modes within the eigenvalue limits)
eigenvalueMin (float): Lower eigenvalue (load factor) limit (default 0)
eigenvalueMax (float): Upper limit (default 0: no limit, the lowest numModes modes)
Results: eigenvalues (load factors) and mode shapes with AnalysisType.LINEAR_BUCKLING; the
displacements and stresses of the preload with the same analysis type.
runLinearBucklingAnalysis() -> None
Run linear buckling analysis with the limits set by setLba*.
initializeTransientResponse() -> None
Initialize transient response analysis (time step and damping set before). Then for each step: change the loads if they vary in time (clearLoad(), then addForce/addPressure: applied loads stay until cleared), call runTransientResponseStep() and read the results of the step with AnalysisType.TRANSIENT_RESPONSE.
runTransientResponseStep() -> None
Run one time step of the transient response with the loads applied at that time.
getNumSteps() -> int
Get number of transient steps run, the initial one included.
getProgress() -> float
Get progress of the running analysis (0 to 1).
requestStop() -> None
Ask the running analysis to stop (from another thread).
requestPause() -> None
Ask the running analysis to pause (from another thread).
requestResume() -> None
Resume a paused analysis.
getNumModes(analysisType: AnalysisType = <AnalysisType.NATURAL_FREQUENCIES: 1>) -> int
Get number of modes extracted.
Args:
analysisType (AnalysisType): NATURAL_FREQUENCIES (default) or LINEAR_BUCKLING
Returns:
int: Number of modes
getFrequency(modeIndex: int) -> float
Get natural frequency for mode.
Args:
modeIndex (int): Mode index
Returns:
float: Frequency in Hz
getFrequencies() -> numpy.NDArray[numpy.float64]
Get all natural frequencies (Hz) as an array.
getEigenvalue(modeIndex: int, analysisType: AnalysisType = <AnalysisType.NATURAL_FREQUENCIES: 1>) -> float
Get eigenvalue of a mode: squared circular frequency, or buckling load factor.
Args:
modeIndex (int): Mode index
analysisType (AnalysisType): NATURAL_FREQUENCIES (default) or LINEAR_BUCKLING
getEigenvalues(analysisType: AnalysisType = <AnalysisType.NATURAL_FREQUENCIES: 1>) -> numpy.NDArray[numpy.float64]
Get the eigenvalues of all modes as an array.
getEigenvectorValue(node: int, dof: int, modeIndex: int, analysisType: AnalysisType = <AnalysisType.NATURAL_FREQUENCIES: 1>) -> float
Get mode shape value of a node and DOF.
Args:
node (int): Node index
dof (int): DOF index (0-5)
modeIndex (int): Mode index
analysisType (AnalysisType): NATURAL_FREQUENCIES (default) or LINEAR_BUCKLING
getEigenvector(modeIndex: int, analysisType: AnalysisType = <AnalysisType.NATURAL_FREQUENCIES: 1>) -> numpy.NDArray[numpy.float64]
Get mode shape of all nodes, shape (numNodes, 6).
getDisplacementValue(node: int, dof: int, caseOrModeIndex: int = 0, analysisType: AnalysisType = <AnalysisType.NONE: 0>) -> float
Get displacement value for a node and DOF.
Args:
node (int): Node index
dof (int): DOF index (0-5)
caseOrModeIndex (int): Load case index (linear static), unused otherwise
analysisType (AnalysisType): LINEAR_STATIC, LINEAR_BUCKLING (preload) or TRANSIENT_RESPONSE
(current step); default NONE: the analysis run last
Returns:
float: Displacement value
getDisplacements(caseIndex: int = 0, analysisType: AnalysisType = <AnalysisType.NONE: 0>) -> numpy.NDArray[numpy.float64]
Get displacements of all nodes, shape (numNodes, 6).
Args:
caseIndex (int): Load case index (linear static; default 0)
analysisType (AnalysisType): As for getDisplacementValue (default NONE: the analysis run last)
getVonMisesStress(elemIndex: int, caseIndex: int = 0, analysisType: AnalysisType = <AnalysisType.LINEAR_STATIC: 2>) -> float
Get maximum Von Mises stress of an element.
Args:
elemIndex (int): Element index
caseIndex (int): Load case index (linear static; default 0)
analysisType (AnalysisType): LINEAR_STATIC (default), LINEAR_BUCKLING (preload) or
TRANSIENT_RESPONSE (current step)
getVonMisesStresses(caseIndex: int = 0, analysisType: AnalysisType = <AnalysisType.LINEAR_STATIC: 2>) -> numpy.NDArray[numpy.float64]
Get maximum Von Mises stress of all elements, shape (numElements,).
getNumDofs() -> int
Get number of DOFs in system.
Returns:
int: Number of DOFs
releaseLicense() -> None
Give the license back to the license server now (the next run takes it again).
getLicenseStamp() -> str
Get the line naming the registered user and the license type, as put on results.
clear() -> None
Clear all data
clearMaterials() -> None
Clear materials
clearProperties() -> None
Clear properties
clearNodes() -> None
Clear nodes
clearElements() -> None
Clear elements
clearConstraints() -> None
Clear constraints
clearMpcs() -> None
Clear multi-point constraints
clearLoad() -> None
Clear loads
exception AfemeError(RuntimeError)
Enumerations
enum AnalysisType
Analysis types (whose results to read)
| NONE | 0 | The analysis run last |
| NATURAL_FREQUENCIES | 1 | Natural frequencies analysis |
| LINEAR_STATIC | 2 | Linear static analysis |
| LINEAR_BUCKLING | 3 | Linear buckling analysis |
| TRANSIENT_RESPONSE | 4 | Transient response analysis |
enum StorageSystem
Storage of the system matrices
| SPARSE | 0 | Sparse (default) |
| DENSE | 1 | Dense |
enum PressureDistribution
How a pressure is passed to the nodes of a face
| EQUAL | 0 | Equally to the face nodes |
| SHAPE_FUNCTION | 1 | According to the shape functions |
enum EigenvaluePerformanceMode
Eigenvalue solver favoring speed or accuracy
| SPEED | 0 | Speed |
| ACCURACY | 1 | Accuracy |