Beam Numerical

Overview

Introduction Beam numerical analysis is the computational process of predicting how a one-dimensional structural member responds to loads, supports, and material stiffness. In practice, this means estimating reaction forces at supports, internal actions (shear and moment), and displacement (deflection) along the span. The category sits on top of classical beam mechanics, especially Euler–Bernoulli beam theory, and exposes that theory through spreadsheet-friendly functions.

For business and engineering users, this matters because many decisions are constrained by serviceability and strength requirements. In building projects, a floor beam that is strong enough may still be unacceptable if deflection causes cracking in finishes, vibration discomfort, or misalignment of façade elements. In manufacturing, machine frames and support rails need tight movement limits to maintain tolerance stacks. In utilities and energy systems, support structures for ducts, pipes, and cable trays require predictable reactions and moments to size anchors and avoid overloading existing framing.

The tools in this category provide a practical bridge between quick hand calculations and full finite-element software. They are faster and more scalable than repeatedly applying tabulated formulas in Excel, but simpler than running full 3D structural models for early-stage checks. Under the hood, the implementation is based on the IndeterminateBeam Python library, which is designed to analyze determinate and indeterminate beam configurations, including spring supports and mixed load types.

Within this category, ANALYZE_BEAM is the broad model-level workflow that solves the beam and returns multiple result components in one call. BEAM_DEFLECTION is a targeted query function for displacement at a specific coordinate, and BEAM_REACTION is a targeted query function for one reaction component at a support location. Together they support both exploratory modeling and production spreadsheet pipelines where one KPI is needed per cell.

From a dual pillar perspective, this overview page is the conceptual pillar: it explains what beam numerical analysis is, when to use it, and how to choose the right calculator for the job. The individual function sections in the category index are the tactical pillar: they provide syntax, argument-level details, and executable examples.

When to Use It Use beam numerical tools when the job to be done is “turn a load/support concept into defensible structural response values quickly.” The strongest use cases appear where teams need repeatable calculations, transparent assumptions, and the ability to iterate many scenarios.

A common scenario is early-stage structural option screening. Suppose a project team is comparing two framing layouts for a mezzanine: one with shorter spans and denser columns, another with longer spans and fewer columns. They need to estimate support reactions for connection design and estimate deflection limits under service load combinations. Here, ANALYZE_BEAM is typically the first stop because it gives a broad response snapshot. Then BEAM_REACTION can populate a comparison table for anchor design loads at each support, and BEAM_DEFLECTION can check key points (midspan, quarter points, or equipment support points).

A second scenario is retrofit and change-order impact analysis. In renovation projects, loading conditions change after initial design: heavier partitions, new suspended equipment, or redistributed process loads. Engineers often need rapid checks against existing members before issuing field instructions. With the same support and geometry model, they can swap load rows and immediately inspect how reactions and deflections shift. This is especially useful for communicating risk: a PM can see that a small load increase may cause a disproportionately large increase in fixed-end moment or deflection at a critical location.

A third scenario is design automation in bid, estimating, or productized engineering workflows. Many teams have recurring beam problems with parameterized spans and loads (for example, modular platforms, racking systems, and repeated bays). Instead of maintaining dozens of brittle worksheet formulas and lookup tables, they can standardize a compact set of calls: ANALYZE_BEAM for model QA, BEAM_REACTION for support design exports, and BEAM_DEFLECTION for serviceability checks. This approach improves auditability, because assumptions are concentrated in explicit input arrays rather than hidden across multiple worksheet tabs.

Use these calculators when any of the following conditions apply: - More than one load type is present (point load, point moment, uniformly distributed load, or trapezoidal load). - Support conditions are mixed (pin/roller/fixed) or include springs. - The beam is statically indeterminate, so simple equilibrium equations alone are insufficient. - You need repeatable coordinate-based queries for reports or downstream design sheets. - You need to run multiple what-if cases quickly without rebuilding formulas each time.

Avoid relying on this category as your only source when behavior is clearly outside small-deflection linear beam assumptions, when geometric/material nonlinearity dominates, or when local effects (plate action, torsion-dominant response, connection flexibility, stress concentrations) govern design decisions. In those situations, these tools are best used as a screening layer before escalating to higher-fidelity analysis.

How It Works At a high level, all three functions represent the same workflow: define beam geometry and stiffness, define supports as displacement/rotation constraints (or support springs), define external loads, solve the boundary value problem, and query the resulting response fields.

The conceptual basis comes from linear elastic beam theory. In Euler–Bernoulli form, the governing relationship is commonly written as:

\frac{d^2}{dx^2}\left(EI\frac{d^2 w}{dx^2}\right)=q(x)

For constant E and I, this reduces to:

EI\,\frac{d^4 w}{dx^4}=q(x)

where w(x) is vertical deflection, q(x) is distributed load, E is Young’s modulus, and I is the second moment of area. Once deflection is known, shear and moment follow by derivative/integral relationships (under a chosen sign convention), and support reactions are recovered from equilibrium plus compatibility.

