Skip to content

[2] Calc report enrichment, PRO workflow polish, and product step 1 continuation#47

Open
Batuis wants to merge 26 commits into
pr/2-next-product-iterationfrom
pr/3-calc-report-and-pro-polish
Open

[2] Calc report enrichment, PRO workflow polish, and product step 1 continuation#47
Batuis wants to merge 26 commits into
pr/2-next-product-iterationfrom
pr/3-calc-report-and-pro-polish

Conversation

@Batuis
Copy link
Copy Markdown
Collaborator

@Batuis Batuis commented Apr 7, 2026

Summary

Continuation of product step 1 work, stacked on PR #45.

Focus areas (from PRODUCT_ROADMAP.md daily-work priorities):

  • Calc report enrichment: governing cases, design-check tables, diagram exports
  • PRO workflow polish: remaining table/editing rough edges
  • Report and deliverable workflow hardening

Status

Work in progress.

Batuis added 22 commits April 19, 2026 00:55
Add a Design Summary section at the beginning of the PRO report (before
Model Data) when verification results exist:

- Overall pass/fail/warn status counts in a highlighted bar
- Design code reference
- Member Utilization Summary table sorted by utilization (most critical first):
  Element ID, Type, Section, Governing Check, Utilization %, Status
- Load combinations reference note

This is the "executive summary" that lets an engineer immediately see which
elements are critical and what the overall structural status is.

i18n: added 20+ report keys for en and es (designSummary, utilizationSummary,
governingCheck, flexure, shear, axialFlexure, beam, column, wall, etc.)
New example in the PRO Examples menu under "Energy & Offshore":
- 4-leg battered jacket (30m base → 18m top, 60m tall)
- X-bracing on all 4 faces across 6 bays (48 diagonal braces)
- Horizontal framing at 7 levels
- 4 central conductors
- Topsides deck at z=65m (24×24m, cantilevered beyond jacket)
- Flare boom arm with diagonal brace
- 6 steel sections (CHS legs, braces, horizontals, conductors + W-shape deck)
- 4 load cases (dead, live, wind, wave/current)
- 6 LRFD combinations

46 nodes, 121 elements, 8 supports, 20 loads.
Inspired by North Sea jacket platform reference.
Rebuilt the offshore example with much higher structural detail:

Jacket (80m tall, 8 bays):
- 4 battered legs (40m base → 20m top footprint)
- 64 X-braces (2 per face × 4 faces × 8 bays)
- 36 horizontal ring members (9 levels)
- 10 plan bracing members (every other level)
- 4 pile guide legs with mudline horizontal ring and cross bracing

Conductors (central core):
- 4 conductors segmented at 5 levels (0, 20, 40, 60, 80m)
- Horizontal tie rings and cross bracing at each conductor level
- Connected to jacket legs at matching levels

Topsides (3 deck levels: 82, 87, 92m):
- 24 deck nodes with perimeter and cross beams
- 16 inter-deck columns with diagonal bracing
- 4 transition columns from jacket top

Drilling derrick (92-122m):
- 4-leg lattice tower tapering upward
- Horizontal rings at 3 levels, X-bracing between levels

Flare boom: 3-member arm from deck to (52, -16, 100) with braces
Pedestal crane: column + arm to (-32, 12, 98) connected to deck

103 nodes, 316 elements, 12 supports, 50 loads.
All fixture validation tests pass (solves correctly).
Rebuilt jacket topology to match the reference image:

Jacket perimeter (12 vertical legs):
- 4 main corner legs (CHS 1200×40) at ±22m base → ±11m top
- 8 intermediate perimeter legs (CHS 900×30), 2 per face at 1/3 and 2/3
- Each face now has 4 vertical lines creating 3 bracing panels per face
- Total jacket height: 90m (z=-5 to z=85), 9 bays

Bracing density:
- 216 face X-braces (3 panels × 4 faces × 9 bays × 2 diagonals)
- 120 horizontal ring members (12 segments per level × 10 levels)
- 10 plan cross-braces at alternating levels
- 32 internal diagonal braces (corners to opposite-face intermediates)

Conductor core (8 conductors):
- 4 outer + 4 inner conductors at ±3m and ±1m offsets
- Segmented at 5 levels with horizontal ties and cross bracing
- Connected to jacket corner legs at matching levels

