예제 #1
0
def make_node_plots(original_c: Config):
    """Make all variations of 3d scatter plots of nodes."""
    for damage_scenario in healthy_and_cracked_scenarios:
        c, sim_params = damage_scenario.use(original_c, SimParams([]))
        for ctx, ctx_name in [
            (BuildContext(add_loads=[Point(x=85, y=0, z=0)]), "refined"),
            (None, "unrefined"),
        ]:
            bridge_nodes = get_bridge_nodes(bridge=c.bridge, ctx=ctx)
            deck_nodes = set(flatten(bridge_nodes[0], Node))
            pier_nodes = set(flatten(bridge_nodes[1], Node))
            all_nodes = set(flatten(bridge_nodes, Node))
            # For each combination of parameters plot the nodes.
            for nodes_name, nodes in [
                ("all", all_nodes),
                ("deck", deck_nodes),
                ("pier", pier_nodes),
            ]:
                node_scatter_3d(nodes=nodes)
                plt.title(f"Nodes of {c.bridge.name}")
                plt.savefig(
                    c.get_image_path(
                        f"geometry/nodes-{ctx_name}",
                        safe_str(f"{nodes_name}") + ".pdf",
                    ))
                plt.close()
예제 #2
0
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()
예제 #3
0
def test_loads_to_traffic_array():
    # First with one point load per wheel.
    wagen1_loads = [
        flatten(truck1.to_point_load_pw(time=time, bridge=c.bridge), PointLoad)
        for time in np.linspace(entered_time, leaving_time, 1000)
    ]
    for row in loads_to_traffic_array(c=c, loads=wagen1_loads):
        assert sum(row) == truck1.total_kn()
    # Then with point loads based on wheel tracks.
    wagen1_loads = [
        flatten(truck1.to_wheel_track_loads(c=c, time=time), PointLoad)
        for time in np.linspace(entered_time, leaving_time, 1000)
    ]
    for row in loads_to_traffic_array(c=c, loads=wagen1_loads):
        assert np.isclose(sum(row), truck1.total_kn())
예제 #4
0
 def to_point_load_pw(
     self, time: float, bridge: Bridge, list: bool = False
 ) -> Union[List[Tuple[PointLoad, PointLoad]], List[PointLoad]]:
     """A tuple of point load per axle, one point load per wheel."""
     z0, z1 = self.wheel_tracks_zs(bridge=bridge, meters=True)
     assert z0 < z1
     kn_per_axle = self.kn_per_axle()
     result = []
     # For each axle.
     for x_i, x in enumerate(self.xs_at(time=time, bridge=bridge)):
         # Skip axle if not on the bridge.
         if (x < bridge.x_min and not np.isclose(x, bridge.x_min)) or (
             x > bridge.x_max and not np.isclose(x, bridge.x_max)
         ):
             continue
         # Two wheel load intensities.
         kn_wheel = kn_per_axle[x_i] / 2
         result.append(
             (
                 PointLoad(x=x, z=z0, load=kn_wheel),
                 PointLoad(x=x, z=z1, load=kn_wheel),
             )
         )
     if list:
         return flatten(result, PointLoad)
     return result
예제 #5
0
def compare_load_positions(c: Config):
    """Compare load positions (normal vs. buckets)."""
    c.il_num_loads = 10
    num_times = 1000

    # Wagen 1 from the experimental campaign.
    point = Point(x=c.bridge.x_max / 2, y=0, z=-8.4)
    end_time = uni_axle_vehicle.time_left_bridge(bridge=c.bridge)
    vehicle_times = list(np.linspace(0, end_time, num_times))
    plt.portrait()

    pw_loads = [
        flatten(uni_axle_vehicle.to_point_load_pw(time=time, bridge=c.bridge),
                PointLoad) for time in vehicle_times
    ]
    pw_load_xs = [[c.bridge.x(l.x_frac) for l in pw_loads[time_ind]]
                  for time_ind in range(len(pw_loads))]
    plt.subplot(3, 1, 1)
    # for l in pw_load_xs:
    #     print(l)
    plt.plot([l[0] for l in pw_load_xs])
    plt.plot([l[1] for l in pw_load_xs])

    wt_loads = [
        flatten(uni_axle_vehicle.to_wheel_track_loads(c=c, time=time),
                PointLoad) for time in vehicle_times
    ]
    wt_load_xs = [[c.bridge.x(l.x_frac) for l in wt_loads[time_ind]]
                  for time_ind in range(len(wt_loads))]
    plt.subplot(3, 1, 2)
    plt.scatter(vehicle_times, [l[0] for l in wt_load_xs], label="0")
    plt.scatter(vehicle_times, [l[1] for l in wt_load_xs], label="1")
    plt.legend()

    wt_load_kn = [[l.kn for l in wt_loads[time_ind]]
                  for time_ind in range(len(wt_loads))]
    plt.subplot(3, 1, 3)
    for l in wt_load_kn:
        print(l)
    plt.scatter(vehicle_times, [l[0] for l in wt_load_kn], label="0")
    plt.scatter(vehicle_times, [l[1] for l in wt_load_kn], label="1")
    plt.legend()

    plt.tight_layout()
    plt.savefig(c.get_image_path("verification", "compare-load-positions.pdf"))
    plt.close()
