Load Effect Calculation from Traffic File#

This demo reveals how to conduct a simulation from a historical traffic and shows more ways of defining load effects. Also, it illustrates all the possible outputs that can be requested in a simulation.

The steps are:

Step 1: Read the historical traffic file;

Step 2: Define the bridge and load effects;

Step 3: Request the outputs;

Step 4: Set and start a new simulation task;

Step 5: Load the outputs.

The generated 1-month traffic from the last Comprehensive Traffic Generation Example is used in this demo.


Import all the necessary modules.

[1]:
import pybtls as pb
from pathlib import Path

Step 1: Read the historical traffic file.

From the last example, the generated traffic file is saved as ./temp/sim_gen_example/output_traffic.txt.

[2]:
traffic_file_path = Path("./temp/sim_gen_example/output_traffic.txt")

traffic_loader = pb.TrafficLoader(no_lane = 4)
traffic_loader.add_traffic(
    traffic = traffic_file_path,
    traffic_format = 4,
)

Step 2: Define the bridge and load effects.

The bridge is:

  • Simply supported;

  • four 3.5m-width uni-directional lanes;

  • 20m span length;

  • 16m width.

We are still interested in its mid-span bending moment, but this time the same load effect is defined in three different ways:

  • Built-in influence line function (same as the last example);

  • User-defined discrete influence line;

  • User-defined influence surface.

[ ]:
inf_line_built_in = pb.InfluenceLine(IL_type = "built-in")
inf_line_built_in.set_IL(  # Read the documentation for other built-in ILs
    id = 1,  # Simply supported beam mid-span bending moment
    length = 20.0,
)

inf_line_discrete = pb.InfluenceLine(IL_type = "discrete")
inf_line_discrete.set_IL(
    position = [0.0, 10.0, 20.0],  # x-coordinates along the bridge length
    ordinate = [0.0, 5.0, 0.0],  # influence line values at the corresponding positions
)

lanes_position = [  # In transverse direction
    (0.5, 4.0),
    (4.0, 7.5),
    (8.5, 12.0),
    (12.0, 15.5),
]
inf_surf_matrix = [  # Refer to the Manual for more details about the matrix format
    [0.0, 0.0, 4.0, 8.0, 12.0, 16.0],  # The transverse position of the IS data points
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],  # The values of the IS at the left end of the bridge
    [10.0, 5.0, 5.0, 5.0, 5.0, 5.0],  # The values of the IS at the mid-span of the bridge
    [20.0, 0.0, 0.0, 0.0, 0.0, 0.0],  # The values of the IS at the right end of the bridge
]
inf_surf = pb.InfluenceSurface()
inf_surf.set_IS(inf_surf_matrix, lanes_position)

bridge = pb.Bridge(length = 20.0, no_lane = 4)
bridge.add_load_effect(inf_line_surf = inf_line_built_in)
bridge.add_load_effect(inf_line_surf = inf_line_discrete)
bridge.add_load_effect(inf_line_surf = inf_surf)

Step 3: Request the outputs.

Here we want to have all possible outputs.

[ ]:
output_config = pb.OutputConfig()
output_config.set_event_output(  # Time history and each event output
    write_time_history = True,
    write_each_event = True
)
output_config.set_vehicle_file_output(  # Traffic output, this output_traffic.txt will be the same as the input traffic file
    write_vehicle_file = True,
    vehicle_file_format = 4,
    vehicle_file_name = "output_traffic.txt",
)
output_config.set_stats_output(  # Some statistics for the traffic flow and events
    write_flow_stats = True,
    write_overall = True,
    write_intervals = True,
)
output_config.set_BM_output(  # Block-maximum
    write_vehicle = True,
    write_mixed = True,
    write_summary = True,
)
output_config.set_POT_output(  # Peak-over-threshold
    write_vehicle = True,
    write_counter = True,
    write_summary = True,
)
output_config.set_fatigue_output(  # Fatigue event and rainflow counting
    write_fatigue_event = True,
    write_rainflow_output = True,
)

Step 4: Set and start a new simulation task.

[ ]:
sim_task = pb.Simulation(output_dir = Path("./temp"))  # Can specify a different output directory here.
sim_task.add_sim(
    bridge = bridge,
    traffic = traffic_loader,
    output_config = output_config,
    tag = "sim_read_example",
)
sim_task.run()

Step 5: Load the outputs.

Here we show a complete list of outputs that can be obtained in a simulation. Note that this is not necessary in a real application, and users can choose the outputs they need.

[ ]:
sim_output = sim_task.get_output()["sim_read_example"]

# Time history and each event data
time_history_data = sim_output.read_data("time_history")["TH_20"]
all_event_data = sim_output.read_data("all_events")["BL_20_AllEvents"]

# Traffic output
generated_traffic = sim_output.read_data("traffic")["output_traffic"]

# Statistics data
traffic_stats = sim_output.read_data("traffic_statistics")
flow_stats_lane1 = traffic_stats["FlowData_1_1"]
flow_stats_lane2 = traffic_stats["FlowData_1_2"]
flow_stats_lane3 = traffic_stats["FlowData_1_3"]
flow_stats_lane4 = traffic_stats["FlowData_1_4"]

event_stats_overall = sim_output.read_data("E_cumulative_statistics")["SS_C_20"]

event_stats = sim_output.read_data("E_interval_statistics")
event_stats_interval_LE1 = event_stats["SS_S_20_Eff_1"]
event_stats_interval_LE2 = event_stats["SS_S_20_Eff_2"]
event_stats_interval_LE3 = event_stats["SS_S_20_Eff_3"]

# Block-maximum data
BM_by_trucks = sim_output.read_data("BM_by_no_trucks")
BM_1_truck_data = BM_by_trucks["BM_V_20_1"]  # 1-truck events
BM_2_truck_data = BM_by_trucks["BM_V_20_2"]  # 2-truck events
BM_3_truck_data = BM_by_trucks["BM_V_20_3"]  # 3-truck events
BM_4_truck_data = BM_by_trucks["BM_V_20_4"]  # 4-truck events
BM_5_truck_data = BM_by_trucks["BM_V_20_5"]  # 5-truck events

BM_mixed_truck_data = sim_output.read_data("BM_by_mixed")["BM_V_20_All"]  # Mixed number of truck events

BM_summary = sim_output.read_data("BM_summary")
BM_summary_data_LE1 = BM_summary["BM_S_20_Eff_1"]
BM_summary_data_LE2 = BM_summary["BM_S_20_Eff_2"]
BM_summary_data_LE3 = BM_summary["BM_S_20_Eff_3"]

# Peak-over-threshold data
POT_vehicle = sim_output.read_data("POT_vehicle")
POT_vehicle_data_LE1 = POT_vehicle["PT_V_20_1"]
POT_vehicle_data_LE2 = POT_vehicle["PT_V_20_2"]
POT_vehicle_data_LE3 = POT_vehicle["PT_V_20_3"]

POT_counter_data = sim_output.read_data("POT_counter")["PT_C_20"]

POT_summary = sim_output.read_data("POT_summary")
POT_summary_data_LE1 = POT_summary["PT_S_20_Eff_1"]
POT_summary_data_LE2 = POT_summary["PT_S_20_Eff_2"]
POT_summary_data_LE3 = POT_summary["PT_S_20_Eff_3"]

# Fatigue event and rainflow counting data
fatigue_event_data = sim_output.read_data("fatigue_events")["BL_20_Fatigue"]

rainflow_counting = sim_output.read_data("fatigue_rainflow")
rainflow_counting_data_LE1 = rainflow_counting["FR_20_1"]
rainflow_counting_data_LE2 = rainflow_counting["FR_20_2"]
rainflow_counting_data_LE3 = rainflow_counting["FR_20_3"]