Topsides (3 levels: 87, 92, 97m):
- 8 nodes per deck (corners + mid-edges), cantilevered 15m
- 8 transition columns from jacket top (corners + intermediates)
- Full perimeter + cross beam framing per level

Drilling derrick: tapered 4-leg lattice (97-127m)
Flare boom: 3-segment arm to (58, -22, 100m)
Pedestal crane: column + arm to (-35, 13, 103m)

203 nodes, 668 elements, 20 supports, 74 loads.
Replaced the chaotic internal diagonals with structured internal planes:

Old pattern (wrong):
- Corners connected to opposite-face intermediates with ad hoc diagonals
- Created visually noisy crossing lines with no clear structural logic
- 32 arbitrary internal braces at 4 scattered levels

New pattern (correct):
- 2 orthogonal internal planes connecting parallel perimeter legs:
  - N-S plane: south intermediates ↔ north intermediates
  - E-W plane: east intermediates ↔ west intermediates
- Horizontal ties on both planes at every level (40 members)
- X-bracing on both planes between bays (72 members, 4 panels × 9 bays × 2 diags)
- Internal structure reads as 2 clear internal frames, not a web

The internal bracing now follows the same bay-by-bay X-brace logic
as the perimeter faces, just on the internal planes connecting
opposing parallel vertical lines.

203 nodes, 748 elements (+80 from v3), 20 supports, 74 loads.
…deck

Offshore example:
- Removed elements 740-748 (flare boom + crane) and their orphaned nodes
- Cleaned up floating node 203 with its load reference
- 197 nodes, 739 elements (down from 203/748)

Pitch deck:
- Complete visual redesign with Inter font, dark premium theme
- Grid/mesh background pattern, gradient backgrounds per slide
- Slide 1: product positioning with tagline
- Slide 2: capability grid (modeling, verification, reports) + example tags
- Slide 3: energy expansion with sector cards + offshore proof-of-concept bar
- Slide 4: Argentina focus with 2-column sector/opportunity layout
- Slide 5: team credentials (FIUBA/CEARE) + Patagonia field validation next step
Offshore example:
- Removed element 739 (orphaned boom member) and node 197
- Fixed disconnected structure: inner conductors (±1m) were isolated
  from outer conductor ring (±3m) — added 20 truss ties at each
  conductor level
- Fixed derrick disconnection: 4 derrick base nodes at z=97 were not
  tied to any deck nodes — added 4 frame connections to nearest deck
- 196 nodes, 762 elements, solves correctly

Pitch deck:
- Added real product screenshots: 3d-colormap.jpg (title slide),
  3d-deformed.jpg (capability slide), offshore-reference.webp (energy slide)
- Images integrated into slide layouts with shadows and borders
- Split-layout slides: text left, visual right
- Changed "Próximo paso clave" to "Próximos pasos" with 4 concrete items
  (Patagonia, expert testing, report review, industry pilots)
Offshore example fixes:
- Removed 20 intermediate-leg wave loads (kept corner-leg only), reduced
  magnitudes — lateral/gravity ratio improved from 1:2 to 1:6
- Upgraded deck beam from W24x68 (J=0.0000015) to RHS 500x300x16
  (J=0.000906) — 600x torsional stiffness improvement
- Upgraded derrick-to-deck connections from CHS 300x10 to CHS 800x25
- Converted 32 conductor frame ties to truss members (axial-only)
- Reduced wind loads from 150/50 kN to 50/20 kN per node

Root causes of wild deformed behavior:
1. Wave loads (Fx=2000 + Fy=1000 total) were nearly half the gravity load
2. Deck W-shape had near-zero torsional stiffness causing twist
3. Derrick connections used CHS 300 (weak bending) on long spans

Pitch deck:
- Replaced generic images with real landing-page screenshots:
  Slide 1: pro-verification.png (PRO RC building with rebar)
  Slide 2: 3d-industrial.png (Basic 3D industrial with color map)
  Slide 3: pro-features.png (PRO 3D model overview)
- Changed "Próximo paso clave" to "Próximos pasos" with 4 items
Captured the Offshore Jacket Platform example from the running PRO app
via Puppeteer (headless Chrome). Shows the full 196-node/762-element
battered jacket structure with dense bracing, topsides, and derrick.

Replaced the generic pro-features.png on the energy/offshore slide
with this real product screenshot, making the deck's offshore expansion
claim concrete and verifiable.
Main layout problems fixed:
- S1 hero: was fixed 480×360px absolute-positioned; now flex column
  with 580px max-width and 420px height img-frame
