SutranetTower — User Manual

A beginner-friendly guide to designing and analysing lattice communication towers — either 3-leg equilateral-triangular or 4-leg square cross-section — using SutranetTower, the tower engineering analysis app by Sutranet, live at www.sutranet.co.in. Covers IS 875 Part 3 wind loading, a full 3D finite-element solve, and IS 17740 / IS 800 member capacity checks.

IS 875 Part 3:2015 IS 17740:2022 IS 800:2007 3-leg & 4-leg OpenSeesPy 3D FEM

1.Introduction

SutranetTower is a web application by Sutranet for designing lattice telecom towers — either a 3-leg (equilateral-triangular) or 4-leg (square) cross-section, selected under Tower Type. You describe the tower’s geometry, member sizes, bracing, wind environment and antenna loads in a structured form (or as a JSON file), and the app:

  1. Computes wind loads on every section per IS 875 Part 3:2015.
  2. Builds the real 3D lattice (legs, diagonals, horizontals) and solves it with OpenSeesPy, a finite-element engine.
  3. Checks every member against tension and compression (buckling) capacity per IS 17740:2022 / IS 800:2007.
  4. Produces a single self-contained HTML report you can open, share, or archive — and, optionally, a STAAD.Pro .std file for independent cross-checking.
Who this is for Structural/telecom engineers checking tower adequacy, or anyone needing a fast first-pass design and utilisation check before detailed STAAD/manual design. This manual assumes no prior familiarity with the tool, but does assume basic familiarity with tower/lattice structural terminology.

2.Key Concepts

Slope

A tapering segment of the tower defined by its bottom_width, top_width and height. A tower is built from one or more stacked slopes, bottom to top.

Section

A sub-division within a slope with its own height, panel count, bracing pattern and member sizes (section_id e.g. S1, S2…). This is the level at which you assign leg/diagonal/horizontal pipe or angle sections.

Panel

The smallest repeating bracing unit inside a section, set by num_panels. Each panel gets the section’s bracing pattern repeated on every face by rotational symmetry (120° on a 3-leg tower, 90° on a 4-leg tower).

Tower type

Set under Tower Type: 3-leg (equilateral triangle, 3 faces) or 4-leg (square, 4 faces). This drives the leg/face geometry, the wind-load tables (IS 875 Table 33/34/35) and the antenna/ladder mount indices.

Face / Leg / Diagonal / Horizontal

Each face has 2 inclined legs (corner chords) shared with its neighbour, diagonal bracing members, and optional horizontals at panel breaks. Even-leg (4-leg) towers can also carry plan bracing across the ring for torsional rigidity.

3.Quick Start

  1. Open the app at www.sutranet.co.in. Click Load Example to start from a working 40 m tower instead of a blank one.
  2. In the Tower Builder tab, walk the left-hand tree: click Wind to set basic wind speed and terrain; click each Slope / Section to set geometry, bracing and member sizes.
  3. (Optional) Click the ✦ Review Inputs button to get an automated sanity check before you spend time waiting on the solve.
  4. Click Run Analysis. The app polls progress every 1.5 s until the job finishes (typically seconds to low minutes, hard-capped at 180 s — see Limitations).
  5. Review the report in the Result tab: start with Summary for the headline max utilisation and drift, then drill into Capacity and Lattice Forces for any overstressed members.
  6. Use Export JSON to save your tower definition, and (optionally) download the STAAD .std file for an independent cross-check.

4.Wind Input

Wind loading follows IS 875 Part 3:2015. The design wind speed at any height is:

Vz = Vb × k1 × k2 × k3 × k4
pz = 0.6 × Vz²   (design wind pressure, N/m²)
FieldMeaningDefaultNotes
basic_wind_speed_ms (Vb)Basic wind speed at 10 m, flat open terrain39.0 m/sUse your site’s code-mapped value
terrain_category1 = open sea, 2 = open/scattered obstructions, 3 = dense obstructions/suburbs, 4 = dense urban / large city centres2Drives k2 height-profile interpolation
k1Risk coefficient (probability factor, Table 1)1.0Typically 0.82–1.05 depending on design life/return period
k3Topography factor (Appendix C)1.0Up to ~1.36 on hills/cliffs/escarpments
k4Importance factor for cyclonic regions (Table 3)1.01.0 outside cyclone-prone coastal belts
gust_factorGust effectiveness factor GautoIf omitted, computed from IS 875 Appendix B turbulence intensity, peak factor ≈3.5
direction_degList of wind azimuths analysed3-leg: 0–330° in 30° steps (12 pts); 4-leg: 0/15/30/45° octant0° aligns with model +Y, 90° with +X. The 4-leg octant relies on square symmetry — it auto-expands to the full 0–345° rose when antennas/a ladder make the loading asymmetric

Wind speed lookup by location

Click the map/lat-lon field in the Wind panel to auto-fill basic wind speed from data/windmap.geojson and nearest-coast distance from data/coastline.geojson.

Coverage limit The location lookup only works inside the Indian subcontinent (lat −10…40, lon 60…100). Outside this box, enter basic_wind_speed_ms and terrain_category manually.

How force coefficients are applied

The Cf table used depends on both the member shape and the tower type (IS 875 Cl. 7.4.3.5):

  • Flat-sided (angle) members use Table 33: Cf depends on solidity ratio φ. On a 3-leg tower it is constant for all wind directions; on a 4-leg (square) tower the face→corner increase (Cl. 7.4.3.5(b), 1.0→1.2×) is interpolated linearly by wind angle.
  • Round (pipe) members use Table 35 on a 3-leg tower and Table 34 (face vs. corner Cf) on a 4-leg tower. Cf depends on solidity ratio φ and flow regime, set by D×Vz (DVd): below 6 m²/s the flow is subcritical (higher Cf, ~1.3–1.8); at/above 6 m²/s it is supercritical (lower Cf, ~0.8–1.2).
  • Solidity ratio φ is computed per section from the actual projected member areas vs. the gross panel face area — you don’t set φ directly, it falls out of your member sizing.

5.Slopes & Sections

Build the tower top-down or bottom-up in the tree: add Slopes for each taper change, then one or more Sections inside each slope.

