def test_to_wheel_track_loads(): # As Truck 1 enters the bridge, total load is less than Truck 1. enter_times = np.linspace(entering_time, entered_time - 0.001, 100) for time in enter_times: loads = truck1.to_wheel_track_loads(c=c, time=time) flat_loads = flatten(loads, PointLoad) total_kn = sum(map(lambda l: l.load, flat_loads)) assert total_kn < truck1.total_kn() # As Truck 1 is fully on the bridge, total load equals that of Truck 1. on_times = np.linspace(entered_time, leaving_time, 100) truck_front_x = np.arange(8, 102) more_times = np.array( [truck1.time_at(x=x, bridge=c.bridge) for x in truck_front_x]) on_times = np.concatenate((on_times, more_times)) for time in on_times: loads = truck1.to_wheel_track_loads(c=c, time=time) flat_loads = flatten(loads, PointLoad) total_kn = sum(map(lambda l: l.load, flat_loads)) assert np.isclose(total_kn, truck1.total_kn()) # As Truck 1 is leaving the bridge, total load is less than Truck 1. leave_times = np.linspace(leaving_time + 0.001, left_time, 100) for time in leave_times: loads = truck1.to_wheel_track_loads(c=c, time=time) flat_loads = flatten(loads, PointLoad) total_kn = sum(map(lambda l: l.load, flat_loads)) assert total_kn < truck1.total_kn()
def truck_1_loads(x: float): config = c() time = truck1.time_at(x=x, bridge=config.bridge) print_i(f"Time = {time:.4f}s") axle_loads = truck1.to_point_loads(time=time, bridge=config.bridge) for i in range(len(axle_loads)): print_i( f"Axle {i}: ({axle_loads[i][0].repr(config.bridge)}), " f" ({axle_loads[i][1].repr(config.bridge)})" )
def test_compare_to_wheel_track_and_to_point_load(): truck_front_x = np.arange(1, 116.1, 1) times = [truck1.time_at(x=x, bridge=c.bridge) for x in truck_front_x] loads_wt = [[v.to_wheel_track_loads(c=c, time=time) for v in [truck1]] for time in times] # print_w(f"Not using fractions of wheel track bins in simulation") loads_pw = [[ v.to_point_load_pw(time=time, bridge=c.bridge) for v in [truck1] ] for time in times] def sum_loads(loads): """Sum of the load intensity (kn) of all given loads.""" return sum(map(lambda l: l.load, flatten(loads, PointLoad))) for i in range(len(times)): # Assert that the total load intensity is equal for both functions. wt, pw = np.array(loads_wt[i]), np.array(loads_pw[i]) sum_wt = np.around(sum_loads(wt), 5) sum_pw = np.around(sum_loads(pw), 5) assert sum_wt == sum_pw # Assert the shape of fem is as expected. assert wt.shape[0] == 1 # One vehicles. assert pw.shape[0] == 1 # One vehicles. # Assert that both loads have equal amount of axles. assert wt.shape[1] == pw.shape[1] # Assert that at each time, the shape of loads is as expected. if wt.shape[1] >= 1: assert len(wt.shape) >= 3 assert len(pw.shape) == 3 assert wt.shape[2] == 2 assert pw.shape[2] == 2 if len(wt.shape) == 4: assert wt.shape[3] == 2 # Assert that x positions of loads match up. for axle_i in range(wt.shape[1]): for wt_load, pw_load in zip(wt[0][axle_i], pw[0][axle_i]): # Total kn should be equal between both functions.. wt_kn = sum_loads(wt_load) assert np.isclose(wt_kn, pw_load.load) # ..x positions should match up too. if len(wt_load) == 1: assert np.isclose(wt_load[0].x, pw_load.x) elif len(wt_load) == 2: assert wt_load[0].x < pw_load.x < wt_load[1].x else: assert False
def cover_photo(c: Config, x: float, deformation_amp: float): """ TODO: SimParams takes any loads iterable, to be flattened. TODO: Wrap SimRunner into Config. TODO: Ignore response type in SimParams (fill in by load_sim_responses). """ response_type = ResponseType.YTranslation sim_responses = load_fem_responses( c=c, sim_runner=OSRunner(c), response_type=response_type, sim_params=SimParams( response_types=[response_type], ploads=list( chain.from_iterable( truck1.to_point_loads( bridge=c.bridge, time=truck1.time_at(x=x, bridge=c.bridge), ))), ), ) shells = contour_responses_3d(c=c, sim_responses=sim_responses) for cmap in [ parula_cmap, get_cmap("jet"), get_cmap("coolwarm"), get_cmap("viridis"), ]: contour_responses_3d( c=c, sim_responses=sim_responses, deformation_amp=deformation_amp, shells=shells, cmap=cmap, ) plt.axis("off") plt.grid(False) plt.savefig( c.get_image_path( "cover-photo", f"cover-photo-deform-{deformation_amp}" f"-cmap-{cmap.name}.pdf", )) plt.close()
def number_of_uls_plot(c: Config): """Plot error as a function of number of unit load simulations.""" if not c.shorten_paths: raise ValueError("This plot requires --shorten-paths true") response_type = ResponseType.YTranslation num_ulss = np.arange(100, 2000, 10) chosen_uls = 600 point = Point(x=c.bridge.x_max - (c.bridge.length / 2), y=0, z=-8.4) wagen1_time = truck1.time_at(x=point.x, bridge=c.bridge) print_i(f"Wagen 1 time at x = {point.x:.3f} is t = {wagen1_time:.3f}") # Determine the reference value. truck_loads = flatten( truck1.to_point_load_pw(time=wagen1_time, bridge=c.bridge), PointLoad) print_i(f"Truck loads = {truck_loads}") sim_responses = load_fem_responses( c=c, response_type=response_type, sim_runner=OSRunner(c), sim_params=SimParams(ploads=truck_loads, response_types=[response_type]), ) ref_value = sim_responses.at_deck(point, interp=True) * 1000 print_i(f"Reference value = {ref_value}") # Collect the data. total_load = [] num_loads = [] responses = [] for num_uls in num_ulss: c.il_num_loads = num_uls # Nested in here because it depends on the setting of 'il_num_loads'. truck_loads = flatten( truck1.to_wheel_track_loads(c=c, time=wagen1_time), PointLoad) num_loads.append(len(truck_loads)) total_load.append(sum(map(lambda l: l.kn, truck_loads))) sim_responses = load_fem_responses( c=c, response_type=response_type, sim_runner=OSRunner(c), sim_params=SimParams(ploads=truck_loads, response_types=[response_type]), ) responses.append(sim_responses.at_deck(point, interp=True) * 1000) # Plot the raw fem, then error on the second axis. plt.landscape() # plt.plot(num_ulss, fem) # plt.ylabel(f"{response_type.name().lower()} (mm)") plt.xlabel("ULS") error = np.abs(np.array(responses) - ref_value).flatten() * 100 # ax2 = plt.twinx() plt.plot(num_ulss, error) plt.ylabel("Error (%)") plt.title( f"Error in {response_type.name()} to Truck 1 as a function of ULS") # Plot the chosen number of ULS. chosen_error = np.interp([chosen_uls], num_ulss, error)[0] plt.axhline( chosen_error, label=f"At {chosen_uls} ULS, error = {np.around(chosen_error, 2)} %", color="black", ) plt.axhline(0, color="red", label="Response from direct simulation (no wheel tracks)") plt.legend() plt.tight_layout() plt.savefig(c.get_image_path("paramselection", "uls.pdf")) plt.close() # Additional verification plots. plt.plot(num_ulss, total_load) plt.savefig(c.get_image_path("paramselection", "uls-verify-total-load.pdf")) plt.close() plt.plot(num_ulss, num_loads) plt.savefig(c.get_image_path("paramselection", "uls-verify-num-loads.pdf")) plt.close()