예제 #6
0
def make_shell_properties_3d(original_c: Config):
    """Make plots of the shells in 3D, coloured by material property."""
    # For each scenarios scenario build the model and extract the shells.
    for damage_scenario in healthy_and_cracked_scenarios:
        c, sim_params = damage_scenario.use(original_c, SimParams([]))
        for ctx, ctx_name in [
            (BuildContext(add_loads=[Point(x=85, y=0, z=0)]), "refined"),
            (None, "unrefined"),
        ]:
            bridge_shells = get_bridge_shells(bridge=c.bridge, ctx=ctx)
            deck_shells = flatten(bridge_shells[0], Shell)
            pier_shells = flatten(bridge_shells[1], Shell)
            all_shells = flatten(bridge_shells, Shell)
            # For each combination of parameters plot the shells.
            for shells_name, shells in [
                ("pier", pier_shells),
                ("all", all_shells),
                ("deck", deck_shells),
            ]:
                for outline, label in itertools.product([True, False],
                                                        [True, False]):
                    for prop_name, prop_units, prop_f in [
                        ("Thickness", "m", lambda s: s.thickness),
                        ("Density", "kg/m", lambda s: s.density),
                        ("Poisson's ratio", "m/m", lambda s: s.poissons),
                        ("Young's modulus", "MPa", lambda s: s.youngs),
                    ]:
                        for cmap in [default_cmap, get_cmap("tab10")]:
                            shell_properties_3d(
                                shells=shells,
                                prop_units=prop_units,
                                prop_f=prop_f,
                                cmap=cmap,
                                outline=outline,
                                label=label,
                                colorbar=not label,
                            )
                            plt.title(f"{prop_name} of {c.bridge.name}")
                            plt.savefig(
                                c.get_image_path(
                                    f"geometry/shells-{ctx_name}-3d",
                                    safe_str(
                                        f"{shells_name}-{prop_name}-outline-{outline}-{cmap.name}"
                                    ) + ".pdf",
                                ))
                            plt.close()
예제 #7
0
def test_to_point_load_pw():
    # As Truck 1 enters the bridge.
    wagen1_times = np.linspace(entering_time, entered_time - 0.001, 100)
    for time in wagen1_times:
        loads = truck1.to_point_load_pw(time=time, bridge=c.bridge)
        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.
    wagen1_times = np.linspace(entered_time, leaving_time, 100)
    for time in wagen1_times:
        loads = truck1.to_point_load_pw(time=time, bridge=c.bridge)
        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 leaving the bridge.
    wagen1_times = np.linspace(leaving_time + 0.001, left_time, 100)
    for time in wagen1_times:
        loads = truck1.to_point_load_pw(time=time, bridge=c.bridge)
        flat_loads = flatten(loads, PointLoad)
        total_kn = sum(map(lambda l: l.load, flat_loads))
        assert total_kn < truck1.total_kn()
예제 #8
0
 def to_wheel_track_loads(
     self, c: "Config", time: float, flat: bool = False
 ) -> List[Tuple[List[PointLoad], List[PointLoad]]]:
     z0, z1 = self.wheel_tracks_zs(bridge=c.bridge, meters=True)
     assert z0 < z1
     result = []
     for axle_loads in self.to_wheel_track_loads_(c=c, time=time):
         left, right = [], []
         left_loads, right_loads = axle_loads
         for load_x, load_kn in left_loads:
             left.append(PointLoad(x=load_x, z=z0, load=load_kn))
         for load_x, load_kn in right_loads:
             right.append(PointLoad(x=load_x, z=z1, load=load_kn))
         result.append((left, right))
     if flat:
         return flatten(result, PointLoad)
     return result
