Skip to content

Statics

fpc.statics

statics.py - equilibrium and load analysis for bodies at rest.

Statics is dynamics with everything standing still: the sum of forces and the sum of moments are both zero. These helpers cover the calculations that show up constantly in structural and machine design - reactions, moments, stress, and friction.

Statics

Common statics calculations for bodies in equilibrium.

Source code in fpc/statics.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
class Statics:
    """Common statics calculations for bodies in equilibrium."""

    def moment(self, *, force, distance):
        """Moment (torque) of a force about a point: M = F * d.

        ``distance`` is the perpendicular distance (moment arm) from the pivot
        to the force's line of action.

        :param force: applied force [N]
        :param distance: perpendicular moment arm [m]
        :returns: moment [N*m]
        """
        return force * distance

    def resultant_2d(self, *, fx, fy):
        """Combine perpendicular force components into magnitude and direction.

        :param fx: force component along x [N]
        :param fy: force component along y [N]
        :returns: tuple (magnitude [N], angle [degrees] measured from +x axis)
        """
        magnitude = math.hypot(fx, fy)  # sqrt(fx^2 + fy^2)
        angle_deg = math.degrees(math.atan2(fy, fx))
        return magnitude, angle_deg

    def beam_reactions_point_load(self, *, span, load, load_position):
        """Support reactions for a simply supported beam with one point load.

        The beam rests on a pin at the left (A) and a roller at the right (B).
        Summing moments about each support gives the two vertical reactions.

        :param span: distance between supports L [m]
        :param load: downward point load P [N]
        :param load_position: distance of the load from support A [m]
        :returns: tuple (reaction at A [N], reaction at B [N])
        """
        # Sum of moments about A = 0  ->  R_B * L = P * a
        reaction_b = load * load_position / span
        # Sum of vertical forces = 0  ->  R_A + R_B = P
        reaction_a = load - reaction_b
        return reaction_a, reaction_b

    def axial_stress(self, *, force, area):
        """Normal (axial) stress: sigma = F / A.

        :param force: axial force [N]
        :param area: cross-sectional area [m^2]
        :returns: stress [Pa]
        """
        return force / area

    def factor_of_safety(self, *, strength, applied_stress):
        """Factor of safety: FoS = material strength / applied stress.

        A value above 1 means the part can carry more than it currently sees.

        :param strength: allowable or yield strength [Pa]
        :param applied_stress: actual working stress [Pa]
        :returns: dimensionless factor of safety
        """
        return strength / applied_stress

    def friction_force(self, *, coefficient, normal_force):
        """Maximum dry friction force: F = mu * N.

        :param coefficient: coefficient of friction mu [-]
        :param normal_force: normal (perpendicular) force N [N]
        :returns: maximum friction force [N]
        """
        return coefficient * normal_force

moment(*, force, distance)

Moment (torque) of a force about a point: M = F * d.

distance is the perpendicular distance (moment arm) from the pivot to the force's line of action.

Parameters:

Name Type Description Default
force

applied force [N]

required
distance

perpendicular moment arm [m]

required

Returns:

Type Description

moment [N*m]

Source code in fpc/statics.py
18
19
20
21
22
23
24
25
26
27
28
def moment(self, *, force, distance):
    """Moment (torque) of a force about a point: M = F * d.

    ``distance`` is the perpendicular distance (moment arm) from the pivot
    to the force's line of action.

    :param force: applied force [N]
    :param distance: perpendicular moment arm [m]
    :returns: moment [N*m]
    """
    return force * distance

resultant_2d(*, fx, fy)

Combine perpendicular force components into magnitude and direction.

Parameters:

Name Type Description Default
fx

force component along x [N]

required
fy

force component along y [N]

required

Returns:

Type Description

tuple (magnitude [N], angle [degrees] measured from +x axis)

Source code in fpc/statics.py
30
31
32
33
34
35
36
37
38
39
def resultant_2d(self, *, fx, fy):
    """Combine perpendicular force components into magnitude and direction.

    :param fx: force component along x [N]
    :param fy: force component along y [N]
    :returns: tuple (magnitude [N], angle [degrees] measured from +x axis)
    """
    magnitude = math.hypot(fx, fy)  # sqrt(fx^2 + fy^2)
    angle_deg = math.degrees(math.atan2(fy, fx))
    return magnitude, angle_deg

beam_reactions_point_load(*, span, load, load_position)

Support reactions for a simply supported beam with one point load.

The beam rests on a pin at the left (A) and a roller at the right (B). Summing moments about each support gives the two vertical reactions.

Parameters:

Name Type Description Default
span

distance between supports L [m]

required
load

downward point load P [N]

required
load_position

distance of the load from support A [m]

required

Returns:

Type Description

tuple (reaction at A [N], reaction at B [N])

Source code in fpc/statics.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def beam_reactions_point_load(self, *, span, load, load_position):
    """Support reactions for a simply supported beam with one point load.

    The beam rests on a pin at the left (A) and a roller at the right (B).
    Summing moments about each support gives the two vertical reactions.

    :param span: distance between supports L [m]
    :param load: downward point load P [N]
    :param load_position: distance of the load from support A [m]
    :returns: tuple (reaction at A [N], reaction at B [N])
    """
    # Sum of moments about A = 0  ->  R_B * L = P * a
    reaction_b = load * load_position / span
    # Sum of vertical forces = 0  ->  R_A + R_B = P
    reaction_a = load - reaction_b
    return reaction_a, reaction_b

axial_stress(*, force, area)

Normal (axial) stress: sigma = F / A.

Parameters:

Name Type Description Default
force

axial force [N]

required
area

cross-sectional area [m^2]

required

Returns:

Type Description

stress [Pa]

Source code in fpc/statics.py
58
59
60
61
62
63
64
65
def axial_stress(self, *, force, area):
    """Normal (axial) stress: sigma = F / A.

    :param force: axial force [N]
    :param area: cross-sectional area [m^2]
    :returns: stress [Pa]
    """
    return force / area

factor_of_safety(*, strength, applied_stress)

Factor of safety: FoS = material strength / applied stress.

A value above 1 means the part can carry more than it currently sees.

Parameters:

Name Type Description Default
strength

allowable or yield strength [Pa]

required
applied_stress

actual working stress [Pa]

required

Returns:

Type Description

dimensionless factor of safety

Source code in fpc/statics.py
67
68
69
70
71
72
73
74
75
76
def factor_of_safety(self, *, strength, applied_stress):
    """Factor of safety: FoS = material strength / applied stress.

    A value above 1 means the part can carry more than it currently sees.

    :param strength: allowable or yield strength [Pa]
    :param applied_stress: actual working stress [Pa]
    :returns: dimensionless factor of safety
    """
    return strength / applied_stress

friction_force(*, coefficient, normal_force)

Maximum dry friction force: F = mu * N.

Parameters:

Name Type Description Default
coefficient

coefficient of friction mu [-]

required
normal_force

normal (perpendicular) force N [N]

required

Returns:

Type Description

maximum friction force [N]

Source code in fpc/statics.py
78
79
80
81
82
83
84
85
def friction_force(self, *, coefficient, normal_force):
    """Maximum dry friction force: F = mu * N.

    :param coefficient: coefficient of friction mu [-]
    :param normal_force: normal (perpendicular) force N [N]
    :returns: maximum friction force [N]
    """
    return coefficient * normal_force