FieldLevelMeaning
bottom_width / top_widthSlopeFace width (m) at the bottom/top of that slope
heightSlope / SectionVertical extent (m)
section_idSectionUnique label, e.g. S1
num_panelsSectionNumber of bracing panels stacked in this section (≥ 1)
panel_heightSectionPer-panel height; must equal height / num_panels
bracingSectionPattern name/alias — see Bracing Patterns
Heights must be consistent The geometry is cross-checked before the solve and the run is rejected with a clear error if either of these fails:
  • The sum of a slope’s section heights must equal that slope’s height (the slope height is the width-interpolation reference; a mismatch would silently build a taller/shorter tower).
  • Each section’s num_panels × panel_height must equal its height (a mismatch leaves a gap/overlap at the panel nodes). A ~1% tolerance absorbs rounded values like 3 × 1.6667 = 5.0001 m.
Modelling tip Use more, shorter sections near the base (highest forces, often heavier members) and fewer/taller sections near the top where forces are smaller. The 20-section cap applies across the whole tower — see Limitations.

6.Member Sections

Each section needs a leg_section, diagonal_section and (optionally) horizontal_section (horizontal), plus any redundant_sections needed by the chosen bracing pattern. Two section types are supported:

Pipe (circular hollow section)

FieldMeaning
odOuter diameter (mm)
thkWall thickness (mm)
gradeYield strength fy (MPa) — default 300 for legs, 250 for diagonals/horizontals

Angle (equal-leg, IS 808:2021)

FieldMeaning
designationFree text, e.g. ISA 65x65x6 or shorthand ISA 50x5
end_connectionsingle_bolt (default) or multi_bolt_or_weld — governs net-section rupture per IS 800 Cl. 6.3.3

Double angle

Same fields as Angle, plus gap_mm (back-to-back spacing, default 10 mm), which shifts the combined Iyy via the parallel-axis theorem.

Bolt holes & net section

Set n_bolt_holes and bolt_hole_dia_mm on any member to have its net-section tensile capacity (Tdn, IS 800 Cl. 6.3.1) reduced accordingly. fu (ultimate strength) is derived automatically from fy via the IS 2062 grade mapping (e.g. fy = 250 → fu = 410 MPa) — you do not set fu directly.

Connection design (optional)

Each section can carry a bolted-connection check, enabled by the Connection design toggle on that section in the Tower Builder. The spec is edited as a small raw-JSON block; leave a sub-key out to skip that connection. The checks are driven by the factored axial demand that the section’s members actually attract in the analysis (tension for the flange, axial magnitude for bracing), and every result appears in the report’s Connections tab. All checks use IS 800:2007 partial safety factors: γm0 = 1.10, γm1 = 1.25, γmb = 1.25 (bolts), γmw = 1.25 (shop weld).

Sub-keyApplies toBasis & checks
flangeLeg splice for a pipe (CHS) legRing-flange splice: bolt tension + prying (IS 800 §10.3.5 / §10.4.7), annular-plate flexural mechanism (EN 1993-1-8 §6.2.4 T-stub, Mode 1/2), and the shell-to-plate fillet weld (§10.5). Governing utilisation across the three.
leg_spliceLeg splice for an angle / double-angle legBolted lap / cover-plate splice in double shear (IS 800 §10.3). Use this or flange to match the leg type — not both.
diag_bracingDiagonals / horizontalsBolted shear connection: bolt shear (§10.3.3, incl. long-joint βlj), bolt bearing (§10.3.4), net-section rupture (§6.3) and block shear (§6.4.1). Governing utilisation across all.
redundant_bracingRedundant members, by tagBracing-shear spec, given either per tag as a {"r1": {…}, "r2": {…}} map keyed by the same tags as redundant_sections, or as one flat spec shared by every tag. A tag omitted from the map is left undetailed; a tag named in the map that the section does not define is an error, not a no-op.

Bolted shear connections — what each field measures

Applies to diag_bracing, horiz_bracing, redundant_bracing and leg_splice — they all share one field set. All dimensions are in millimetres, strengths in MPa.

Gusset / cleat plate Bracing member end d_hole = d_bolt + clearance end_dist pitch edge the member is pulled away from edge_dist width_gross N (factored axial) A A
Plan view. end_dist is measured along the line of force to the edge the bolt bears toward; edge_dist is transverse to it. n_bolts_line counts the bolts in the line of force (2 here), and pitch is the spacing between them — leave pitch at 0 for a single bolt.
Section A–A cover plate member cover plate d_bolt shear plane 1 shear plane 2 t_ply cover plates react N/2 each N
Section through the bolt. The sandwiched detail shown crosses two shear planes, so n_shear_planes = 2. A single lap (member to one plate) crosses one, so n_shear_planes = 1 — that halves the bolt shear capacity, and it is the usual detail for redundants. t_ply is the governing thickness in bearing: the thinner of the member and the sum of the plates on one side.
FieldMeaningNotes
d_boltNominal bolt diameterDrives shear area and bearing.
d_holeHole diameterBolt + clearance (typ. +2 mm to M24). Sets net section and the Cl. 10.2.4.2 minimum distances.
fub_boltBolt ultimate strength800 for grade 8.8, 400 for 4.6.
n_shear_planesShear planes crossedDefaults to 2. Set 1 for a single lap — the usual redundant detail.
threads_in_planeThreads in the shear plane?Default true (uses the 0.78 net area). false uses the shank.
t_ply, fy_plyGoverning ply thickness & yieldfu is derived from fy by the IS 2062 grade map.
width_grossGross width of the connected elementNet section = (width_grossd_hole) × t_ply. Omit (0) to skip the rupture check.
end_dist, edge_distEnd and edge distancesSee the figure. end_dist also enters the bearing kb; leaving it at 0 overstates bearing capacity.
edge_typeHow the edge was cutRequired, no default — see Detailing below.
pitch, n_bolts_lineSpacing and count in the line of forceLong joints (> 15·d) get the Cl. 10.3.3.1 βlj reduction automatically.
bearing_creditleg_splice onlytrue halves the compressive demand per IS 800 §10.8 full-contact bearing. A documented simplification — confirm against your adopted reading.

Ring-flange leg splice — what each field measures

Applies to flange, used when the leg is a pipe (CHS).

Plan pcd / 2 n_bolts plate_od leg pipe OD (from the leg section) Section weld_throat leg pipe d_bolt plate_thickness m e m and e are derived — they drive prying
Plan and section. The bolt pitch circle pcd and plate outside diameter plate_od are diameters, not radii. The prying levers m (bolt axis to shell wall, less 0.8√2·weld_throat) and e (bolt axis to plate edge) are computed from them — a large pcd relative to the pipe means a long lever and a high prying force.
FieldMeaningNotes
n_boltsBolts on the pitch circleAssumed equally spaced.
d_boltNominal bolt diameter
pcdBolt pitch-circle diameterMust clear the pipe OD; sets the prying lever m.
plate_thicknessFlange plate thicknessDrives the plate flexural mechanism — the usual governing mode.
plate_odPlate outside diameterSets the edge lever e.
plate_fyPlate yieldfu derived from fy.
fub_bolt, fyb_boltBolt grade800 / 640 for 8.8.
weld_throatFillet weld effective throatShell to plate. 0 means full-penetration — the weld check is then skipped, not failed.
pretensionedBolts pretensioned?Sets β in Cl. 10.4.7 prying (1 if true, else 2). Default false.

Detailing (IS 800 §10.2). Every bolted-shear spec is also checked against the spacing limits the capacity equations assume: minimum end and edge distance (Cl. 10.2.4.2), maximum edge distance 12·t·ε (Cl. 10.2.4.3), and minimum pitch 2.5·d (Cl. 10.2.2). The minimum end/edge distance depends on how the edge was prepared, so edge_type is required and has no default — "sheared" / "hand_flame_cut" give 1.7× the hole diameter, "rolled" / "machine_flame_cut" / "sawn" / "planed" give 1.5×. Omitting it reports the distance as unchecked rather than assuming a factor; an unrecognised value is an error. A detailing violation fails the connection but does not appear in its utilisation ratio, which stays a pure strength figure. Note the Cl. 10.2.3.1 maximum pitch and the corrosive-exposure edge cap are not checked.

edge_typeEdge preparationMin. end & edge distanceM16 (d0=18)M20 (d0=22)M24 (d0=26)
"sheared"
"hand_flame_cut"
Sheared or hand-flame cut1.7 × hole dia30.6 mm37.4 mm44.2 mm
"rolled"
"machine_flame_cut"
"sawn" / "planed"
Rolled, machine-flame cut, sawn or planed1.5 × hole dia27.0 mm33.0 mm39.0 mm
edge_type has no default — on purpose Assuming 1.5× on a sheared edge would pass a connection IS 800 rejects; assuming 1.7× on a rolled edge would fail a compliant one. Neither guess is safe, so a spec that gives distances without edge_type reports them as unchecked rather than resolving either way, and a misspelt value is an error rather than a fallback.

JSON schema

The connections object sits on a section, alongside leg_section / diagonal_section / redundant_sections. Every sub-key is optional — omit one to skip that connection entirely. Notation below: (required) means the analysis raises if the key is absent; = value is the default applied when it is.

"connections": {                    // optional, per section

  "flange": {                      // leg splice — PIPE (CHS) leg only
    "n_bolts":          integer (required)   // bolts on the pitch circle
    "d_bolt":           number  (required)   // mm
    "pcd":              number  (required)   // mm, bolt pitch-circle DIAMETER
    "plate_thickness":  number  (required)   // mm
    "plate_od":         number  (required)   // mm, plate outside DIAMETER
    "plate_fy":         number  = 250        // MPa
    "plate_fu":         number  = from plate_fy
    "fub_bolt":         number  = 800        // MPa (grade 8.8)
    "fyb_bolt":         number  = 640        // MPa
    "pretensioned":     boolean = false      // sets β in Cl. 10.4.7 prying
    "weld_throat":      number  = 0          // mm; 0 ⇒ full pen, weld check SKIPPED
    "fu_weld":          number  = 410        // MPa
    "fu_pipe":          number  = from the leg grade
  },                                          // pipe OD/thk/fy come from leg_section

  "leg_splice": {                  // leg splice — ANGLE / DOUBLE-ANGLE leg only
    // …all the bolted-shear fields below, plus:
    "bearing_credit":   boolean = false      // true ⇒ halve compressive demand (§10.8)
    "t_ply":            number  = 8.0        // NOTE: 6.4 for the bracing blocks
  },

  "diag_bracing":  { …bolted-shear fields… },   // diagonals
  "horiz_bracing": { …bolted-shear fields… },   // horizontals

  "redundant_bracing":                 // EITHER one shared spec…
      { …bolted-shear fields… }
    // …OR one spec per redundant tag, keyed as in "redundant_sections":
    { "r1": { …fields… }, "r2": { …fields… } }
}

// ── bolted-shear fields (diag_bracing, horiz_bracing,
//    redundant_bracing and leg_splice all share these) ──
    "d_bolt":           number  (required)   // mm
    "d_hole":           number  (required)   // mm, = d_bolt + clearance
    "edge_type":        string  (required if end_dist/edge_dist given)
                                             // "sheared" | "hand_flame_cut"
                                             // "rolled" | "machine_flame_cut" | "sawn" | "planed"
    "fub_bolt":         number  = 800        // MPa
    "n_shear_planes":   integer = 2          // 1 = single lap ← usual for redundants
    "threads_in_plane": boolean = true       // false ⇒ shank area, not 0.78·A
    "t_ply":            number  = 6.4        // mm, governing thickness in bearing
    "fy_ply":           number  = 250        // MPa
    "fu_ply":           number  = from fy_ply
    "width_gross":      number  = 0          // mm; 0 ⇒ net-section check SKIPPED
    "end_dist":         number  = 0          // mm; 0 ⇒ inflates bearing k_b
    "edge_dist":        number  = 0          // mm
    "pitch":            number  = 0          // mm, between bolts in line of force
    "n_bolts_line":     integer = 1          // bolts in the line of force

fu is never set directly — it is derived from fy through the IS 2062 grade map (250→410, 300→440, 310→450, 350→490 MPa; anything else → 410).

Two defaults that quietly weaken the check n_shear_planes defaults to 2, so a single-lap redundant left unset is credited with double the bolt shear it has. And end_dist defaults to 0, which drops the e/(3d0) term from the bearing kb and overstates bearing capacity — the §10.2 detailing check reports that one, but set the distance rather than relying on the report to catch it. width_gross and weld_throat at 0 skip their checks entirely, which is intended but worth knowing.
Unrecognised keys are ignored, not rejected A misspelt sub-key or field is currently silently dropped — writing "redundent" instead of "redundant_bracing" produces a report with no redundant connection results at all and no warning anywhere. Copy the names from this schema; if a connection you configured is missing from the report’s Connections tab, a misspelt key is the first thing to check.