예제 #9
0
 def to_wheel_track_loads_(
     self,
     c: "Config",
     time: float,
     flat: bool = False,
     wheel_track_xs: Optional[List[float]] = None,
 ):
     """Load intensities and positions per axle, per wheel.
     "Bucketed" to fit onto wheel tracks.
     NOTE: In each tuple of two point loads, one tuple per wheel, each point
     load is for a unit load position in the wheel track. Each point load is
     weighted by the distance to the unit load.
     """
     if wheel_track_xs is None:
         wheel_track_xs = c.bridge.wheel_track_xs(c)
     xs = self.xs_at(time=time, bridge=c.bridge)
     kns = self.kn_per_axle()
     result = []
     assert len(xs) == len(kns)
     # For each axle.
     for x, kn in zip(xs, kns):
         # Skip axle if not on the bridge.
         if (x < c.bridge.x_min and not np.isclose(x, c.bridge.x_min)) or (
             x > c.bridge.x_max and not np.isclose(x, c.bridge.x_max)
         ):
             continue
         left, right = [], []
         for (load_x, load_frac) in self.to_wheel_track_xs(
             c=c, wheel_x=x, wheel_track_xs=wheel_track_xs,
         ):
             if load_frac > 0:
                 bucket_kn = kn / 2 * load_frac
                 left.append((load_x, bucket_kn))
                 right.append((load_x, bucket_kn))
         result.append((left, right))
     if flat:
         return flatten(result, PointLoad)
     return result
예제 #10
0
def responses_to_vehicles_d(
        c: Config,
        response_type: ResponseType,
        points: List[Point],
        mv_vehicles: List[Vehicle],
        times: List[float],
        binned: bool = True,
        damage_scenario: Scenario = HealthyScenario(),
):
    """Response vehicles via direct simulation (not using superposition).

    """
    if not isinstance(damage_scenario, HealthyScenario):
        raise ValueError("Only HealthyDamage supported in direct simulation")
    if binned:
        loads = [[v.to_wheel_track_loads(c=c, time=time) for v in mv_vehicles]
                 for time in times]
    else:
        print_w(f"Not using fractions of wheel track bins in simulation")
        loads = [[
            v.to_point_load_pw(time=time, bridge=c.bridge) for v in mv_vehicles
        ] for time in times]
    loads = [flatten(vehicle_loads, PointLoad) for vehicle_loads in loads]
    print([len(load_) for load_ in loads])
    print(loads[0])
    print(loads[-1])
    assert isinstance(loads, list)
    assert isinstance(loads[0], list)
    assert isinstance(loads[0][0], PointLoad)
    return responses_to_loads_d(
        c=c,
        response_type=response_type,
        points=points,
        loads=loads,
        damage_scenario=damage_scenario,
    )