The critical distinction in real projects is determinate versus indeterminate systems. For determinate beams, reactions can be found using static equilibrium equations alone. For indeterminate beams, there are more unknown reactions than independent equilibrium equations. Additional compatibility conditions are required (for example, zero displacement at supports, prescribed spring displacement-force behavior). The IndeterminateBeam documentation explains this framework and the sign/unit conventions used by the library.

In Boardflare’s category implementation, the three functions map to three layers of this process:

  1. ANALYZE_BEAM corresponds to full-model solve behavior (aligned with Beam.analyse from the upstream library). It is designed for “solve once, inspect many outputs.” Inputs include span, support matrix, load matrix, and optional section/material properties. Outputs include support reactions and sampled internal responses.
  2. BEAM_DEFLECTION corresponds to “solve and query displacement at one coordinate” (aligned with Beam.get_deflection after analysis). It is optimized for single-cell serviceability checks and dashboard metrics.
  3. BEAM_REACTION corresponds to “solve and query one reaction component at one support coordinate” (aligned with Beam.get_reaction after analysis). It is optimized for support load extraction workflows.

Input modeling conventions matter more than most users expect: - Supports are entered as rows with position and restraint flags/stiffnesses (horizontal, vertical, rotational). This defines the boundary conditions. - Loads are entered as typed rows (point, moment, UDL, trapezoidal, and optional horizontal point load in the Python example). - Coordinate consistency is essential: all support and load coordinates should lie on the same span axis and use consistent units. - Sign convention consistency is essential: if downward loads are negative in your model, keep that convention everywhere.

From a numerical perspective, these tools are not finite-element meshing of arbitrary geometry; they are beam-theory solvers with explicit support/load objects and coordinate queries. That gives a strong speed-to-clarity tradeoff for everyday engineering calculations. It also means the user should understand the assumptions:

  • Linear elastic behavior and small strains are assumed.
  • Beam idealization is 1D; cross-section effects enter primarily through E, I, and (where used) area/stiffness parameters.
  • Support idealization is as modeled; real-world semi-rigid connections should be represented carefully (for example via spring stiffness when known).
  • Results are only as good as boundary conditions and load definitions.

These assumptions are typical for conceptual design, load path studies, and spreadsheet-driven engineering QA. They are often sufficient for sizing and comparison tasks, but final design packages may still require code-specific checks and higher-order modeling depending on jurisdiction and project risk.

Practical Example Consider a realistic workflow for an industrial platform beam where an engineer needs both serviceability and support design checks. The beam spans 8 m between two supports, carries a machine point load near midspan, and includes a maintenance walk load represented as a distributed load. The engineer’s goals are:

  1. Confirm approximate support reactions for base plate and anchor checks.
  2. Confirm deflection at the machine mounting location.
  3. Produce a repeatable worksheet template for scenario updates.

Step 1 is model setup. The engineer enters span, support definitions, and load rows in structured ranges. Support rows include coordinate and restraint flags. Load rows include type plus magnitude and coordinate range. This is where most model quality issues happen, so teams typically enforce validation rules (for example, support coordinates within span, nonempty load types, and consistent units).

Step 2 is baseline solve with ANALYZE_BEAM. This gives a broad model response and acts as a “model health check.” If reactions look physically unreasonable (for example, unexpected sign reversals or near-zero reactions at a clearly loaded support), the engineer inspects boundary conditions before proceeding. This mirrors good structural practice: never trust a single extracted number before the global model behavior makes sense.

Step 3 is serviceability query with BEAM_DEFLECTION. The engineer queries deflection at the machine coordinate and also at midspan. If the machine vendor has a movement limit, that value can be compared directly. Because the function is coordinate-based, the worksheet can expose a cell for query_x, allowing quick sweeps across critical points without rewriting formulas.

Step 4 is support design extraction with BEAM_REACTION. For each support location, the engineer pulls vertical reaction ("y") and, if relevant, moment reaction ("m") for fixed ends. Horizontal reaction ("x") is queried when horizontal loads or restraints are modeled. These results feed connection and anchorage checks in adjacent sheets.

Step 5 is scenario management. The team duplicates the input block for alternate machine weights, shifted equipment position, and future expansion load. Because formulas are stable and row-based, each case can be recalculated quickly. This is where Python-backed functions outperform static lookup methods in Excel: the same model logic applies across many parameter changes.

Step 6 is communication and QA. The engineer reports not just single values, but a short interpretation: “Case B increases right support vertical reaction by 18% and doubles fixed-end moment at Support A; deflection remains under target.” This format is decision-ready for project managers and reviewers.

Compared with traditional manual spreadsheet modeling, this workflow reduces hidden formula complexity. Classic approaches often split each load type into separate equations, stitch segments manually, and rely on copied formulas that are hard to audit. In contrast, the Boardflare approach keeps inputs explicit, delegates beam solving to the library, and keeps outputs query-oriented. It is faster to review and less fragile when assumptions change.

