Structural Model Import (Dynamics)¶
The building dynamic-response pipeline needs the structure’s modal model:
per-floor mass, polar inertia and radius of gyration, the centre of mass,
the natural periods, and the per-floor mode shapes (DX, DY and the
torsional rotation RZ). The structural engineer produces that model in
their design software; these converters turn those exports into the internal
BuildingStructuralData the recipe
consumes, removing a manual, error-prone transcription step.
Supported sources¶
TQS (Portico Espacial), nodal set – read_tqs_portels. Latin-1 text
files (// comment lines, comma decimals, TAB-separated). The file-name
prefix is PORTELS_ (older) or PORTELSSE_ (newer); both are accepted:
*_MODOS.TXT– one row per mode: number, period, angular frequency, frequency.*_NOS.TXT– nodal coordinates (No; X; Y; Z).*_MASSAS.TXT– lumped nodal masses.*_FORMAS2.TXT– per-mode nodal mode shapes carrying rotation (No; DX; DY; RZ).*_PISOS.TXT– optional floor table (Piso; Nome; Nivel), in newer exports.
This is nodal data and needs aggregation to per-floor (see below).
TQS (Portico), per-floor set – read_tqs_portico. Some deliveries ship a
per-floor summary instead (TAB-separated, decimal point):
PORTICO_MASSAS_PAVIMENTO.TXT– per floor:Pavimento; Elevacao (cm); Massa X/Y/Z; Momento de inercia; Xcg (cm); Ycg (cm).PORTICO_MODOS_PAVIMENTO.TXT– per mode: per-floorPavimento; DX; DY; RZ.modes.csv–mode,period[,wp,freq](the natural periods).
Already per-floor – no nodal aggregation.
Eberick (AltoQi) – read_eberick. Eberick models each storey as a rigid
diaphragm, so its results are already per-floor. A pair of spreadsheets:
DISTRIBUICAO_DAS_MASSAS_DOS_PAVIMENTOS.xlsx– per floorPavimento; Altura; Elevacao (cm); Massa; Momento de inercia; Xcg (cm); Ycg (cm).FORMAS_MODAIS_DOS_PAVIMENTOS.xlsx– one block per mode with its frequency (Hz) and a per-floorPavimento; Dx (cm); Dy (cm); Rz (rad)table.
The reader skips the project-identifying header block and matches the files
case/accent-insensitively. The damping ratio lives in the companion “sistema de
referencia” sheet; pass it explicitly to to_config(damping_ratio=...).
How the conversion works¶
All three readers converge on the same internal model. The transformation:
Nodal -> per-floor (TQS PORTELS only). Nodes are grouped by slab elevation, and each slab is reduced to lumped floor properties (
aggregate_to_building()):M = sum_node mXG = sum_node m*x / M,YG = sum_node m*y / M(centre of mass)I = sum_node m*((x-XG)^2 + (y-YG)^2)(polar inertia about the CoM)R = sqrt(I / M)(radius of gyration)DX = sum_node m*DX_node / M(mass-weighted rigid-diaphragm shape; same forDY,RZ)
When a
PISOStable is present its levels define the real floors, so the many intermediate FE node elevations (beams, landings) collapse onto actual slabs; otherwise elevations are found by clustering nodeZ. The Portico and Eberick sets already give these floor quantities directly.Units -> SI. Portico and Eberick report lengths in centimetres and mass in
tf.s^2/cm; these are converted to metres and kilograms (EberickUnits, overridable). TQS PORTELS coordinates are already in metres.Mass-normalization. Mode shapes are scaled to unit generalized mass (
sum_floor M*(DX^2 + DY^2 + (R*RZ)^2) = 1per mode) – the precondition the single-degree-of-freedom modal solver assumes.Metadata. The storey names are carried through in
BuildingStructuralData.floor_labelsand any extra per-floor columns (e.g. Eberick’s storey height) infloor_metadata– ignored by the recipe but preserved for reporting and written as extra columns infloors.csv.
The result is a per-floor model: floors ascending by elevation, floor_points
/ cm_positions from the centre of mass, floors_mass / floors_radius,
natural_frequencies (angular, from the periods), and mass-normalized
mode_shapes.
Usage¶
From Python:
from cfdmod.dynamics import read_tqs_portels, read_tqs_portico, read_eberick
structure = read_tqs_portels("path/to/portels_export/")
# or: read_tqs_portico("path/to/portico_export/")
# or: read_eberick("path/to/eberick_export/")
cfg = structure.to_config(damping_ratio=0.015)
# -> build_building_dynamic_response(load_source, cfg)
Each reader also accepts explicit file paths (for renamed files), e.g.
read_eberick(dir, masses_file=..., formas_file=...).
From the command line, writing the internal modes.csv / floors.csv /
phi{m}.csv (round-trippable with
from_csvs(); the
floors.csv also carries a name column and any metadata):
cfdmod dynamics <export_dir> --out out_dir --format tqs
cfdmod dynamics <export_dir> --out out_dir --format portico
cfdmod dynamics <export_dir> --out out_dir --format eberick