예제 #11
0
def top_view_plot(c: Config, max_time: int, skip: int, damage_scenario):
    response_type = ResponseType.YTranslation
    # Create the traffic.
    traffic_scenario = normal_traffic(c=c, lam=5, min_d=2)
    traffic_sequence, traffic, traffic_array = load_traffic(
        c=c,
        traffic_scenario=traffic_scenario,
        max_time=max_time,
    )
    assert len(traffic) == traffic_array.shape[0]
    # Points on the deck to collect fem.
    deck_points = [
        Point(x=x, y=0, z=z) for x in np.linspace(
            c.bridge.x_min, c.bridge.x_max, num=int(c.bridge.length * 2))
        for z in np.linspace(
            c.bridge.z_min, c.bridge.z_max, num=int(c.bridge.width * 2))
        # for x in np.linspace(c.bridge.x_min, c.bridge.x_max, num=30)
        # for z in np.linspace(c.bridge.z_min, c.bridge.z_max, num=10)
    ]
    point = Point(x=21, y=0, z=-8.4)  # Point to plot
    deck_points.append(point)
    # Traffic array to fem array.
    responses_array = responses_to_traffic_array(
        c=c,
        traffic_array=traffic_array,
        damage_scenario=damage_scenario,
        points=deck_points,
        response_type=response_type,
    )
    # Temperature effect July 1st.
    temps_2019 = temperature.load("holly-springs")
    temps_2019["temp"] = temperature.resize(temps_2019["temp"])
    effect_2019 = temperature.effect(
        c=c,
        response_type=response_type,
        points=deck_points,
        temps=temps_2019["temp"],
        solar=temps_2019["solar"],
        len_per_hour=60,
    ).T
    # The effect is ordered by time series and then by points. (104910, 301)
    assert len(effect_2019) == len(temps_2019)
    july_2019_i, july_2019_j = temperature.from_to_indices(
        temps_2019,
        datetime.fromisoformat(f"2019-10-01T00:00"),
        datetime.fromisoformat(f"2019-10-01T23:59"),
    )
    temp_effect = []
    for i in range(len(deck_points)):
        temp_effect.append(
            temperature.apply(
                # Effect for July 1st, for the current point..
                effect=effect_2019.T[i][july_2019_i:july_2019_j],
                # ..for the length of the time series.
                responses=responses_array,
            ))
    temp_effect = np.array(temp_effect)
    plt.subplot(2, 1, 1)
    plt.plot(effect_2019.T[-1])
    plt.subplot(2, 1, 2)
    plt.plot(temp_effect[-1])
    plt.show()
    # Determine response due to pier settlement.
    pd_response_at_point = 0
    if isinstance(damage_scenario, PierDispDamage):
        pd_expt = list(
            DCMatrix.load(c=c,
                          response_type=response_type,
                          fem_runner=OSRunner(c)))
        for pier_displacement in damage_scenario.pier_disps:
            pd_sim_responses = pd_expt[pier_displacement.pier]
            pd_response_at_point += pd_sim_responses.at_deck(
                point, interp=False) * (pier_displacement.displacement /
                                        c.pd_unit_disp)
    # Resize fem if applicable to response type.
    resize_f, units = resize_units(response_type.units())
    if resize_f is not None:
        responses_array = resize_f(responses_array)
        temp_effect = resize_f(temp_effect.T).T
        print(np.mean(temp_effect[-1]))
        pd_response_at_point = resize_f(pd_response_at_point)
    responses_w_temp = responses_array + temp_effect.T
    # Determine levels of the colourbar.
    amin, amax = np.amin(responses_array), np.amax(responses_array)
    # amin, amax = min(amin, -amax), max(-amin, amax)
    levels = np.linspace(amin, amax, 25)
    # All vehicles, for colour reference.
    all_vehicles = flatten(traffic, Vehicle)
    # Iterate through each time index and plot results.
    warmed_up_at = traffic_sequence[0][0].time_left_bridge(c.bridge)
    # Plot for each time step.
    for t_ind in range(len(responses_array))[::skip]:
        plt.landscape()
        # Plot the bridge top view.
        plt.subplot2grid((3, 1), (0, 0), rowspan=2)
        top_view_bridge(c.bridge, compass=False, lane_fill=False, piers=True)
        top_view_vehicles(
            bridge=c.bridge,
            mv_vehicles=flatten(traffic[t_ind], Vehicle),
            time=warmed_up_at + t_ind * c.sensor_hz,
            all_vehicles=all_vehicles,
        )
        responses = Responses(
            response_type=response_type,
            responses=[(responses_array[t_ind][p_ind], deck_points[p_ind])
                       for p_ind in range(len(deck_points))],
            units=units,
        )
        plot_contour_deck(c=c,
                          responses=responses,
                          levels=levels,
                          mm_legend=False)
        plt.scatter(
            [point.x],
            [point.z],
            label=f"Sensor in bottom plot",
            marker="o",
            color="red",
            zorder=10,
        )
        plt.legend(loc="upper right")
        plt.title(
            f"{response_type.name()} after {np.around(t_ind * c.sensor_hz, 4)} seconds"
        )
        # Plot the fem at a point.
        plt.subplot2grid((3, 1), (2, 0))
        time = t_ind * c.sensor_hz
        plt.axvline(x=time,
                    color="black",
                    label=f"Current time = {np.around(time, 4)} s")
        plt.plot(
            np.arange(len(responses_array)) * c.sensor_hz,
            responses_w_temp.T[-1],
            color="red",
            label="Total effect",
        )
        if isinstance(damage_scenario, PierDispDamage):
            plt.plot(
                np.arange(len(responses_array)) * c.sensor_hz,
                np.ones(temp_effect[-1].shape) * pd_response_at_point,
                color="green",
                label="Pier settlement effect",
            )
        plt.plot(
            np.arange(len(responses_array)) * c.sensor_hz,
            temp_effect[-1],
            color="blue",
            label="Temperature effect",
        )
        plt.ylabel(f"{response_type.name()} ({responses.units})")
        plt.xlabel("Time (s)")
        plt.title(f"{response_type.name()} at sensor in top plot")
        plt.legend(loc="upper right", framealpha=1)
        # Finally save the image.
        name = f"{damage_scenario.name}-{response_type.name()}-{t_ind}"
        plt.tight_layout()
        plt.savefig(c.get_image_path("classify/top-view", f"{name}.pdf"))
        plt.savefig(c.get_image_path("classify/top-view/png", f"{name}.png"))
        plt.close()