How to Choose Choose the function based on the output granularity needed for the immediate decision. A simple rule is: start broad, then query narrow.

graph TD
    A[Start with beam inputs: span, supports, loads] --> B{Need full model response?}
    B -- Yes --> C[Use ANALYZE_BEAM]
    B -- No --> D{Need displacement at one x?}
    D -- Yes --> E[Use BEAM_DEFLECTION]
    D -- No --> F{Need support reaction component?}
    F -- Yes --> G[Use BEAM_REACTION]
    F -- No --> H[Use ANALYZE_BEAM for initial diagnostics]
    C --> I[Then optionally query targeted values]
    I --> E
    I --> G

The comparison below helps with day-to-day selection:

Function Primary question answered Best use case Strengths Tradeoffs
ANALYZE_BEAM “What is the overall response of this beam model?” Initial model solve, QA, and multi-output review Broad visibility into reactions and internal responses; good first-pass diagnostic tool More output than needed for a single KPI; may require post-processing for specific report cells
BEAM_DEFLECTION “What is the deflection at coordinate x?” Serviceability checks at specific points Fast single-value extraction; easy to parameterize query_x in sheets Narrow output; does not replace full model sanity checking
BEAM_REACTION “What reaction component occurs at support coordinate x?” Connection/base/anchor load extraction Direct access to x, y, or m component for report tables Requires accurate support coordinate and direction selection; narrow output by design

A practical decision sequence is:

  1. Build and verify the model once with ANALYZE_BEAM.
  2. If the decision is about movement limits, use BEAM_DEFLECTION for each critical coordinate.
  3. If the decision is about supports/connections, use BEAM_REACTION for required components.
  4. If results appear unintuitive, return to step 1 and validate supports, signs, and load coordinates.

For organizations implementing repeatable templates, this also suggests a robust architecture: keep one block where ANALYZE_BEAM is used as a model validation checkpoint, then expose thin calculation layers with BEAM_DEFLECTION and BEAM_REACTION for report-ready values. This preserves both transparency and speed.

In summary, the category is most effective when users treat it as a structured decision system rather than three isolated formulas. ANALYZE_BEAM establishes model confidence, BEAM_DEFLECTION answers serviceability-at-point questions, and BEAM_REACTION answers support load-at-point questions. That division maps cleanly to real engineering workflows and supports reliable, auditable spreadsheet-based structural analysis.

ANALYZE_BEAM

Performs a comprehensive numerical analysis of a 1D beam under various loading conditions. Using the indeterminatebeam library, this function calculates the reaction forces and moments at specified support locations, as well as internal forces (axial, shear, bending moment) and deflections across the beam span.

The analysis considers the equilibrium of forces and moments, solving for indeterminacy using energy methods. Users can specify fixed, pinned, roller, or spring supports, and apply point loads, moments, or distributed loads.

Excel Usage

=ANALYZE_BEAM(span, supports, loads, e_modulus, second_moment, area)
  • span (float, required): Total length of the beam (m).

  • supports (list[list], required): 2D array of support definitions [[x, rx, ry, rm, …]]. x: position (m). rx, ry, rm: 1 for fixed, 0 for free (or stiffness value for spring).

  • loads (list[list], required): 2D array of load definitions [[type, val1, val2, x1, x2]]. type: “point”, “moment”, “udl”, “trap”. val1: force/moment value (N or N/m). val2: ending force for trapezoidal (N/m). x1, x2: start/end positions (m).

  • e_modulus (float, optional, default: 200000000000): Young’s Modulus (Pa).

  • second_moment (float, optional, default: 0.00000905): Second moment of area (m4).

  • area (float, optional, default: 0.23): Cross-sectional area (m2).

Returns (dict): A dictionary containing beam reactions and internal forces at sampled intervals.

Example 1: Simply supported beam with point load

Inputs:

span supports loads
5 0 0 1 0 point -1000 0 2.5 0
5 0 1 0

Excel formula:

=ANALYZE_BEAM(5, {0,0,1,0;5,0,1,0}, {"point",-1000,0,2.5,0})

Expected output:

{"type":"Double","basicValue":5,"properties":{"React":{"type":"Array","elements":[[{"type":"String","basicValue":"Pos"},{"type":"String","basicValue":"Rx"},{"type":"String","basicValue":"Ry"},{"type":"String","basicValue":"Rm"}],[{"type":"Double","basicValue":0},{"type":"Double","basicValue":0},{"type":"Double","basicValue":500},{"type":"Double","basicValue":0}],[{"type":"Double","basicValue":5},{"type":"Double","basicValue":0},{"type":"Double","basicValue":500},{"type":"Double","basicValue":0}]]},"Forces":{"type":"Array","elements":[[{"type":"String","basicValue":"Pos"},{"type":"String","basicValue":"V"},{"type":"String","basicValue":"M"},{"type":"String","basicValue":"v"}],[{"type":"Double","basicValue":0},{"type":"Double","basicValue":500},{"type":"Double","basicValue":0.00005},{"type":"Double","basicValue":1e-10}],[{"type":"Double","basicValue":2.5},{"type":"Double","basicValue":500},{"type":"Double","basicValue":1250},{"type":"Double","basicValue":-0.00143877}],[{"type":"Double","basicValue":5},{"type":"Double","basicValue":-500},{"type":"Double","basicValue":0.00005},{"type":"Double","basicValue":-1e-10}]]}}}