- S2 capability: was max-width 420px; now flex-1 up to 600px with
  440px height frame
- S3 offshore: was 380px fixed column with 360px max-width; now
  flex-1 up to 520px with 420px height and CSS transform scale(1.6)
  to zoom into the model center

All slides now use row flex layout (slide-inner flex-direction:row)
with text and visual columns balanced. Images use img-frame wrapper
with consistent border-radius, shadow, and border. Glow effects
positioned behind each image.

Offshore image uses object-position:center 40% + scale(1.6) to
crop/zoom into the jacket structure without re-capturing.
Pre-solve quality gate:
- handleSolve() now runs checkModel() before invoking the solver
- If model errors exist (severity: error), solve is BLOCKED
- Error message redirects user to the Diagnostics tab
- No cryptic solver crash — clear "N errors must be fixed" message

Quality-gate banner:
- Persistent amber banner appears above tab content when model has errors
- Shows error count + "Fix before solving" message
- Clicking the banner navigates to the Diagnostics tab
- Hides when viewing the Diagnostics tab (to avoid redundancy)

Reactive model error count:
- modelErrorCount derived tracks errors in real-time as model changes
- Powers both the banner visibility and the solve gate

Existing diagnostics infrastructure leveraged:
- checkModel() already has 30+ checks (connectivity, zero-length,
  missing refs, orphan loads, etc.)
- ProDiagnosticsTab already has clickable items that select entities
  and zoom-to-fit
- This change connects the pre-solve flow to that existing infrastructure

i18n: en + es (modelErrorsBlock, seeDiagnostics, qualityGate,
errorsFound, fixBeforeSolve)
Adds a "Generate LRFD Combinations" button in the PRO Loads tab that
auto-generates ASCE 7 / CIRSOC 101 ultimate load combinations from
existing load-case types.

The generator reads load-case types (D, L, Lr, S, W, E) and produces:
1. 1.4D
2. 1.2D + 1.6L + 0.5(Lr or S)
3. 1.2D + 1.6(Lr or S) + L
4. 1.2D + 1.6W + L + 0.5Lr (per wind case)
5. 1.2D + E + L (per seismic case)
6. 0.9D + 1.6W (per wind case)
7. 0.9D + E (per seismic case)

Features:
- Reads existing load-case type tags to determine which combos apply
- Names each combination with clear factor expression (e.g., "U3: 1.2D + 1.6Lr + L")
- Uses short wind/seismic case names in combo labels
- Generated combos are fully editable after generation
- Requires at least one D-type case (shows error toast otherwise)
- All additions wrapped in modelStore.batch() for single undo
- Button appears below the manual combo-add row with hint text

i18n: en + es (generateLRFD, generateLRFDHint, generateLRFDDesc,
combosGenerated, needDeadCase)
Replaces the one-click combo generator with a reviewed modal flow:

1. Click "Generate LRFD Combinations" → opens a review modal
2. Modal lists all candidate ASCE 7 / CIRSOC 101 combinations
3. Each candidate shows: name, factor expression, and whether an
   equivalent combination already exists
4. New combos are checked by default; existing ones are unchecked
   with an "already exists" badge (dimmed row)
5. User can override: check an existing one to intentionally duplicate
6. Click "Generate Selected" → only checked candidates are added

Equivalence detection:
- comboSignature() creates a canonical string from non-zero factors
  sorted by caseId, rounded to 2 decimals
- comboExists() compares candidate signature against all existing
  combination signatures
- Equivalence is content-based, not name-based — works even if
  existing combos were renamed

Modal UX:
- Dark themed, centered overlay with close/cancel/generate buttons
- Shows "N / M selected" counter in footer
- Generate button disabled when nothing is selected
- Backdrop click closes the modal

i18n: en + es (comboAlreadyExists, selected, generateSelected)
Example naming:
- Removed "(CIRSOC 102)" from 7-story Wind +X case name
- Fixed lowercase "Dead load"/"Live load" to "Dead Load"/"Live Load"
  in 3d-building.json and 3d-nave-industrial.json

LRFD equivalence fix:
- Root cause: generator added 0.5×Lr companion to wind combos (pattern 4)
  but existing 7-story combos don't include the Lr companion load,
  so signatures differed (5 non-zero terms vs 4)
- Fix: removed 0.5×Lr/S companion from wind/seismic combos to match
  standard practice where the companion load is optional