예제 #12
0
def compare_responses(c: Config):
    """Compare fem to Truck 1, direct simulation and matmul."""
    assert c.il_num_loads == 600
    num_times = 50
    close_times = 200
    # Running time:
    # responses_to_vehicles_d: num_times * 8
    # responses_to_vehicles_d: 4 * il_num_loads
    # responses_to_loads_m: 0 (4 * il_num_loads)
    # responses_to_loads_m: 0 (4 * il_num_loads)
    # Wagen 1 from the experimental campaign.

    point = Point(x=c.bridge.x_max - (c.bridge.length / 2), y=0, z=-8.4)
    end_time = wagen1.time_left_bridge(bridge=c.bridge)
    wagen1_times = list(np.linspace(0, end_time, num_times))
    more_wagen1_times = list(
        np.linspace(
            wagen1.time_at(x=point.x - 2, bridge=c.bridge),
            wagen1.time_at(x=point.x + 2, bridge=c.bridge),
            close_times,
        ))
    wagen1_times = sorted(wagen1_times + more_wagen1_times)
    plt.portrait()

    # Start with fem from direct simulation.
    responses_not_binned = responses_to_vehicles_d(
        c=c,
        response_type=ResponseType.YTranslation,
        points=[point],
        mv_vehicles=[wagen1],
        times=wagen1_times,
        sim_runner=OSRunner(c),
        binned=False,
    )
    plt.subplot(4, 1, 1)
    plt.title(f"{len(wagen1_times)} fem")
    plt.plot(wagen1_times, responses_not_binned)

    # Then fem from direct simulation with binning.
    c.shorten_paths = True
    responses_binned = responses_to_vehicles_d(
        c=c,
        response_type=ResponseType.YTranslation,
        points=[point],
        mv_vehicles=[wagen1],
        times=wagen1_times,
        sim_runner=OSRunner(c),
        binned=True,
    )
    c.shorten_paths = False
    plt.subplot(4, 1, 2)
    plt.title(f"{len(wagen1_times)} fem (binned)")
    plt.plot(wagen1_times, responses_binned)
    xlim = plt.xlim()

    num_times = int(end_time / c.sensor_hz)
    wagen1_times = np.linspace(0, end_time, num_times)

    # Then from 'TrafficArray' we get fem, without binning.
    wagen1_loads = [
        flatten(wagen1.to_point_load_pw(time=time, bridge=c.bridge), PointLoad)
        for time in wagen1_times
    ]
    responses_ulm = responses_to_traffic_array(
        c=c,
        traffic_array=loads_to_traffic_array(c=c, loads=wagen1_loads),
        response_type=ResponseType.YTranslation,
        damage_scenario=healthy_scenario,
        points=[point],
        sim_runner=OSRunner(c),
    )
    plt.subplot(4, 1, 3)
    plt.title(f"{num_times} fem with ULS = {c.il_num_loads} traffic_array")
    plt.plot(wagen1_times, np.array(responses_ulm).reshape(-1, 1))
    plt.xlim(xlim)

    # # Then from 'TrafficArray' we get fem, with binning.
    wagen1_loads = [
        flatten(wagen1.to_wheel_track_loads(c=c, time=time), PointLoad)
        for time in wagen1_times
    ]
    responses_ulm_binned = responses_to_traffic_array(
        c=c,
        traffic_array=loads_to_traffic_array(c=c, loads=wagen1_loads),
        response_type=ResponseType.YTranslation,
        damage_scenario=healthy_scenario,
        points=[point],
        sim_runner=OSRunner(c),
    )
    plt.subplot(4, 1, 4)
    plt.title(
        f"{num_times} fem from {c.il_num_loads} il_num_loads\ntraffic_array binned"
    )
    plt.plot(wagen1_times, np.array(responses_ulm_binned).reshape(-1, 1))
    plt.xlim(xlim)

    plt.tight_layout()
    plt.savefig(
        c.get_image_path("system-verification", "compare-time-series.pdf"))
