Exemple rezolvate

Patru scripturi de copiat și rulat. Fiecare indică rezultatul așteptat pentru exact datele sale de intrare și soluția analitică față de care a fost verificat, astfel încât să confirmați că instalarea dumneavoastră le reproduce înainte de a avea încredere într-un model propriu.

1. Consolă cu forță la capăt

O consolă IPE 180 de 5 m, complet încastrată la un capăt, cu o forță concentrată descendentă de 1 kN la vârf. Este cel mai simplu model care parcurge întregul lanț: geometrie, material, secțiune, reazem, ipoteză de încărcare și calcul.

from fers_core import FERS, Node, Member, Section, Material, MemberSet, NodalSupport, NodalLoad

model = FERS()

node1 = Node(0, 0, 0)  # fixed end
node2 = Node(5, 0, 0)  # free end (5 m span)

steel = Material(name="Steel S235", e_mod=210e9, g_mod=80.769e9, density=7850, yield_stress=235e6)
# IPE 180 from the FERS section library: i_z = strong axis (in play here), i_y = weak axis
section = Section(name="IPE 180", material=steel, i_y=1.009e-6, i_z=13.17e-6, j=0.0477e-6, area=0.00240)

beam = Member(start_node=node1, end_node=node2, section=section)
node1.nodal_support = NodalSupport()  # fully fixed
model.add_member_set(MemberSet(members=[beam]))

lc = model.create_load_case(name="End Load")
NodalLoad(node=node2, load_case=lc, magnitude=-1000, direction=(0, 1, 0))

model.run_analysis()

dy = model.resultsbundle.loadcases["End Load"].displacement_nodes["2"].dy
print(f"Tip deflection: {dy*1000:.3f} mm")
# Expected output: Tip deflection: -15.065 mm
# Hand check: δ = PL³/3EI_z = 1000·5³ / (3 · 210e9 · 13.17e-6) = 15.07 mm ✓

Verificare manuală: δ = PL³ / 3EI_z = 1000·5³ / (3 · 210×10⁹ · 13,17×10⁻⁶) = 15,07 mm. Solverul returnează 15,065 mm.

2. Grindă simplu rezemată cu forță la mijloc

Un IPE 300 de 10 m împărțit în două bare de 5 m, pentru a avea un nod la mijlocul deschiderii unde să încărcați și să citiți. Articulație la un capăt, reazem mobil la celălalt.

Observați condițiile de rezemare explicite. Articulația blochează cele trei translații și rotirea de torsiune, dar lasă libere rotirile de încovoiere — dacă nu blocați torsiunea, grinda are un mod de corp rigid, iar matricea de rigiditate este singulară. Reazemul mobil eliberează în plus translația longitudinală, ca grinda să se poată alungi liber.

from fers_core import FERS, Node, Member, Section, Material, MemberSet, NodalSupport, NodalLoad

model = FERS()

node1 = Node(0, 0, 0)
node2 = Node(5, 0, 0)   # mid-span
node3 = Node(10, 0, 0)  # right support

steel = Material(name="Steel S235", e_mod=210e9, g_mod=80.769e9, density=7850, yield_stress=235e6)
section = Section(name="IPE 300", material=steel, i_y=6.038e-6, i_z=83.58e-6, j=0.199e-6, area=0.00538)

beam1 = Member(start_node=node1, end_node=node2, section=section)
beam2 = Member(start_node=node2, end_node=node3, section=section)

# Pin at node1 — bending rotations free, torsion (RX) held so the beam
# has no rigid-body twist mode. Roller at node3 — X translation free too.
pin = NodalSupport(
    displacement_conditions={"X": "Fixed", "Y": "Fixed", "Z": "Fixed"},
    rotation_conditions={"X": "Fixed", "Y": "Free", "Z": "Free"},
)
roller = NodalSupport(
    displacement_conditions={"X": "Free", "Y": "Fixed", "Z": "Fixed"},
    rotation_conditions={"X": "Free", "Y": "Free", "Z": "Free"},
)
node1.nodal_support = pin
node3.nodal_support = roller

model.add_member_set(MemberSet(members=[beam1, beam2]))

lc = model.create_load_case(name="Centre Load")
NodalLoad(node=node2, load_case=lc, magnitude=-10000, direction=(0, 1, 0))

model.run_analysis()

dy_mid = model.resultsbundle.loadcases["Centre Load"].displacement_nodes["2"].dy
print(f"Mid-span deflection: {dy_mid*1000:.3f} mm")
# Expected output: Mid-span deflection: -11.870 mm
# Hand check: δ = PL³/48EI_z = 10000·10³ / (48 · 210e9 · 83.58e-6) = 11.87 mm ✓

Verificare manuală: δ = PL³ / 48EI_z = 10000·10³ / (48 · 210×10⁹ · 83,58×10⁻⁶) = 11,87 mm. Solverul returnează 11,870 mm.

3. Cadru sub încărcare orizontală

Doi stâlpi HEA 200 de 4 m cu baze încastrate și o riglă IPE 300 de 6 m, încărcați cu o forță orizontală de 5 kN în capul stâlpului stâng. Este cel mai mic model în care comportarea de cadru — și nu o bară izolată — determină rezultatul.

from fers_core import FERS, Node, Member, Section, Material, MemberSet, NodalSupport, NodalLoad

model = FERS()

# Portal frame: two columns (h=4 m) + one beam (L=6 m)
n1 = Node(0, 0, 0)   # left base
n2 = Node(0, 4, 0)   # left top
n3 = Node(6, 4, 0)   # right top
n4 = Node(6, 0, 0)   # right base

steel = Material(name="Steel S235", e_mod=210e9, g_mod=80.769e9, density=7850, yield_stress=235e6)
col_sec  = Section(name="HEA 200", material=steel, i_y=13.36e-6, i_z=36.93e-6, j=0.206e-6, area=0.00538)
beam_sec = Section(name="IPE 300", material=steel, i_y=6.038e-6, i_z=83.58e-6, j=0.199e-6, area=0.00538)

col_left  = Member(start_node=n1, end_node=n2, section=col_sec)
col_right = Member(start_node=n4, end_node=n3, section=col_sec)
rafter    = Member(start_node=n2, end_node=n3, section=beam_sec)

n1.nodal_support = NodalSupport()  # fixed base
n4.nodal_support = NodalSupport()  # fixed base

model.add_member_set(MemberSet(members=[col_left, col_right, rafter]))

lc = model.create_load_case(name="Wind")
# Horizontal wind load on left column top
NodalLoad(node=n2, load_case=lc, magnitude=5000, direction=(1, 0, 0))

model.run_analysis()

dx = model.resultsbundle.loadcases["Wind"].displacement_nodes["2"].dx
print(f"Sway at left top: {dx*1000:.3f} mm")
# Expected output: Sway at left top: 5.310 mm
# Hand check (slope-deflection, axial deformation neglected): 5.30 mm ✓

Verificare manuală prin metoda deplasărilor, neglijând deformația axială: 5,30 mm. Solverul returnează 5,310 mm. O tratare mai amplă, cu diagrame, se află în exemplul de cadru.

4. Verificare de oțel conform Eurocod 3

check_beam construiește o grindă cu o singură deschidere, o calculează și rulează verificările EN 1993-1-1 într-un singur apel. Aici: un IPE 400 simplu rezemat de 7,5 m din S355, sub o încărcare uniform distribuită caracteristică de 13 kN/m, majorată cu 1,35, cu talpa comprimată nerezemată pe toată deschiderea.

Rezultatul conține o desfășurare clauză cu clauză în locul unui singur număr, astfel încât fiecare grad de utilizare se citește ca un calcul manual — toate valorile intermediare care l-au produs sunt acolo.

from fers_core import check_beam

# 7.5 m simply supported IPE 400 in S355, 13 kN/m characteristic UDL,
# ULS factor 1.35, compression flange unrestrained over the full span
model = check_beam(
    span=7.5,
    section="IPE400",
    material="S355",
    udl=13_000,       # N/m characteristic (13 kN/m)
    uls_factor=1.35,
)

model.run_analysis()

check = model.unity_check_results()[0]
print(f"Governing UC: {check['max_utilization']:.2f}")
for step in check["governing"]["trace"]:
    print(f"  {step['label']:22s} {step['value']:.2f}")

# Expected output (solver-computed, matches the published worked example):
# Governing UC: 0.82
#   Bending y (6.2.5)      0.00
#   Bending z (6.2.5)      0.27
#   Shear z (6.2.6)        0.00
#   Shear y (6.2.6)        0.07
#   Combined N+M (6.2.1)   0.27
#   LTB (6.3.2)            0.82
#   Governing              0.82

Acest lucru reproduce exemplul publicat pentru Eurocod 3, în care același caz este desfășurat clauză cu clauză. Determinant este flambajul lateral prin încovoiere-răsucire, cu un grad de utilizare de 0,82.

Verificați înainte de a avea încredere

Fiecare exemplu de mai sus afișează un număr alături de soluția analitică pe care ar trebui să o reproducă. Este intenționat și este obiceiul care merită preluat: calculați un caz al cărui răspuns îl cunoașteți deja, înainte de a trece la unul pe care nu îl cunoașteți.

Testele de precizie fac acest lucru pe un set mai larg de soluții analitice, iar pagina NAFEMS rulează în direct, în browserul dumneavoastră, testele standard cu elemente finite, cu eroarea dintre valoarea țintă și FERS pentru fiecare.

Pagini conexe

Vezi și

Întrebări frecvente

De ce exemplul cu grindă simplu rezemată are nevoie de două bare?

Doar pentru a avea un nod la mijlocul deschiderii, unde se aplică forța și se citește deplasarea. Formularea elementului este exactă pentru o bară prismatică, deci împărțirea deschiderii nu schimbă rezultatul — oferă doar un punct de aplicare.

De ce articulația blochează rotirea de torsiune?

Eliberarea tuturor celor trei rotiri la ambele capete ale unei grinzi drepte o lasă liberă să se rotească în jurul propriei axe. Acel mod de corp rigid face matricea de rigiditate singulară, iar calculul eșuează. Blocarea RX la un reazem elimină modul fără a împiedica vreo încovoiere.

Valorile mele diferă la ultima cifră — este ceva greșit?

Nu. Valorile afișate sunt rotunjite la trei zecimale de milimetru; comparația cu soluția analitică este dată cu precizia pe care o justifică formula. O diferență mai mare indică de obicei i_y și i_z inversate sau o greșeală de unități.

De unde provin caracteristicile secțiunilor?

Din biblioteca de profile de oțel FERS, livrată împreună cu pachetul. Puteți transmite caracteristicile și direct, cum fac aceste exemple, sau le puteți determina pentru o formă oarecare cu calculatorul de caracteristici de secțiune.

Pot rula aceste exemple fără cont?

Da. Toate patru se calculează local, fără credențiale. Doar stocarea în cloud și canalele API/agenți contorizate necesită o cheie.

Cum fac același lucru din JavaScript?

Același motor este publicat ca pachet npm în WebAssembly, cu un format de model identic — vedeți FERS din JavaScript.