- Now the 7-story U4-U7 combos correctly match generated candidates

Display ordering:
- Factor expressions in the generator modal now sort by load-case type
  priority: D → L → Lr → S → W → E → other
- Within same type, sorted by caseId
- Produces stable professional ordering regardless of insertion order
Example naming cleanup:
- Removed redundant type prefixes from load-case names in 7-story
  and offshore examples (e.g., "D — Superimposed dead" → "Superimposed dead")
- Type is already shown by the UI's type column/dot; the name now
  carries only the descriptive content

Service/ASD combination generator:
- New "Generate Service Combinations" button alongside the existing LRFD one
- Produces ASCE 7 §2.4 / CIRSOC 101 ASD combinations:
  S1: D
  S2: D + L
  S3: D + Lr (or S)
  S4: D + 0.75L + 0.75Lr
  S5: D + W (per wind direction)
  S6: D + 0.7E (per seismic direction)
  S7: D + 0.75L + 0.75W
  S8: 0.6D + W
  S9: 0.6D + 0.7E
- Same reviewed modal workflow as LRFD (candidates, equivalence, check/uncheck)
- Service combos prefixed with "S" (vs "U" for LRFD)

Provenance badges:
- Combination cards now show small badges based on naming convention:
  - "LRFD" badge (red) for combos matching /^U\d+:/
  - "SVC" badge (teal) for combos matching /^S\d+:/
- Badges are visual-only; combos remain fully editable
- If user renames away from the convention, badge disappears (honest)

Other:
- Removed lightning emoji from generate button
- Modal header shows template name + ASCE 7 section reference
- i18n: en + es for generateService, generateServiceHint, serviceCombosGenerated
Preview formatting:
- Existing-equivalent combos in the modal now show only non-zero
  factors, each on its own row: factor | type | name
- Matches the mental model of the main combination card layout
- Zero-factor load cases are no longer shown (were cluttering the preview)
- Rows sorted by type priority: D → L → Lr → S → W → E

Numbering fix:
- Root cause: applySelectedCombos used combinations.length for the
  counter, so U1-U8 existing → first service combo was S9 instead of S1
- Fix: count only combos matching the active prefix (/^U\d+:/ or /^S\d+:/)
- LRFD and Service numbering are now fully independent families
- U1-U8 existing + no S combos → first service is S1
- S1-S4 existing + no U combos → first LRFD is U1
…Design tab

Report Design Summary:
- Added "Governing Combo" column to the Member Utilization Summary table
- Shows the combination name that produces the governing check for each element
- Combo selection logic: picks the combo corresponding to the governing check type
  (flexure → flexure combo, shear → shear combo, axial+flexure → axial combo)
- Displayed at 9px to fit the table width without overflow

ProDesignTab expandable check details:
- Clicking a design-check row now expands a detail panel below it
- Detail panel shows ALL individual checks for that member:
  Check name | Demand | Capacity | Ratio | Status | Combo
- Each check shows its own governing combination reference
- This enables per-check combo traceability (flexure may govern in U3
  while shear governs in U5 — both are now visible)
- Second click collapses the detail panel
- Click also selects the element in the viewport (existing behavior preserved)

These changes connect the combination workflow → verification → report chain:
- Combinations are generated/edited in the Loads tab
- The Design tab shows which combo governs each check (expandable)
- The Report summarizes governing combos per element (printable)