A complete example

An angle-leg section with per-tag redundant detailing — r1 on M16 and the more heavily loaded r2 on M20:

"connections": {
  "leg_splice": {
    "d_bolt": 20.0, "d_hole": 22.0, "fub_bolt": 800.0,
    "n_shear_planes": 2,            // cover plate each side of the angle
    "t_ply": 8.0, "fy_ply": 250.0, "width_gross": 70.0,
    "end_dist": 40.0, "edge_dist": 38.0, "edge_type": "sheared",
    "pitch": 60.0, "n_bolts_line": 2,
    "bearing_credit": true          // IS 800 §10.8 full-contact bearing
  },
  "diag_bracing": {
    "d_bolt": 20.0, "d_hole": 22.0, "fub_bolt": 800.0,
    "n_shear_planes": 1,            // single lap onto the gusset
    "t_ply": 8.0, "fy_ply": 250.0, "width_gross": 70.0,
    "end_dist": 40.0, "edge_dist": 38.0, "edge_type": "sheared"
  },
  "redundant_bracing": {            // keys match "redundant_sections"
    "r1": {
      "d_bolt": 16.0, "d_hole": 18.0, "fub_bolt": 800.0, "n_shear_planes": 1,
      "t_ply": 6.0, "fy_ply": 250.0, "width_gross": 50.0,
      "end_dist": 32.0, "edge_dist": 32.0, "edge_type": "sheared"
    },
    "r2": {
      "d_bolt": 20.0, "d_hole": 22.0, "fub_bolt": 800.0, "n_shear_planes": 1,
      "t_ply": 8.0, "fy_ply": 250.0, "width_gross": 70.0,
      "end_dist": 45.0, "edge_dist": 38.0, "edge_type": "sheared"
    }
  }
}

The // comments are for this manual only — strip them, JSON has no comments. A single flat spec is still accepted in place of the {"r1": …, "r2": …} map when every redundant tag shares one detail. Swap leg_splice for flange if the leg is a pipe.

Scaffold-grade — requires engineering sign-off The connection module is an implementation scaffold, not a validated calculation. In particular the ring-flange plate mechanism borrows the EN 1993-1-8 T-stub Mode 1/2 coefficients applied per single bolt around the circle — these are not validated against a ring-flange-specific model (e.g. Schmidt–Neuper / Petersen segment method). Every formula, coefficient and clause reference must be checked against your own copy of IS 800:2007 / EN 1993-1-8, and the flange numbers cross-checked against a dedicated model, before any production use. The responsible engineer owns the result.

7.Bracing Patterns

Pick a bracing pattern per section from the dropdown (built from the editable bracings.json library). Every face automatically receives the same pattern by rotational symmetry (120° on a 3-leg tower, 90° on a 4-leg tower). Each pattern declares which leg counts it is valid for (applicable_legs) — the dropdown only offers patterns valid for the current Tower Type, and picking an incompatible one is rejected at run time with a clear error.

The shipped library is a deliberately small starter set of four standard patterns. Anything beyond these is user-defined: create your own in the Bracing Library editor and they are saved to your private library (they never modify the shipped set).

PatternAliasesLegsDescription
single1, warren, pratt3, 4Single diagonal per face, with a horizontal ring at each panel top (Warren / Pratt). The simplest usable pattern.
cross2, x, xx3, 4X-bracing (two crossing diagonals), unsplit at the crossover. No horizontal ring — the diagonals are the only load path (use single if you want a ring at each panel top).
k_bracek, 53, 4Two half-diagonals rise from the bottom corners to a node at mid-span of the top horizontal ring, which is split at that node. The ring holds the apex in-plane, so it is not a mechanism.
x_plan44The 4-leg workhorse: X split at the crossover, plus opposite-face plan bracing through the crossover node (face_offset = 2). Gives the square ring torsional rigidity and shortens the diagonals’ out-of-plane buckling length (Annex F F-1). Needs a plan1 entry in the section’s redundant_sections (or auto_size).

Plan bracing (4-leg towers)

A triangular ring is inherently rigid, but a square ring is not — so even-leg (4-leg) towers often need plan bracing: horizontal diagonals across the ring that provide torsional/plan rigidity and also shorten the out-of-plane buckling length of crossover X-braces. In the library editor these appear as Plan Bracing (opposite-face links) alongside the legacy Hip Members (adjacent-face links); both are saved into each pattern’s redundant_links.

The Bracing Library editor

The Bracing Library tab is a single unified 3D editor — you author directly on the live 3D lattice (it replaces the older 2D Face Canvas / Hip / Plan views and the read-only preview). You still design one face — whatever you draw on the reference face is replicated to every other face automatically by rotational symmetry, so a pattern stays leg-count-agnostic. The tab has three regions plus two assistants:

  • Pattern list (left) — every pattern with a small 2D thumbnail; + New, Clone, Delete. The list is filtered to patterns valid for the current Tower Type.
  • 3D Pattern Editor (centre) — the interactive viewport: drag to rotate, scroll to zoom. Each face carries the fixed corner nodes bot_L, bot_R, top_L, top_R, and faces are labelled F0, F1…. You author by clicking one node then another: two nodes on the same face draw a same-face member; two nodes on different faces draw a cross-face (hip / plan) link with the face offset inferred automatically — there is no separate Hip/Plan mode. Click an existing member or cross-face line to split it with a node. A colour legend below the viewport keys diagonal / redundant / ring / cross-face / leg.
  • Editing & controls (right) — the context panels that appear for the current action (draw-member / add-node, member type & OPS element, cross-face link tag, rings and redundant-link lists), plus the two assistants below.
  • Pattern Health panel — four live checks (no duplicate members, all nodes connected, no bypassed nodes, all nodes have out-of-plane stiffness) that update as you edit. Fix reds before saving.
  • Guidance panel — a rule-based (or AI-backed, if an API key is configured) helper. Click Explain current errors or ask a free-text question about the pattern.

Anatomy of a pattern

A pattern is a small record (stored in bracings.json) built from these pieces:

PieceWhat it is
extra_nodesPoints you add on the face beyond the four corners. Most are placed at a fraction t (0–1) along a line between two existing nodes. A special x-intersect node is placed at the true geometric crossing of two lines (used for a real X crossover, e.g. the split X in x_plan4).
face_membersThe members drawn between two same-face nodes. Each has a typediagonal, horizontal, or redundant — which decides its section (leg/diagonal/horizontal/redundant) and its KL/r limit (150 / 200 / 250).
ops_elementThe finite-element formulation for that member: corotTruss (axial-only, geometrically nonlinear — the default for bracing), Truss (axial-only, linear), or elasticBeamColumn (full 6-DOF beam). Set per member.
redundant_linksCross-face links authored in 3D. A Hip joins nodes on adjacent faces (face_offset = ±1); Plan bracing joins opposite faces (face_offset = num_legs/2, 4-leg only). Each may carry a tag so you can give it its own section.
ringsA horizontal member auto-replicated all the way around the polygon at one node level (a full closed ring), authored by clicking the same node label on two adjacent faces in 3D.
cross_nodesA split point placed along a cross-face link (needs the two-face context to resolve). Only usable as a redundant-link endpoint — never as a same-face face_member endpoint.
name / aliases / descriptionIdentity. Aliases are alternate names the dropdown and JSON accept (e.g. xcross).
applicable_legsWhich tower types the pattern is valid for — a non-empty subset of {3, 4}. Set via the Applies to checkboxes.

Step-by-step: creating a custom pattern

  1. Open the Bracing Library tab. Start from an existing pattern close to what you want (select it, then edit) rather than a blank face — it’s faster and less error-prone.
  2. Set the Tower Type you’re targeting in the Tower Builder first, so the 3D editor shows the correct 3-leg or 4-leg lattice while you work.
  3. Place nodes. In the 3D viewport click two existing nodes on the same face; in the panel that appears, drag Position t and click Add Node to drop a node at that fraction along the line between them. For a true X crossing, click ✕ X-intersect Node and then click the four endpoints of the two crossing lines — the app computes their intersection.
  4. Draw members. Click one node, then another on the same face; choose Diagonal, Horizontal or Redundant. Click an existing member to change its Type, its OPS element, or (for redundants) its Tag, or to remove it.
  5. Split, don’t bypass. If a node sits partway along a member’s path, that member must be drawn as two segments meeting at the node — never as one member that runs past it (see Do’s & Don’ts). Click a member (or a cross-face line) to split it at a node.
  6. (4-leg / stiffening) Add cross-face links in the same viewport: click a node on one face, then a node on a different face — the editor makes a Hip (adjacent face) or Plan-bracing (opposite face) link and infers the face offset automatically. Give it a Tag and Save Link. For a full horizontal ring, click the same node label on two adjacent faces and choose + Horizontal ring. Use the F0, F1… face labels to pick the intended adjacent/opposite face deliberately.
  7. Watch the Pattern Health panel. Resolve every red item; use Explain current errors for a plain-language fix.
  8. Open Pattern Settings & Save: set Name, Aliases, Description, and tick the Applies to (3-leg / 4-leg) boxes. Click Save Pattern (local).
  9. Save to server (built-in library for admins, or my patterns for a private copy). The server re-validates with validate_bracing_pattern() and rejects anything invalid. This step is required before the pattern can be used in an analysis.
  10. Assign the pattern to a section in the Tower Builder, and give that section a redundant_section for each redundant Tag you used (or enable Auto-Size).

Do’s and Don’ts

✓ Do

  • Start from a working pattern and modify it incrementally.
  • Split every member at any node on its path (e.g. bot_L→mid + mid→top_R), so interior nodes are actually connected.
  • Author leg-splitting nodes directly on the leg corners — a node on a leg must be defined as a fraction of bot_L→top_L (or bot_R→top_R), so the lattice builder physically splits the leg there.
  • Give every diagonal/horizontal/redundant a section in the section that uses the pattern; use distinct Tags for redundants that need different sizes.
  • Add plan bracing on 4-leg towers whose face has an unbraced crossover — it supplies the plan/torsional rigidity a square ring lacks and shortens X-brace buckling lengths.
  • Clear the Pattern Health panel and Save to server before running an analysis.
  • Set applicable_legs honestly — only tick 4-leg if the geometry really works on a square face.

✗ Don’t

  • Don’t duplicate a member — two members on the same node pair (in either order) create a singular stiffness matrix.
  • Don’t leave a node floating — every extra_node must be an endpoint of at least one member, or it’s an unconstrained point.
  • Don’t let a member bypass an interior node on its path — the skipped node keeps an unconstrained out-of-plane DOF and the solve won’t converge.
  • Don’t define a leg node transitively (e.g. bot_L→5 where 5 is itself the leg midpoint) — the leg beam runs straight past it, leaving a mechanism the solver can’t stabilise.
  • Don’t reference a cross_node from a same-face member, and don’t chain cross_nodes — they only resolve as redundant-link endpoints.
  • Don’t reuse a redundant tag on two different links — they would silently share one cross-section assignment.
  • Don’t rely on a 4-leg X-brace being self-braced out-of-plane — a square face has no inherent plan rigidity; without plan bracing it can fail slenderness.
Why these rules exist Each “don’t” maps to a real failure mode the server’s validate_bracing_pattern() catches: a singular matrix, a floating node, or a zero-stiffness mechanism that makes the OpenSeesPy Newton–Raphson solve diverge. Fixing them at authoring time is far cheaper than debugging a non-converging run.
Restart / reload to take effect Patterns saved to the server are written to bracings.json and hot-reloaded in most deployments, but if a new or edited pattern doesn’t appear in the dropdown or the analysis still uses the old geometry, restart the server so it re-reads the file.

8.Antennas & Ladder/Cable Tray

Antennas

Add one or more antenna entries with an elevation_m, a type (panel / dish / generic), and one or more mounted instances (mount index, radial offset_m from the tower centreline, and azimuth_deg). Each instance contributes projected wind area, drag, dead weight and an associated torsional moment to the global load vector at its elevation.

Ladder / cable tray

Toggle this on to add a continuous vertical appurtenance, defined by effective drag area per metre (A_eff_m2_per_m), its location (outside_face, inside_face, or inside_axis), and the elevation range it covers.

Sanity check Keep antenna elevations and ladder elevation ranges inside the tower’s total height — the Review Inputs guidance flags antenna/ladder elevations that fall outside the modelled tower.

9.Analysis Config

