18
18
from osmg .analysis .supports import ElasticSupport , FixedSupport
19
19
from osmg .core .common import EPSILON , THREE_DIMENSIONAL , TWO_DIMENSIONAL
20
20
from osmg .core .osmg_collections import BeamColumnAssembly
21
- from osmg .model_objects .element import BeamColumnElement
21
+ from osmg .model_objects .element import BeamColumnElement , Bar
22
22
23
23
from tqdm import tqdm
24
24
25
25
if TYPE_CHECKING :
26
26
from osmg .analysis .common import PointLoad
27
27
from osmg .core .model import Model , Model2D , Model3D
28
28
from osmg .model_objects .node import Node
29
+ from osmg .core .osmg_collections import ComponentAssembly
29
30
30
31
31
32
def ensure_minmax_level_exists_or_add (data : pd .DataFrame ) -> pd .DataFrame :
@@ -241,7 +242,7 @@ def define_rigid_diaphragm(
241
242
def calculate_basic_forces ( # noqa: C901
242
243
self ,
243
244
recorder_name : str ,
244
- element_lengths : dict [int , float ],
245
+ components : dict [int , ComponentAssembly ],
245
246
* ,
246
247
ndm : int ,
247
248
num_stations : int = 12 ,
@@ -300,9 +301,25 @@ def calculate_basic_forces( # noqa: C901
300
301
raise TypeError (msg )
301
302
302
303
if isinstance (self , HasLoads ):
303
- udls = self .load_registry .element_udl
304
+ udls_global = self .load_registry .element_udl
304
305
else :
305
- udls = {}
306
+ udls_global = {}
307
+
308
+ udls_local = {}
309
+ elements = {}
310
+ for component_uid , component in components .items ():
311
+ if not isinstance (component , BeamColumnAssembly ):
312
+ continue
313
+ for element in component .elements .values ():
314
+ if isinstance (element , (BeamColumnElement , Bar )):
315
+ elements [element .uid ] = element
316
+ elements .update (component .elements )
317
+ component_global_udl = udls_global .get (component_uid )
318
+ if component_global_udl :
319
+ component_local_udls = component .calculate_element_udl (
320
+ component_global_udl
321
+ )
322
+ udls_local .update (component_local_udls )
306
323
307
324
data = recorder .get_data ()
308
325
@@ -327,11 +344,17 @@ def calculate_basic_forces( # noqa: C901
327
344
# dof: df.xs(1.0, level='station', axis=1) for dof, df in dof_data.items()
328
345
# }
329
346
330
- missing_elements = [e for e in recorder .elements if e not in element_lengths ]
347
+ missing_elements = [e for e in recorder .elements if e not in elements ]
331
348
if missing_elements :
332
- msg = f'Missing lengths for elements: { missing_elements } '
349
+ msg = f'Missing elements: { missing_elements } '
333
350
raise ValueError (msg )
334
351
352
+ element_lengths : dict [int , float ] = {
353
+ element .uid : element .clear_length ()
354
+ for element in elements .values ()
355
+ if isinstance (element , BeamColumnElement )
356
+ }
357
+
335
358
locations = np .array (
336
359
[
337
360
np .linspace (0.00 , element_lengths [element ], num = num_stations )
@@ -360,7 +383,9 @@ def calculate_basic_forces( # noqa: C901
360
383
# data_j_axial = dof_data_j[1]
361
384
w_data_axial = np .array (
362
385
[
363
- udls [element_uid ][0 ] if udls .get (element_uid ) is not None else 0.00
386
+ udls_local [element_uid ][0 ]
387
+ if udls_local .get (element_uid ) is not None
388
+ else 0.00
364
389
for element_uid in recorder .elements
365
390
]
366
391
)[np .newaxis , :, np .newaxis ]
@@ -385,7 +410,9 @@ def calculate_basic_forces( # noqa: C901
385
410
# data_j_shear_y = dof_data_j[2]
386
411
w_data_shear_y = np .array (
387
412
[
388
- udls [element_uid ][1 ] if udls .get (element_uid ) is not None else 0.00
413
+ udls_local [element_uid ][1 ]
414
+ if udls_local .get (element_uid ) is not None
415
+ else 0.00
389
416
for element_uid in recorder .elements
390
417
]
391
418
)[np .newaxis , :, np .newaxis ]
@@ -418,8 +445,8 @@ def calculate_basic_forces( # noqa: C901
418
445
# data_j_shear_z = dof_data_j[3]
419
446
w_data_shear_z = np .array (
420
447
[
421
- udls [element_uid ][2 ]
422
- if udls .get (element_uid ) is not None
448
+ udls_local [element_uid ][2 ]
449
+ if udls_local .get (element_uid ) is not None
423
450
else 0.00
424
451
for element_uid in recorder .elements
425
452
]
@@ -680,18 +707,16 @@ def self_weight(self, case_name: str, scaling_factor: float = 1.0) -> None:
680
707
case_name: Name of the load case to be created.
681
708
scaling_factor: Self-weight scaling factor to use.
682
709
"""
683
- # get all beamcolumn elements
684
- elements = [
685
- element
710
+ # get all beamcolumn assemblies
711
+ components = [
712
+ component
686
713
for component in self .model .components .values ()
687
714
if isinstance (component , BeamColumnAssembly )
688
- for element in component .elements .values ()
689
- if isinstance (element , BeamColumnElement )
690
715
]
691
- for element in elements :
692
- weight_per_length = element . section .sec_w * scaling_factor
716
+ for component in components :
717
+ weight_per_length = component . get_section () .sec_w * scaling_factor
693
718
udl = UDL ((0.00 , 0.00 , - weight_per_length ))
694
- self .dead [case_name ].load_registry .element_udl [element .uid ] = udl
719
+ self .dead [case_name ].load_registry .element_udl [component .uid ] = udl
695
720
696
721
def self_mass (
697
722
self ,
@@ -712,30 +737,29 @@ def self_mass(
712
737
a scaling coefficient.
713
738
g_constant: Factor to convert loads to mass.
714
739
"""
715
- # get all beamcolumn elements
716
- elements = {
717
- element .uid : element
740
+ # get all BeamColumn assemblies
741
+ components = {
742
+ component .uid : component
718
743
for component in self .model .components .values ()
719
744
if isinstance (component , BeamColumnAssembly )
720
- for element in component .elements .values ()
721
- if isinstance (element , BeamColumnElement )
722
745
}
723
746
for source_load_case , factor in source_load_cases :
724
747
# Convert UDL to mass
725
748
for uid , udl in source_load_case .load_registry .element_udl .items ():
726
- element = elements [uid ]
727
- length = element .clear_length ()
749
+ component = components [uid ]
750
+ length = component .clear_length ()
728
751
weight = np .abs (udl [- 1 ] * length )
729
- mass = weight * factor / g_constant / 2.0
752
+ num_nodes = len (component .internal_nodes )
753
+ mass = weight * factor / g_constant / num_nodes
730
754
# TODO(JVM): separate cases for other ndm/ndf
731
755
# configurations.
732
756
point_mass = PointMass ((mass , mass , mass , 0.00 , 0.00 , 0.00 ))
733
- for node in element . nodes :
734
- if node . uid not in target_load_case .mass_registry :
735
- target_load_case .mass_registry [node . uid ] = point_mass
757
+ for node_uid in component . internal_nodes :
758
+ if node_uid not in target_load_case .mass_registry :
759
+ target_load_case .mass_registry [node_uid ] = point_mass
736
760
else :
737
- existing_mass = target_load_case .mass_registry [node . uid ]
738
- target_load_case .mass_registry [node . uid ] = PointMass (
761
+ existing_mass = target_load_case .mass_registry [node_uid ]
762
+ target_load_case .mass_registry [node_uid ] = PointMass (
739
763
(* (e + p for e , p in zip (existing_mass , point_mass )),)
740
764
)
741
765
0 commit comments