Example 2: Cantilever with UDL

Inputs:

span supports loads
3 0 1 1 1 udl -500 0 0 3

Excel formula:

=ANALYZE_BEAM(3, {0,1,1,1}, {"udl",-500,0,0,3})

Expected output:

{"type":"Double","basicValue":3,"properties":{"React":{"type":"Array","elements":[[{"type":"String","basicValue":"Pos"},{"type":"String","basicValue":"Rx"},{"type":"String","basicValue":"Ry"},{"type":"String","basicValue":"Rm"}],[{"type":"Double","basicValue":0},{"type":"Double","basicValue":0},{"type":"Double","basicValue":1500},{"type":"Double","basicValue":2250}]]},"Forces":{"type":"Array","elements":[[{"type":"String","basicValue":"Pos"},{"type":"String","basicValue":"V"},{"type":"String","basicValue":"M"},{"type":"String","basicValue":"v"}],[{"type":"Double","basicValue":0},{"type":"Double","basicValue":1500},{"type":"Double","basicValue":-2250},{"type":"Double","basicValue":0}],[{"type":"Double","basicValue":1.5},{"type":"Double","basicValue":750},{"type":"Double","basicValue":-562.5},{"type":"Double","basicValue":-0.000990591}],[{"type":"Double","basicValue":3},{"type":"Double","basicValue":0.00005},{"type":"Double","basicValue":0},{"type":"Double","basicValue":-0.00279696}]]}}}

Example 3: Propped cantilever

Inputs:

span supports loads
4 0 1 1 1 point -2000 0 2 0
4 0 1 0

Excel formula:

=ANALYZE_BEAM(4, {0,1,1,1;4,0,1,0}, {"point",-2000,0,2,0})

Expected output:

{"type":"Double","basicValue":4,"properties":{"React":{"type":"Array","elements":[[{"type":"String","basicValue":"Pos"},{"type":"String","basicValue":"Rx"},{"type":"String","basicValue":"Ry"},{"type":"String","basicValue":"Rm"}],[{"type":"Double","basicValue":0},{"type":"Double","basicValue":0},{"type":"Double","basicValue":1375},{"type":"Double","basicValue":1500}],[{"type":"Double","basicValue":4},{"type":"Double","basicValue":0},{"type":"Double","basicValue":625},{"type":"Double","basicValue":0}]]},"Forces":{"type":"Array","elements":[[{"type":"String","basicValue":"Pos"},{"type":"String","basicValue":"V"},{"type":"String","basicValue":"M"},{"type":"String","basicValue":"v"}],[{"type":"Double","basicValue":0},{"type":"Double","basicValue":1375},{"type":"Double","basicValue":-1500},{"type":"Double","basicValue":0}],[{"type":"Double","basicValue":2},{"type":"Double","basicValue":1375},{"type":"Double","basicValue":1250},{"type":"Double","basicValue":-0.000644567}],[{"type":"Double","basicValue":4},{"type":"Double","basicValue":-625},{"type":"Double","basicValue":0.0000625},{"type":"Double","basicValue":-1e-10}]]}}}

Example 4: Beam with trapezoidal load

Inputs:

span supports loads
6 0 0 1 0 trap -1000 -2000 0 6
6 0 1 0

Excel formula:

=ANALYZE_BEAM(6, {0,0,1,0;6,0,1,0}, {"trap",-1000,-2000,0,6})

Expected output:

{"type":"Double","basicValue":6,"properties":{"React":{"type":"Array","elements":[[{"type":"String","basicValue":"Pos"},{"type":"String","basicValue":"Rx"},{"type":"String","basicValue":"Ry"},{"type":"String","basicValue":"Rm"}],[{"type":"Double","basicValue":0},{"type":"Double","basicValue":0},{"type":"Double","basicValue":4000},{"type":"Double","basicValue":0}],[{"type":"Double","basicValue":6},{"type":"Double","basicValue":0},{"type":"Double","basicValue":5000},{"type":"Double","basicValue":0}]]},"Forces":{"type":"Array","elements":[[{"type":"String","basicValue":"Pos"},{"type":"String","basicValue":"V"},{"type":"String","basicValue":"M"},{"type":"String","basicValue":"v"}],[{"type":"Double","basicValue":0},{"type":"Double","basicValue":4000},{"type":"Double","basicValue":0.0004},{"type":"Double","basicValue":7e-10}],[{"type":"Double","basicValue":3},{"type":"Double","basicValue":250},{"type":"Double","basicValue":6750},{"type":"Double","basicValue":-0.0139848}],[{"type":"Double","basicValue":6},{"type":"Double","basicValue":-5000},{"type":"Double","basicValue":0.0005},{"type":"Double","basicValue":-8e-10}]]}}}

Python Code

Show Code
from indeterminatebeam import Beam, Support
from indeterminatebeam.loading import PointLoadV, PointLoadH, PointTorque, UDLV, TrapezoidalLoadV

def analyze_beam(span, supports, loads, e_modulus=200000000000, second_moment=9.05e-06, area=0.23):
    """
    Perform numerical analysis of a structural beam to determine reactions and internal forces.

    See: https://indeterminatebeam.readthedocs.io/en/main/docstrings.html#indeterminatebeam.Beam.analyse

    This example function is provided as-is without any representation of accuracy.

    Args:
        span (float): Total length of the beam (m).
        supports (list[list]): 2D array of support definitions [[x, rx, ry, rm, ...]].
    x: position (m).
    rx, ry, rm: 1 for fixed, 0 for free (or stiffness value for spring).

        loads (list[list]): 2D array of load definitions [[type, val1, val2, x1, x2]].
    type: "point", "moment", "udl", "trap".
    val1: force/moment value (N or N/m).
    val2: ending force for trapezoidal (N/m).
    x1, x2: start/end positions (m).

        e_modulus (float, optional): Young's Modulus (Pa). Default is 200000000000.
        second_moment (float, optional): Second moment of area (m4). Default is 9.05e-06.
        area (float, optional): Cross-sectional area (m2). Default is 0.23.

    Returns:
        dict: A dictionary containing beam reactions and internal forces at sampled intervals.
    """
    try:
        def to2d(value):
            return [[value]] if not isinstance(value, list) else value

        supports = to2d(supports)
        loads = to2d(loads)

        if not isinstance(supports, list) or not all(isinstance(row, list) for row in supports):
            return "Error: Invalid input - supports must be a 2D list"
        if not isinstance(loads, list) or not all(isinstance(row, list) for row in loads):
            return "Error: Invalid input - loads must be a 2D list"

        beam = Beam(span=span, E=e_modulus, I=second_moment, A=area)

        support_rows = []
        has_x_restraint = False
        for row in supports:
            if len(row) < 4:
                continue
            try:
                x_pos = float(row[0])
                rx_raw = float(row[1])
                ry_raw = float(row[2])
                rm_raw = float(row[3])
            except (TypeError, ValueError):
                continue

            kx = rx_raw if rx_raw > 1 else None
            ky = ry_raw if ry_raw > 1 else None
            rx_fixed = int(bool(rx_raw)) if kx is None else 0
            ry_fixed = int(bool(ry_raw)) if ky is None else 0
            rm_fixed = int(bool(rm_raw))

            if rx_fixed == 1 or (kx is not None and kx > 0):
                has_x_restraint = True

            support_rows.append({
                "x": x_pos,
                "fixed": (rx_fixed, ry_fixed, rm_fixed),
                "kx": kx,
                "ky": ky,
            })

        if not support_rows:
            return "Error: At least one valid support is required"

        if not has_x_restraint:
            support_rows[0]["fixed"] = (1, support_rows[0]["fixed"][1], support_rows[0]["fixed"][2])
            support_rows[0]["kx"] = None

        for support in support_rows:
            beam.add_supports(Support(support["x"], fixed=support["fixed"], kx=support["kx"], ky=support["ky"]))

        for row in loads:
            if len(row) < 2:
                continue
            l_type = str(row[0]).lower()
            try:
                val1 = float(row[1])
                val2 = float(row[2]) if len(row) > 2 else 0.0
                x1 = float(row[3]) if len(row) > 3 else 0.0
                x2 = float(row[4]) if len(row) > 4 else 0.0
            except (TypeError, ValueError):
                continue

            if l_type == "point":
                beam.add_loads(PointLoadV(val1, x1))
            elif l_type == "moment":
                beam.add_loads(PointTorque(val1, x1))
            elif l_type == "udl":
                beam.add_loads(UDLV(val1, (x1, x2)))
            elif l_type == "trap":
                beam.add_loads(TrapezoidalLoadV((val1, val2), (x1, x2)))
            elif l_type == "point_h":
                beam.add_loads(PointLoadH(val1, x1))

        beam.analyse()

        reactions_data = []
        for x_pos in sorted({support["x"] for support in support_rows}):
            reaction = beam.get_reaction(x_pos)
            if reaction is None:
                continue
            reactions_data.append([
                {"type": "Double", "basicValue": float(x_pos)},
                {"type": "Double", "basicValue": float(reaction[0])},
                {"type": "Double", "basicValue": float(reaction[1])},
                {"type": "Double", "basicValue": float(reaction[2])}
            ])

        internal_data = []
        step = span / 2.0
        for i in range(3):
            x_query = i * step
            v_val = float(beam.get_shear_force(x_query))
            m_val = float(beam.get_bending_moment(x_query))
            d_val = float(beam.get_deflection(x_query))
            internal_data.append([
                {"type": "Double", "basicValue": float(x_query)},
                {"type": "Double", "basicValue": v_val},
                {"type": "Double", "basicValue": m_val},
                {"type": "Double", "basicValue": d_val}
            ])

        return {
            "type": "Double",
            "basicValue": span,
            "properties": {
                "React": {
                    "type": "Array",
                    "elements": [
                        [{"type": "String", "basicValue": "Pos"}, {"type": "String", "basicValue": "Rx"}, {"type": "String", "basicValue": "Ry"}, {"type": "String", "basicValue": "Rm"}]
                    ] + reactions_data
                },
                "Forces": {
                    "type": "Array",
                    "elements": [
                        [{"type": "String", "basicValue": "Pos"}, {"type": "String", "basicValue": "V"}, {"type": "String", "basicValue": "M"}, {"type": "String", "basicValue": "v"}]
                    ] + internal_data
                }
            }
        }
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Total length of the beam (m).
2D array of support definitions [[x, rx, ry, rm, ...]]. x: position (m). rx, ry, rm: 1 for fixed, 0 for free (or stiffness value for spring).
2D array of load definitions [[type, val1, val2, x1, x2]]. type: "point", "moment", "udl", "trap". val1: force/moment value (N or N/m). val2: ending force for trapezoidal (N/m). x1, x2: start/end positions (m).
Young's Modulus (Pa).
Second moment of area (m4).
Cross-sectional area (m2).