예제 #13
0
def compare_axles(c: Config):
    """Compare fem between uniaxle vehicles and Truck 1."""
    assert c.il_num_loads == 600

    point = Point(x=c.bridge.x_max / 2, y=0, z=-8.4)
    end_time = wagen1.time_left_bridge(bridge=c.bridge)
    num_times = int(end_time / c.sensor_hz)
    wagen1_times = np.linspace(0, end_time, num_times)
    plt.portrait()

    wagen1_loads = [
        flatten(wagen1.to_wheel_track_loads(c=c, time=time), PointLoad)
        for time in wagen1_times
    ]
    responses_ulm = responses_to_traffic_array(
        c=c,
        traffic_array=loads_to_traffic_array(c=c, loads=wagen1_loads),
        response_type=ResponseType.YTranslation,
        damage_scenario=healthy_scenario,
        points=[point],
        sim_runner=OSRunner(c),
    )
    plt.subplot(3, 1, 1)
    plt.title(
        f"{num_times} fem with ULS = {c.il_num_loads} (Wagen 1 (4 axles))")
    plt.plot(wagen1_times, np.array(responses_ulm).reshape(-1, 1))

    bi_axle_loads = [
        flatten(bi_axle_vehicle.to_wheel_track_loads(c=c, time=time),
                PointLoad) for time in wagen1_times
    ]
    responses_ulm = responses_to_traffic_array(
        c=c,
        traffic_array=loads_to_traffic_array(c=c, loads=bi_axle_loads),
        response_type=ResponseType.YTranslation,
        damage_scenario=healthy_scenario,
        points=[point],
        sim_runner=OSRunner(c),
    )
    plt.subplot(3, 1, 2)
    plt.title(f"{num_times} fem with ULS = {c.il_num_loads} (2 axles)")
    plt.plot(wagen1_times, np.array(responses_ulm).reshape(-1, 1))

    uni_axle_loads = [
        flatten(uni_axle_vehicle.to_wheel_track_loads(c=c, time=time),
                PointLoad) for time in wagen1_times
    ]
    responses_ulm = responses_to_traffic_array(
        c=c,
        traffic_array=loads_to_traffic_array(c=c, loads=uni_axle_loads),
        response_type=ResponseType.YTranslation,
        damage_scenario=healthy_scenario,
        points=[point],
        sim_runner=OSRunner(c),
    )
    plt.subplot(3, 1, 3)
    plt.title(f"{num_times} fem with ULS = {c.il_num_loads} (1 axle)")
    plt.plot(wagen1_times, np.array(responses_ulm).reshape(-1, 1))

    plt.tight_layout()
    plt.savefig(c.get_image_path("system-verification", "compare-axles.pdf"))
예제 #14
0
def make_shell_properties_top_view(
    c: Config,
    shells_name_: str,
    prop_name_: str,
    refined_: bool,
    outline: bool,
    lanes: bool,
):
    """Make plots of the shells in top view, coloured by material property."""
    original_c = c
    # For each scenarios scenario build the model and extract the shells.
    for damage_scenario, damage_name in zip(healthy_and_cracked_scenarios,
                                            [None, "cracked"]):
        c, sim_params = damage_scenario.use(original_c)
        for ctx, ctx_name, refined, in [
            (
                BuildContext(
                    add_loads=[Point(x=85, y=0, z=0)],
                    refinement_radii=[2, 1, 0.5],
                ),
                "refined",
                True,
            ),
            (None, "unrefined", False),
        ]:
            if refined != refined_:
                continue
            bridge_shells = get_bridge_shells(bridge=c.bridge, ctx=ctx)
            deck_shells = flatten(bridge_shells[0], Shell)
            pier_shells = flatten(bridge_shells[1], Shell)
            all_shells = pier_shells + deck_shells
            for shells_name, shells in [
                ("piers", pier_shells),
                ("deck", deck_shells),
            ]:
                if shells_name != shells_name_:
                    continue
                for prop_name, prop_units, prop_f in [
                    ("Mesh", "", None),
                    ("Thickness", "m", lambda s: np.around(s.thickness, 3)),
                    ("Density", "kg/m", lambda s: np.around(s.density, 3)),
                    ("Poisson's ratio", "m/m", lambda s: s.poissons),
                    ("Young's modulus", "MPa",
                     lambda s: np.around(s.youngs, 1)),
                ]:
                    if prop_name_ not in prop_name.lower():
                        continue
                    for cmap in [parula_cmap, default_cmap]:

                        def top_view():
                            top_view_bridge(
                                bridge=c.bridge,
                                abutments=True,
                                piers=True,
                                lanes=lanes,
                                compass=prop_f is not None,
                            )

                        top_view()
                        shell_properties_top_view(
                            shells=shells,
                            prop_f=prop_f,
                            prop_units=prop_units,
                            cmap=cmap,
                            colorbar=prop_f is not None,
                            # label=prop_f is not None,
                            outline=outline,
                        )
                        top_view()
                        damage_str = "" if damage_name is None else f" ({damage_name})"
                        plt.title(
                            f"{prop_name} of bridge 705's {shells_name}{damage_str}"
                        )
                        plt.savefig(
                            c.get_image_path(
                                f"geometry/{shells_name}-shells-{ctx_name}-top-view",
                                safe_str(
                                    f"{prop_name}-{cmap.name}-outline-{outline}-lanes-{lanes}"
                                ) + ".pdf",
                            ))
                        plt.close()
                        if prop_f is None:
                            break
예제 #15
0
 def sum_loads(loads):
     """Sum of the load intensity (kn) of all given loads."""
     return sum(map(lambda l: l.load, flatten(loads, PointLoad)))