The Config node sets the load-combination standard (IS 800:2007 Table 4 or IS 17740:2022 Table 2) and the redundant-member steel grade (IS 2062). When Auto-Size is enabled, a redundant with no explicit section is sized automatically (IS 1161 / IS 808); otherwise a section is required and the run errors rather than silently borrowing the diagonal size.

The element formulation for each diagonal and horizontal is defined per member in the Bracing Library — every pattern carries its own ops_element (choose corotTruss, Truss, or elasticBeamColumn on each member), so different sections can use different bracing behaviour. It is no longer a single tower-wide toggle in the Config node.

OptionWhat it modelsWhen to use
corotTruss (default)Axial-only, geometrically nonlinear (accounts for P–&Delta/rope-tension effects)Standard choice for diagonals/horizontals in lattice towers — matches typical industry pin-jointed bracing assumption
TrussAxial-only, geometrically linearMatches STAAD's MEMBER TRUSS exactly, when P–Δ is confirmed not required
elasticBeamColumnFull 6-DOF beam with bending/shear stiffnessUse if the member is rigidly/moment-connected, or to study added lateral stiffness from bending continuity

Legs always use elasticBeamColumn (they carry significant bending in addition to axial load and need full beam behaviour). For model-validation work, the per-member choice can be force-overridden from the CLI (not exposed in the UI):

python main.py tower.json --diag-type elasticBeamColumn --horizontal-type elasticBeamColumn --redundant-grade 350

Automatic planar-joint stabilization. Singular “planar-joint” nodes (for example an X/M crossover on a square 4-leg face with no plan bracing) have no out-of-plane stiffness when their bracing is axial-only truss, which would make the stiffness matrix singular. SutranetTower auto-stabilizes these joints — the offending truss bracing is promoted to elasticBeamColumn automatically (the PLS-TOWER / tnxTower approach), so the model stays solvable without manual edits. This is on by default; the analysis log lists exactly which joints were stabilized.

Dynamic wind, seismic & ice loads

Three additional IS 17740 load effects live under the Ice & Seismic Loads builder node. All three are opt-in and off by default — a plain tower report is unchanged unless you deliberately enable them.

EffectBasisWhen it engages
Gust-factor dynamic windIS 875 Pt 3:2015 Cl. 10.2 — along-wind gust factor G(z) on the hourly-mean pressureAutomatically when the first-mode frequency f₁ < 1.0 Hz (the IS 17740 Cl. 8.2 mandate), or on demand via wind.dynamic_method
SeismicIS 1893 Part 4 (via the IS 17740 Foreword) — Aₕ = (Z/2)(Sa/g)(I/R), storey forces Qᵢ ∝ Wᵢhᵢ²When the seismic block is enabled (zone, importance, response reduction, soil). Adds EQ-X / EQ-Y combinations
IceIS 17740 Cl. 7.2.4 — height-escalated ice thickness, added weight and projected-area sleeve with round-member CfWhen the ice block is enabled and design ice thickness > 0 (rare across most of India). Adds an ice + wind-on-ice combination

When enabled, the member-capacity check envelopes over all ultimate cases (wind + seismic + ice), and the report Summary tab gains dedicated dynamic / seismic / ice panels. A red banner also appears whenever f₁ < 1.0 Hz to flag that a dynamic gust-factor analysis is required.

10.Running the Analysis

  1. Click Run Analysis. The browser posts your tower JSON plus the analysis config to the server, which spawns the analysis as a background job and returns a job_id.
  2. The app polls job status every 1.5 s. Status moves through runningdone or error.
  3. On done, the generated HTML report loads automatically into the Result tab.
  4. On error, the status panel shows the parsed error summary (e.g. validation failure, timeout, or memory limit — see Troubleshooting).
Save your results Jobs are tracked only in server memory. If the server restarts, in-progress and completed jobs you haven’t exported are lost. Export the report or JSON you care about right away.

11.AI / Rule-Based Guidance

Two optional “✦” guidance buttons are available, both backed by Claude (claude-haiku-4-5) when an API key is configured on the server, and by a deterministic rule-based engine otherwise — you get useful feedback either way.

Bracing pattern guidance

While editing a custom bracing pattern, get instant feedback on duplicate members, floating nodes, and bypassed nodes, with suggested fixes.

Tower / results guidance

  • Before running (“Review Inputs”): flags widening-with-height geometry, panel heights below 1 m or above 6 m, very thin-walled members (D/t > 50), wind speeds outside a plausible 25–75 m/s range, and antenna/ladder elevations outside the tower height.
  • After running (“Explain Results”): flags max UC > 1.0 (overstressed) or > 0.9 (marginal), drift exceeding the IS 17740:2022 Cl. 10.1.2 limits (3% of height sway, 4° twist), KL/r above the per-role IS 17740 limits (legs/diagonals 150, horizontals 200, redundants 250), and identifies the governing wind direction, with suggested next steps (e.g. “increase OD×t of section S3 leg”).
Note Guidance is advisory, not a substitute for engineering judgement or a licensed checker’s sign-off. Treat it the way you would a junior engineer’s first-pass comments.

12.Reading the Report

TabWhat to look for
SummaryTower type & height, section count, max UC ratio, max tip drift vs the IS 17740:2022 Cl. 10.1.2(b) limit of 3% of height (plus 4° twist/sway rotation per Cl. 10.1.2(a)), direction envelope & governing member forces, and (if enabled) dynamic / seismic / ice panels
Geometry & Weights3D lattice view, per-section panel breakdown and member profiles/weights — confirm the model matches what you intended before trusting the numbers
Wind LoadPer-section z_mid, k2, Vz, pz, solidity φ, Cf for legs/diagonals/horizontals, DVd and flow regime, resulting wind force per direction
AntennasPer-antenna elevation, drag coefficient, projected area, and resulting wind force per direction (only shown if antennas were defined)
Nodal LoadsFactored nodal loads applied to the 3D lattice per IS 800 load combination
Lattice ForcesAxial (and, for beam elements, moment) member forces from the OpenSeesPy solve per load combination
DisplacementsNode displacements (mm) per load combination and the tip-drift envelope across all wind directions
CapacityUC ratio per member type per section per load combination (enveloped over all ULS cases), governing mode (tension/compression), KL/r, pass/fail
ConnectionsFlange splice (IS 800 + EN 1993-1-8) and bracing shear/bearing checks (IS 800 §10)
Support ReactionsBase node reactions (Rx, Ry, Rz, Mx, My, Mz) per load combination