BEAM_DEFLECTION

Calculates the vertical deflection of a structural beam at a given point x along its span. The function assembles the beam, applies the supplied supports and loads, solves the beam, and then evaluates the deflection curve at the requested coordinate.

In Euler-Bernoulli beam theory, deflection is the displacement field produced by bending. The governing relationship is

E I \frac{d^4 v}{dx^4} = w(x)

where E is Young’s modulus, I is the second moment of area, v(x) is the beam deflection, and w(x) is the applied load distribution. Positive results indicate upward deflection, and negative results indicate downward deflection.

Excel Usage

=BEAM_DEFLECTION(span, supports, loads, query_x, e_modulus, second_moment)
  • span (float, required): Total length of the beam (m).
  • supports (list[list], required): 2D array of support definitions [[x, rx, ry, rm]].
  • loads (list[list], required): 2D array of load definitions [[type, val1, val2, x1, x2]].
  • query_x (float, required): The x-coordinate at which to evaluate deflection (m).
  • e_modulus (float, optional, default: 200000000000): Young’s Modulus (Pa).
  • second_moment (float, optional, default: 0.00000905): Second moment of area (m4).

Returns (float): Vertical deflection (m) at the specified coordinate.

Example 1: Midspan deflection of simply supported beam

Inputs:

span supports loads query_x
10 0 0 1 0 point -1000 0 5 0 5
10 0 1 0

Excel formula:

=BEAM_DEFLECTION(10, {0,0,1,0;10,0,1,0}, {"point",-1000,0,5,0}, 5)

Expected output:

-0.0115101

Example 2: Tip deflection of cantilever

Inputs:

span supports loads query_x
5 0 1 1 1 udl -100 0 0 5 5

Excel formula:

=BEAM_DEFLECTION(5, {0,1,1,1}, {"udl",-100,0,0,5}, 5)

Expected output:

-0.0043163

Example 3: Deflection at point between supports

Inputs:

span supports loads query_x
8 0 0 1 0 point -500 0 4 0 2
8 0 1 0

Excel formula:

=BEAM_DEFLECTION(8, {0,0,1,0;8,0,1,0}, {"point",-500,0,4,0}, 2)

Expected output:

-0.00202578

Example 4: Zero deflection at support

Inputs:

span supports loads query_x
6 0 0 1 0 point -100 0 3 0 0
6 0 1 0

Excel formula:

=BEAM_DEFLECTION(6, {0,0,1,0;6,0,1,0}, {"point",-100,0,3,0}, 0)

Expected output:

0

Python Code

Show Code
from indeterminatebeam import Beam, Support
from indeterminatebeam.loading import PointLoadV, PointLoadH, PointTorque, UDLV, TrapezoidalLoadV

def beam_deflection(span, supports, loads, query_x, e_modulus=200000000000, second_moment=9.05e-06):
    """
    Calculate the deflection of a beam at a specific coordinate.

    See: https://indeterminatebeam.readthedocs.io/en/main/docstrings.html#indeterminatebeam.Beam.get_deflection

    This example function is provided as-is without any representation of accuracy.

    Args:
        span (float): Total length of the beam (m).
        supports (list[list]): 2D array of support definitions [[x, rx, ry, rm]].
        loads (list[list]): 2D array of load definitions [[type, val1, val2, x1, x2]].
        query_x (float): The x-coordinate at which to evaluate deflection (m).
        e_modulus (float, optional): Young's Modulus (Pa). Default is 200000000000.
        second_moment (float, optional): Second moment of area (m4). Default is 9.05e-06.

    Returns:
        float: Vertical deflection (m) at the specified coordinate.
    """
    try:
      def to2d(value):
        return [[value]] if not isinstance(value, list) else value

      supports = to2d(supports)
      loads = to2d(loads)

      if not isinstance(supports, list) or not all(isinstance(row, list) for row in supports):
        return "Error: Invalid input - supports must be a 2D list"
      if not isinstance(loads, list) or not all(isinstance(row, list) for row in loads):
        return "Error: Invalid input - loads must be a 2D list"

      beam = Beam(span=span, E=e_modulus, I=second_moment)

      support_rows = []
      has_x_restraint = False
      for row in supports:
        if len(row) < 4:
          continue
        try:
          x_pos = float(row[0])
          rx_raw = float(row[1])
          ry_raw = float(row[2])
          rm_raw = float(row[3])
        except (TypeError, ValueError):
          continue

        kx = rx_raw if rx_raw > 1 else None
        ky = ry_raw if ry_raw > 1 else None
        rx_fixed = int(bool(rx_raw)) if kx is None else 0
        ry_fixed = int(bool(ry_raw)) if ky is None else 0
        rm_fixed = int(bool(rm_raw))

        if rx_fixed == 1 or (kx is not None and kx > 0):
          has_x_restraint = True

        support_rows.append({
          "x": x_pos,
          "fixed": (rx_fixed, ry_fixed, rm_fixed),
          "kx": kx,
          "ky": ky,
        })

      if not support_rows:
        return "Error: At least one valid support is required"

      if not has_x_restraint:
        support_rows[0]["fixed"] = (1, support_rows[0]["fixed"][1], support_rows[0]["fixed"][2])
        support_rows[0]["kx"] = None

      for support in support_rows:
        beam.add_supports(Support(support["x"], fixed=support["fixed"], kx=support["kx"], ky=support["ky"]))

      for row in loads:
        if len(row) < 2:
          continue
        l_type = str(row[0]).lower()
        try:
          val1 = float(row[1])
          val2 = float(row[2]) if len(row) > 2 else 0.0
          x1 = float(row[3]) if len(row) > 3 else 0.0
          x2 = float(row[4]) if len(row) > 4 else 0.0
        except (TypeError, ValueError):
          continue

        if l_type == "point":
          beam.add_loads(PointLoadV(val1, x1))
        elif l_type == "moment":
          beam.add_loads(PointTorque(val1, x1))
        elif l_type == "udl":
          beam.add_loads(UDLV(val1, (x1, x2)))
        elif l_type == "trap":
          beam.add_loads(TrapezoidalLoadV((val1, val2), (x1, x2)))
        elif l_type == "point_h":
          beam.add_loads(PointLoadH(val1, x1))

      beam.analyse()

      return float(beam.get_deflection(query_x))
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Total length of the beam (m).
2D array of support definitions [[x, rx, ry, rm]].
2D array of load definitions [[type, val1, val2, x1, x2]].
The x-coordinate at which to evaluate deflection (m).
Young's Modulus (Pa).
Second moment of area (m4).

BEAM_REACTION

Calculates a specific reaction component (horizontal force, vertical force, or bending moment) at a support location for a given beam configuration. This function is ideal for extracting specific results from a beam analysis directly into an Excel cell.

The function builds a numerical model of the beam internally, calculates all reactions, and returns the requested component at the specified coordinate.

Excel Usage

=BEAM_REACTION(span, supports, loads, query_x, beam_react_dir)
  • span (float, required): Total length of the beam (m).
  • supports (list[list], required): 2D array of support definitions [[x, rx, ry, rm]].
  • loads (list[list], required): 2D array of load definitions [[type, val1, val2, x1, x2]].
  • query_x (float, required): The x-coordinate of the support to query (m).
  • beam_react_dir (str, required): The reaction component to return (‘x’, ‘y’, or ‘m’).

Returns (float): The reaction force (N) or moment (N.m) at the specified position and direction.

Example 1: Left reaction of simple beam

Inputs:

span supports loads query_x beam_react_dir
6 0 0 1 0 point -600 0 2 0 0 y
6 0 1 0

Excel formula:

=BEAM_REACTION(6, {0,0,1,0;6,0,1,0}, {"point",-600,0,2,0}, 0, "y")

Expected output:

400

Example 2: Right reaction of simple beam

Inputs:

span supports loads query_x beam_react_dir
6 0 0 1 0 point -600 0 2 0 6 y
6 0 1 0

Excel formula:

=BEAM_REACTION(6, {0,0,1,0;6,0,1,0}, {"point",-600,0,2,0}, 6, "y")

Expected output:

200

Example 3: Fixed end moment of cantilever

Inputs:

span supports loads query_x beam_react_dir
4 0 1 1 1 point -100 0 4 0 0 m

Excel formula:

=BEAM_REACTION(4, {0,1,1,1}, {"point",-100,0,4,0}, 0, "m")

Expected output:

400

Example 4: Interior support reaction (propped cantilever)

Inputs:

span supports loads query_x beam_react_dir
10 0 1 1 1 udl -10 0 0 10 10 y
10 0 1 0

Excel formula:

=BEAM_REACTION(10, {0,1,1,1;10,0,1,0}, {"udl",-10,0,0,10}, 10, "y")

Expected output:

37.5

Python Code

Show Code
from indeterminatebeam import Beam, Support
from indeterminatebeam.loading import PointLoadV, PointLoadH, PointTorque, UDLV, TrapezoidalLoadV

def beam_reaction(span, supports, loads, query_x, beam_react_dir):
    """
    Calculate the reaction force or moment at a specific support position.

    See: https://indeterminatebeam.readthedocs.io/en/main/docstrings.html#indeterminatebeam.Beam.get_reaction

    This example function is provided as-is without any representation of accuracy.

    Args:
        span (float): Total length of the beam (m).
        supports (list[list]): 2D array of support definitions [[x, rx, ry, rm]].
        loads (list[list]): 2D array of load definitions [[type, val1, val2, x1, x2]].
        query_x (float): The x-coordinate of the support to query (m).
        beam_react_dir (str): The reaction component to return ('x', 'y', or 'm'). Valid options: Horizontal Force (x), Vertical Force (y), Bending Moment (m).

    Returns:
        float: The reaction force (N) or moment (N.m) at the specified position and direction.
    """
    try:
      def to2d(value):
        return [[value]] if not isinstance(value, list) else value

      supports = to2d(supports)
      loads = to2d(loads)

      if not isinstance(supports, list) or not all(isinstance(row, list) for row in supports):
        return "Error: Invalid input - supports must be a 2D list"
      if not isinstance(loads, list) or not all(isinstance(row, list) for row in loads):
        return "Error: Invalid input - loads must be a 2D list"

      direction = str(beam_react_dir).lower()
      if direction not in {"x", "y", "m"}:
        return "Error: beam_react_dir must be one of 'x', 'y', or 'm'"

      beam = Beam(span=span)

      support_positions = []
      support_rows = []
      has_x_restraint = False
      for row in supports:
        if len(row) < 4:
          continue
        try:
          x_pos = float(row[0])
          rx_raw = float(row[1])
          ry_raw = float(row[2])
          rm_raw = float(row[3])
        except (TypeError, ValueError):
          continue

        kx = rx_raw if rx_raw > 1 else None
        ky = ry_raw if ry_raw > 1 else None
        rx_fixed = int(bool(rx_raw)) if kx is None else 0
        ry_fixed = int(bool(ry_raw)) if ky is None else 0
        rm_fixed = int(bool(rm_raw))

        if rx_fixed == 1 or (kx is not None and kx > 0):
          has_x_restraint = True

        support_rows.append({
          "x": x_pos,
          "fixed": (rx_fixed, ry_fixed, rm_fixed),
          "kx": kx,
          "ky": ky,
        })
        support_positions.append(x_pos)

      if not support_rows:
        return "Error: At least one valid support is required"

      if not has_x_restraint:
        support_rows[0]["fixed"] = (1, support_rows[0]["fixed"][1], support_rows[0]["fixed"][2])
        support_rows[0]["kx"] = None

      for support in support_rows:
        beam.add_supports(Support(support["x"], fixed=support["fixed"], kx=support["kx"], ky=support["ky"]))

      for row in loads:
        if len(row) < 2:
          continue
        l_type = str(row[0]).lower()
        try:
          val1 = float(row[1])
          val2 = float(row[2]) if len(row) > 2 else 0.0
          x1 = float(row[3]) if len(row) > 3 else 0.0
          x2 = float(row[4]) if len(row) > 4 else 0.0
        except (TypeError, ValueError):
          continue

        if l_type == "point":
          beam.add_loads(PointLoadV(val1, x1))
        elif l_type == "moment":
          beam.add_loads(PointTorque(val1, x1))
        elif l_type == "udl":
          beam.add_loads(UDLV(val1, (x1, x2)))
        elif l_type == "trap":
          beam.add_loads(TrapezoidalLoadV((val1, val2), (x1, x2)))
        elif l_type == "point_h":
          beam.add_loads(PointLoadH(val1, x1))

      beam.analyse()

      reaction = beam.get_reaction(query_x, direction)
      if reaction is not None:
        return float(reaction)

      for x_pos in support_positions:
        if abs(x_pos - query_x) < 1e-6:
          reaction = beam.get_reaction(x_pos, direction)
          if reaction is not None:
            return float(reaction)

      return f"Error: No support found at x={query_x}"
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Total length of the beam (m).
2D array of support definitions [[x, rx, ry, rm]].
2D array of load definitions [[type, val1, val2, x1, x2]].
The x-coordinate of the support to query (m).
The reaction component to return ('x', 'y', or 'm').