예제 #16
0
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()
예제 #17
0
def truck_1_time_series(c: Config):
    """Time series of 3 sensors to Truck 1's movement."""
    side_s = 7
    side = int(side_s * (1 / c.sensor_hz))
    assert wagen1.x_at(time=0, bridge=c.bridge) == 0
    # Get times and loads for Truck 1.
    end_time = wagen1.time_left_bridge(c.bridge)
    wagen1_times = np.linspace(-end_time, end_time * 2,
                               int((end_time * 3) / c.sensor_hz))
    print_i("Calculating Truck 1 loads")
    wagen1_loads = [
        flatten(wagen1.to_wheel_track_loads(c=c, time=time), PointLoad)
        # flatten(wagen1.to_point_load_pw(time=time, bridge=c.bridge), PointLoad)
        for time in wagen1_times
    ]
    print_i("Calculated Truck 1 loads")

    def set_labels(ylabel: str, xlabel: str):
        for i, y, x in [
            (1, True, False),
            (2, False, False),
            (3, True, False),
            (4, False, False),
            (5, True, True),
            (6, False, True),
        ]:
            plt.subplot(3, 2, i)
            ax = plt.gca()
            if y:
                plt.ylabel(ylabel)
            else:
                ax.axes.yaxis.set_ticklabels([])
            if x:
                plt.xlabel(xlabel)
            ax.axes.xaxis.set_ticklabels([])
        ymin, ymax = np.inf, -np.inf
        for i in range(1, 6 + 1):
            plt.subplot(3, 2, i)
            ymin = min(ymin, plt.ylim()[0])
            ymax = max(ymax, plt.ylim()[1])
        for i in range(1, 6 + 1):
            plt.subplot(3, 2, i)
            plt.ylim((ymin, ymax))

    ################
    # Vert. trans. #
    ################

    plt.portrait()
    # Find points of each sensor.
    displa_labels = ["U13", "U26", "U29"]
    displa_points = [
        Point(x=sensor_x, y=0, z=sensor_z) for sensor_x, sensor_z in
        [displa_sensor_xz(displa_label) for displa_label in displa_labels]
    ]
    # Ensure points and truck are on the same lane.
    assert all(p.z < 0 for p in displa_points)
    # Results from simulation.
    responses_truck1 = responses_to_traffic_array(
        c=c,
        traffic_array=loads_to_traffic_array(c=c, loads=wagen1_loads),
        response_type=ResponseType.YTranslation,
        damage_scenario=healthy_scenario,
        points=displa_points,
    ).T
    for s_i, sensor_responses in enumerate(responses_truck1):
        plt.subplot(len(displa_points), 2, (s_i * 2) + 1)
        # Find the center of the plot, minimum point in the data.
        data_center = 0
        for i in range(len(sensor_responses)):
            if sensor_responses[i] < sensor_responses[data_center]:
                data_center = i
        # sensor_responses = add_displa_noise(sensor_responses) * 1000
        sensor_responses = sensor_responses * 1000
        plt.plot(sensor_responses[data_center - side:data_center + side])
        plt.title(f"{displa_labels[s_i]} in simulation")
    # Results from experiment.
    side = int(side / ((1 / c.sensor_hz) / 100))
    print_i(f"{side} points each side of center")
    for s_i, displa_label in enumerate(displa_labels):
        plt.subplot(len(displa_points), 2, (s_i * 2) + 2)
        with open(f"validation/experiment/D1a-{displa_label}.txt") as f:
            data = list(map(float, f.readlines()))
        side_expt = int(side_s * (len(data) / 240))
        # Find the center of the plot, minimum point in first 15000 points.
        data_center = 0
        for i in range(15000):
            if data[i] < data[data_center]:
                data_center = i
        plt.plot(data[data_center - side_expt:data_center + side_expt])
        plt.title(f"{displa_label} in dynamic test")
    set_labels("Y translation (mm)", "Time")
    plt.tight_layout()
    plt.savefig(
        c.get_image_path("validation/truck-1", "time-series-vert-trans.pdf"))
    plt.close()

    ##########
    # Strain #
    ##########

    plt.portrait()
    # Find points of each sensor.
    strain_labels = ["T1", "T10", "T11"]
    strain_points = [
        Point(x=sensor_x, y=0, z=sensor_z) for sensor_x, sensor_z in
        [strain_sensor_xz(strain_label) for strain_label in strain_labels]
    ]
    # Results from simulation.
    responses_truck1 = responses_to_traffic_array(
        c=c,
        traffic_array=loads_to_traffic_array(c=c, loads=wagen1_loads),
        response_type=ResponseType.Strain,
        damage_scenario=healthy_scenario,
        points=strain_points,
    ).T
    for s_i, sensor_responses in enumerate(responses_truck1):
        plt.subplot(len(strain_points), 2, (s_i * 2) + 1)
        # Find the center of the plot, minimum point in the data.
        data_center = 0
        for i in range(len(sensor_responses)):
            if sensor_responses[i] > sensor_responses[data_center]:
                data_center = i
        # sensor_responses = add_strain_noise(sensor_responses)
        # plt.plot(sensor_responses)
        plt.plot(sensor_responses[data_center - side:data_center + side])
        # plt.plot(sensor_responses[data_center - side : data_center + side])
        plt.title(f"{strain_labels[s_i]} in simulation")
    # Results from experiment.
    print_i(f"{side} points each side of center")
    for s_i, strain_label in enumerate(strain_labels):
        plt.subplot(len(strain_points), 2, (s_i * 2) + 2)
        with open(f"validation/experiment/D1a-{strain_label}.txt") as f:
            data = list(map(float, f.readlines()))
        side_expt = int(side_s * (len(data) / 240))
        # Find the center of the plot, minimum point in first 15000 points.
        data_center = 0
        for i in range(15000):
            if data[i] < data[data_center]:
                data_center = i
        # plt.plot(data)
        plt.plot(data[data_center - side_expt:data_center + side_expt])
        # plt.plot(data[data_center - side_expt : data_center + side_expt])
        plt.title(f"{strain_label} in dynamic test")
    set_labels("Microstrain", "Time")
    plt.tight_layout()
    plt.savefig(
        c.get_image_path("validation/truck-1", "time-series-strain.pdf"))
    plt.close()