The 3D viewer in the Geometry tab also has Deflected shape and Force colours toggles that redraw the real lattice at its displaced position (scaled) and colour members by force for the selected wind direction.

Utilisation ratio (UC)

UC = |Applied Force| / Governing Capacity
  • Tension: governing capacity = min(gross-section yield Tdg, net-section rupture Tdn if bolted)
  • Compression: governing capacity = Perry–Robertson buckling capacity per IS 800 Cl. 7.1, γm0 = 1.10, using buckling curve ‘a’ (α = 0.21) for CHS/pipe and curve ‘c’ (α = 0.49) for angle / double-angle sections (IS 800 Table 10). Bracing members additionally use the IS 17740 Annex F equivalent slenderness.

Tension and compression envelopes are tracked separately per member/section, so a larger tension force can never mask a smaller-but-governing compression case.

Pass/Fail

A member passes when UC ≤ 1.0 and its KL/r is within the per-role limit (IS 17740 Annex E-4 / Annex F Note 7: legs & diagonals 150, horizontals 200, redundants 250). Tip drift vs the IS 17740:2022 Cl. 10.1.2 limits (3% of height; 4° rotation) is a serviceability flag, not a strength criterion, but should not be ignored.

13.STAAD.Pro Export

Download a STAAD.Pro .std file rebuilt from your stored tower JSON, for independent cross-checking or detailed design continuation.

  • Coordinate system: Z-up; units: METER, KN, °C
  • All lattice nodes (legs, diagonals, extra/redundant nodes, antenna points) and members, mapped to MEMBER TRUSS (pin-ended, axial only) for corotTruss/Truss elements, or full BEAM elements (with section properties AX, IZ, IY, IX, AY, AZ) for elasticBeamColumn
  • Material: E = 200000 MPa, ν = 0.30, ρ = 7850 kg/m³
  • Load cases: LC1 dead load (self-weight + antenna & ladder dead weight), LC2 live/maintenance load (apex maintenance load plus the IS 17740 Cl. 7.2.2 ladder climber load where a ladder is defined), LC3+ wind per direction (including per-direction ladder wind); combinations per the selected standard (IS 800:2007 Table 4 or IS 17740:2022 Table 2)
Cross-check, don’t assume identical results Small differences between SutranetTower’s OpenSeesPy results and a STAAD re-run are expected — mainly from corotTruss (geometrically nonlinear) vs. STAAD’s linear truss elements under wind load. Differences should be small; large divergence is worth investigating before trusting either result.

14.Accounts & Quota

If the deployment has Firebase authentication configured, you’ll see a sign-in modal on first visit. Each account has a role (free or admin) and a monthly run quota that resets on the 1st of each month; your remaining quota is shown next to your email in the header. Admins can adjust other users’ quotas.

Ways to sign in

OptionHow it works
Continue with GoogleOne-click sign-in with a Google account — a Google popup opens, you pick your account, and you’re in. No password to set or remember. First Google sign-in creates your account automatically. (Shown only when the deployment’s Firebase project has Google sign-in enabled.)
Email & password — RegisterEnter an email and a password (minimum 6 characters), then re-type it in the Confirm password box. The SHOW toggle reveals what you typed so you can check it. Mismatched or too-short passwords are caught before the account is created.
Email & password — Sign InEnter the email and password you registered with.

Forgot your password?

On the Sign In tab, click Forgot password?, enter your account email, and click Send reset link. Firebase emails you a secure link to choose a new password — check your inbox (and spam folder). For privacy the app shows the same confirmation whether or not that email is registered, so the message appearing does not by itself confirm an account exists. Password recovery applies to email/password accounts; if you signed up with Google, sign in with the Continue with Google button instead (your password is managed by Google).

Google and email accounts are separate An email/password account and a Google account that happen to share the same email address are treated as two different accounts (each with its own quota). Pick one sign-in method per person and stick with it.
Open-mode deployments If the server has no Firebase service account configured, authentication is fully disabled: every visitor is treated as an anonymous admin with unlimited runs, no sign-in modal appears, and the Google button is hidden.

15.Limitations

LimitationDetail
180-second analysis timeoutA run exceeding 180 s is aborted server-side and reported as a timeout error
20-section capA tower with more than 20 sections is rejected outright (proof-of-concept memory guard on a ~1 GB server)
No persistent job databaseJobs live in server memory only; a server restart loses all in-progress and completed jobs that weren’t exported/saved
India-only wind lookupLat/lon → wind speed lookup only covers lat −10…40, lon 60…100; elsewhere enter wind parameters manually
No local member buckling checkGlobal member buckling (Perry–Robertson) is checked; local/cross-section buckling of thin-walled members is not separately verified
Base fixityLegs are fixed-base beam-columns; effective-length K factors are applied per role via KL/r, but no partial/spring foundation fixity is modelled
Linear-elastic material onlyNo plastic hinge / inelastic analysis, no fatigue, no corrosion allowance (geometric nonlinearity via corotTruss / P–Δ is captured)
First-mode dynamic gust onlyThe Cl. 10.2 gust-factor dynamic wind, IS 1893-4 seismic and Cl. 7.2.4 ice effects are implemented, but the dynamic wind uses a first-mode (f₁) estimate — a full multi-mode resonant/damping analysis is not performed
Fixed DVd thresholdThe subcritical/supercritical flow split for round members is hardcoded at DVd = 6 m²/s with no user override
Library reloadEdits to the bracing library may require a server restart to take effect, depending on deployment
This is a first-pass design/check tool It is not a substitute for a licensed structural engineer’s detailed design, connection design, foundation design, or code compliance sign-off.

16.Best Practices

  • Start from the example tower and modify incrementally rather than building from a blank slate — it’s a known-valid baseline.
  • Run “Review Inputs” before every analysis, especially after large geometry or bracing changes — it catches common modelling mistakes for free.
  • Check the Geometry tab first after every run, before trusting any numbers — a wrong bracing pattern or panel count produces a structurally different (and silently wrong) model.
  • Keep panel heights moderate (roughly 1–6 m) — very short or very tall panels distort solidity ratio and force-coefficient assumptions.
  • Use more/shorter sections at the base, where wind moment and axial load are highest, and fewer/taller sections near the top.
  • Cross-check critical designs against the STAAD export, particularly when UC is close to 1.0 or when you’ve switched diagonals to elasticBeamColumn.
  • Export your tower JSON after every meaningful change — there is no persistent history without Firebase, and a server restart silently discards in-memory jobs.
  • Validate custom bracing patterns in the Bracing Library tab before using them in a real tower — fix any duplicate-member, floating-node, or bypassed-node errors immediately.
  • Treat AI/rule-based guidance as a second opinion, not a final verdict — always apply engineering judgement on top of it.

17.Troubleshooting

SymptomLikely causeFix
“Too many sections (POC limit is 20 sections)”Tower exceeds the 20-section capMerge adjacent sections or reduce subdivisions
“Analysis timed out (> 180s)”Model too large/complex (many sections, fine bracing, many wind directions)Reduce wind directions analysed, simplify bracing, or split into fewer/larger sections
“Slope N: declared height … does not match the sum of its section heights”A slope’s height ≠ the sum of its section heightsAdjust the slope height or the section heights so they add up (see Slopes & Sections)
“Section …: num_panels × panel_height does not match the section height”Panel subdivision doesn’t tile the sectionSet panel_height = height / num_panels, or adjust num_panels/height
Bracing pattern won’t saveDuplicate member, floating extra node, or bypassed nodeUse the Bracing Library editor’s validation message to locate and fix the offending node/member
“bracing pattern … is only valid for N-leg towers”Pattern’s applicable_legs doesn’t include the current Tower TypePick a compatible pattern, or mark the pattern applicable to this leg count in the Bracing Library
Wind lookup says “not found”Coordinates outside the Indian subcontinent boundsEnter basic_wind_speed_ms and terrain_category manually
Job/report disappearedServer restarted (in-memory job store)Re-run the analysis; export JSON/report promptly next time
Memory error on large towers~1 GB VM memory guard exceededReduce section/node count, fewer wind directions, simpler bracing
UC > 1.0 on a memberMember undersized for the governing load combinationIncrease OD×t (pipe) or designation size (angle) for that section’s member; re-run

18.Glossary

Bracing editor & geometry

These are the terms used inside the Bracing Library editor and the pattern schema (bracings.json). A pattern is always authored on one face and replicated to every face by rotational symmetry, so most terms describe a single face and how members reach across to their neighbours.

TermMeaning
Face (F0, F1…)One flat side of the tower, the panel between two adjacent legs. A 3-leg tower has 3 faces, a 4-leg tower 4. The F0/F1… labels in the 3D editor are face indices, used to pick adjacent vs opposite faces deliberately.
Corner node (bot_L, bot_R, top_L, top_R)The four corners of a face panel — bottom/top ends of the two legs (left/right) that bound the face. Left/right are as seen looking at the face from outside.
Extra nodeA user-placed point beyond the four corners, sitting at fraction t along a member or leg. Used as an endpoint for further members. Created by Add Node / splitting a member.
t (position)Interpolation fraction from a member’s from end (t = 0, start) to its to end (t = 1, end). A split node at t = 0.25 sits 25 % of the way from the from node. Clamped to 0.05–0.95 so a node can’t land exactly on an endpoint.
X-intersect nodeA node placed at the geometric crossing of two lines (4-click), e.g. the centre of an X-brace. Because it isn’t on a single member it can’t anchor a ring or hip.
Face memberA member whose both ends lie on the same face (diagonal, horizontal, or redundant). In-plane bracing of that panel; replicated to every face.
DiagonalA face member running corner-to-corner across a panel — the primary bracing that carries shear.
Horizontal (member)A face member lying horizontally within one face (e.g. the mid horizontal of a K-brace). In-plane only — it does not go around the corner to the next face.
Horizontal ringA horizontal member repeated around the polygon, connecting the same node on two adjacent faces. Forms a closed loop tracing the section outline — it frames a diaphragm level and ties neighbouring legs. Schema: rings. Authored by clicking the same node on two adjacent faces → “Horizontal ring”.
Redundant linkAny cross-face connection (schema redundant_links: {from, to, face_offset, tag}). Covers hips and plan bracing — anything joining nodes on different faces.
face_offsetHow many faces around the polygon the target face is from the source: 0 = same face, ±1 = adjacent (a hip), numLegs/2 = opposite (plan bracing).
Hip memberA cross-face member to an adjacent face (face_offset = ±1). Legacy hips schema, now expressed as a redundant link; gives an interior node out-of-plane restraint.
Plan bracing (“cross”)A cross-face member to the opposite face (face_offset = numLegs/2) — a diagonal across the section plan. On a 4-leg square two of these make an X in plan. Stops the section racking/twisting; even-leg towers only (a triangle plan is already rigid).
cross_nodeA split point placed on a cross-face link (it resolves to a point between two faces). Lets one redundant link be split into two segments meeting at a real node.
Crossover / chainAn X-brace split at its crossover into sub-segments. The full-length “chain” drives a separate out-of-plane slenderness check (IS 17740 Annex F F-1 / Cl. 12.4).
TagShort label identifying a redundant or link (r1, rl1, plan1…) so it can be assigned its own member section. Hover a member/node in the 3D editor to see its tag/label.
ops_elementThe OpenSees element type used for a member: corotTruss, Truss, or elasticBeamColumn (see the analysis terms below).

Analysis & code

TermMeaning
UCUtilisation/unity check ratio — applied force divided by governing capacity; ≤ 1.0 = safe
KL/rEffective slenderness ratio (effective length / radius of gyration); per-role limits per IS 17740: legs & diagonals 150, horizontals 200, redundants 250
RedundantSecondary bracing member that subdivides a main member’s unbraced length; designed to a minimum bracing resistance (IS 17740 Cl. 10.4.2 / Annex C). See also Redundant link for the cross-face form.
Vb / VzBasic wind speed (10 m, flat open terrain) / design wind speed at height z
CfForce (drag) coefficient applied to projected member area to get wind force
Solidity ratio (φ)Ratio of projected (solid) member area to gross panel face area — drives Cf
corotTrussCorotational truss element: axial-only, geometrically nonlinear (captures large-displacement / rope effects)
elasticBeamColumnLinear-elastic beam element with full 6-DOF bending/shear/axial stiffness
Tdg / TdnDesign tensile capacity by gross-section yielding / by net-section rupture (IS 800 Cl. 6.1, 6.3)
NdDesign compressive (buckling) capacity, Perry–Robertson method, IS 800 Cl. 7.1
↑ Top