i18n: en + es (report.governingCombo)
The {@const nonZero = ...} was placed inside a <label> element.
In Svelte 5, {@const} must be the immediate child of a block tag
({#each}, {#if}, etc.), not an HTML element.

Moved the declaration to be immediately after the {#each} opening,
before the <label>. The inner {@const lc3 = ...} inside the nested
{#each nonZero as f} was already valid (direct child of #each).
Data model:
- ElementVerification.governingCombos now carries 6 force components:
  flexure, shear, axial, momentY, shearZ, torsion (was only 3)
- auto-verify.ts now attaches all 6 governing combo refs from
  GoverningPerElement3D when available
- normalizeCirsoc201() now passes comboName for torsion and biaxial
  checks (was missing — those checks showed '—')

Design tab expandable detail:
- When different checks are governed by different combos, a note
  appears: "Different checks governed by different combinations"
- Combo column header renamed to "Governing Combo" for clarity
- Combo cells are highlighted in teal when multiple combos are active
- uniqueCombos set computed per element to detect multi-combo cases

Report Design Summary:
- Governing combo column now marks elements where different checks
  have different governing combos with '*' and orange highlighting
- Footnote explains: "Different checks governed by different
  combinations — see detailed verification for full breakdown"

This addresses the structural-design principle that a member's
flexure, shear, and axial checks may each be governed by a different
load combination — the UI now makes this visible instead of collapsing
everything into a single "governing combo" label.

i18n: en + es (report.multiGovNote)
New module: station-design-forces.ts
The core product-layer foundation for elite-grade RC/steel design
traceability. Extracts forces at critical stations along each element,
for each load combination, preserving sign and the full force tuple.

Station strategy (buildCriticalStations):
- Element endpoints (t=0, t=1)
- Quarter and midpoint (t=0.25, 0.5, 0.75)
- All point-load positions from Y and Z load arrays
- Distributed-load start/end positions and midpoints
- Analytical shear zero-crossing point (interior moment peak)
  computed from endpoint shear sign change

Force extraction (extractForcesAtStation):
- Uses evaluateDiagramAt() for each force component at each station
- Returns full signed tuple: N, Vy, Vz, My, Mz, Torsion
- Exact analytical equilibrium — not interpolation

Per-combo extraction (extractElementStations):
- Iterates all combos in resultsStore.perCombo3D
- Extracts station forces for the requested element under each combo
- Preserves comboId, comboName, and full station force tuples

Governing demand extraction (extractGoverningDemands):
- From station-level per-combo data, finds the worst demand per category:
  Mz+, Mz- (sign-aware), My+, My-, Vy, Vz, N_compression, N_tension, Torsion
- Each demand preserves: value, combo, station, AND the full force tuple
  at that combo/station (critical for combined axial+moment checks)
- Does NOT create impossible envelopes by mixing combos/stations

Design tab integration:
- Expanded element rows now show "Station-Based Governing Demands" section
- Shows: category, value, station location, governing combo, and the
  concurrent N/Vy/Mz force tuple
- Only appears when per-combo results exist (combinations were solved)

Also extended:
- ElementVerification.governingCombos now tracks 6 components
  (added momentY, shearZ, torsion)
- normalizeCirsoc201 now passes comboName for torsion/biaxial checks

CURRENT LIMITATIONS (solver contract):
- No P-delta interior forces (endpoint-only for P-delta)
- No support-face offset (d from column face)
- No cracked-section iteration
- Torsion diagram is linear interpolation only
@Batuis Batuis force-pushed the pr/3-calc-report-and-pro-polish branch from 5ed9a93 to 664ff08 Compare April 19, 2026 15:55
Batuis added 2 commits April 19, 2026 15:04
…d drawing reactivity

- Single "Run Design" button replaces two-step batch flow (design check + accept)
- Design edits now drive live drawings via structuredClone + $state.snapshot reactivity fix
- Column structured editor (corner/face bars, diameters) with zero in-place mutation
- All number inputs use oninput for immediate feedback
- Rich inline verification: CIRSOC memos, interaction diagram, check table, utilization
- Provided-verification utilization responds to edits via enrichedResults $derived
- Anchorage severity: warn vs fail distinction, descriptive messages
- Summary row coherence: governing check and utilization from provided verification
- Removed old RC Verification subtab and Analysis dropdown entry
- Removed duplicate design-vs-verification drawings (single trust surface)
- Removed redundant modified-reinforcement summary strip
- Filter cleanup: Un-designed, Modified (user-only), status filters for designed elements
- rc-qa-diagnostic fixture: balanced loads for meaningful QA
- QA feedback docs from QA2-QA4 rounds
@Batuis Batuis force-pushed the pr/3-calc-report-and-pro-polish branch from 4c91e2d to 052539f Compare April 19, 2026 18:05
@Batuis Batuis marked this pull request as ready for review April 19, 2026 18:05
Batuis added 2 commits April 20, 2026 18:42
…ro-polish

Resolves model.svelte.ts conflict by combining:
 - main/pr/2 typed Release per-element-end (Release type, releaseI/releaseJ)
 - pr/3 reinforcement schema (RebarGroup, RebarLayer, StirrupDef,
   LongBarGroup, BeamContinuity, BeamRegions, ColumnReinforcement,
   ProvidedReinforcement) and Element.reinforcement?: field

The two changes are orthogonal — Release is per-end DOF release, while
the reinforcement schema is RC design metadata. Both live on Element.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant