Example #1
0
def make_boundary_plot(c: Config):
    """Top view of bridge with boundary conditions."""
    plt.landscape()
    top_view_bridge(c.bridge, abutments=True, piers=True, compass=False)
    plt.vlines(
        [0, c.bridge.length],
        c.bridge.z_min,
        c.bridge.z_max,
        lw=5,
        color="orange",
        label="     Y = 1, Z = 1",
    )
    for p_i, pier in enumerate(c.bridge.supports):
        z_min_top, z_max_top = pier.z_min_max_bottom()
        x_min, x_max = pier.x_min_max_top()
        x_center = x_min + ((x_max - x_min) / 2)
        plt.vlines(
            [x_center],
            z_min_top,
            z_max_top,
            lw=5,
            color="red" if (8 <= p_i <= 15) else "orange",
            label="X = 1, Y = 1, Z = 1" if p_i == 8 else None,
        )
    legend_marker_size(plt.legend(), 50)
    plt.title("Bridge 705 boundary conditions of nodal supports")
    plt.tight_layout()
    plt.savefig(c.get_image_path("sensors", "boundary.pdf"))
    plt.close()
Example #2
0
def wagen1_plot(c: Config):
    """Plot of wagen1 compared to given specification."""
    plt.landscape()

    wheel_print = (0.31, 0.25)
    wheel_prints = []
    for w_i in range(len(truck1.axle_distances) + 1):
        if w_i in [1, 2]:
            wheel_prints.append([wheel_print, wheel_print])
        else:
            wheel_prints.append([wheel_print])

    plt.subplot(1, 2, 1)
    xlim, ylim = topview_vehicle(truck1, wheel_prints=wheel_prints)
    plt.title("Truck 1 specification")
    plt.xlabel("Width (m)")
    plt.ylabel("Length (m)")

    plt.subplot(1, 2, 2)
    topview_vehicle(truck1, xlim=xlim, ylim=ylim)
    plt.title("Truck 1 in simulation")
    plt.xlabel("Width (m)")
    plt.ylabel("Length (m)")

    plt.savefig(c.get_image_path("vehicles", "wagen-1", bridge=False) + ".pdf")
    plt.close()
Example #3
0
def cracked_concrete_plots(c: Config):
    """Contour plots of cracked concrete scenarios."""
    response_type = ResponseType.YTranslation
    # 10 x 10 grid of points on the bridge deck where to record fem.
    points = [
        Point(x=x, y=0, z=z) for x, z in itertools.product(
            np.linspace(c.bridge.x_min, c.bridge.x_max, 10),
            np.linspace(c.bridge.z_min, c.bridge.z_max, 10),
        )
    ]

    # Create empty traffic array and collect fem.
    response_array = responses_to_traffic_array(
        c=c,
        traffic_array=load_normal_traffic_array(c)[0],
        response_type=response_type,
        bridge_scenario=cracked_scenario,
        points=points,
        sim_runner=OSRunner,
    )

    for t in range(len(response_array)):
        top_view_bridge(c.bridge, abutments=True, piers=True)
        responses = Responses.from_responses(
            response_type=response_type,
            responses=[(response_array[t][p], point)
                       for p, point in enumerate(points)],
        )
        plot_contour_deck(c=c, responses=responses, center_norm=True)
        plt.title("Cracked Concrete")
        plt.savefig(c.get_image_path("cracked-scenario", f"cracked-time-{t}"))
        plt.close()
Example #4
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()
Example #5
0
def make_available_sensors_plot(c: Config, pier_radius: float,
                                track_radius: float, edge_radius: float):
    """Scatter plot of sensors used for classification."""
    top_view_bridge(c.bridge, abutments=True, piers=True, compass=False)
    plot_deck_sensors(
        c=c,
        without=without.points(
            c=c,
            pier_radius=pier_radius,
            track_radius=track_radius,
            edge_radius=edge_radius,
        ),
        label=True,
    )
    for l_i, load in enumerate([Point(x=21, z=-8.4), Point(x=33, z=-4)]):
        plt.scatter(
            [load.x],
            [load.z],
            color="red",
            marker="o",
            s=50,
            label="Sensor of interest" if l_i == 0 else None,
        )
    legend_marker_size(plt.legend(), 50)
    plt.title(f"Sensors available for classification on Bridge 705")
    plt.tight_layout()
    plt.savefig(c.get_image_path("sensors", "unavailable-sensors.pdf"))
    plt.close()
Example #6
0
def temperature_effect_date(c: Config, month: str, vert: bool):
    temp = __init__.load(name=month)
    point = Point(x=51, y=0, z=-8.4)
    plt.landscape()

    def plot_hours():
        if not vert:
            return
        label_set = False
        for dt in temp["datetime"]:
            if np.isclose(float(dt.hour + dt.minute), 0):
                label = None
                if not label_set:
                    label = "Time at vertical line = 00:00"
                    label_set = True
                plt.axvline(x=dt, linewidth=1, color="black", label=label)

    # Plot the temperature.
    plt.subplot(2, 1, 1)
    plot_hours()
    plt.scatter(
        temp["datetime"],
        temp["temp"],
        c=temp["missing"],
        cmap=mpl.cm.get_cmap("bwr"),
        s=1,
    )
    plt.ylabel("Temperature (°C)")
    plt.xlabel("Date")
    plt.gcf().autofmt_xdate()
    plt.title(f"Temperature in {str(month[0]).upper()}{month[1:]}")
    plt.legend()
    # Plot the effect at a point.
    response_type = ResponseType.YTranslation
    plt.subplot(2, 1, 2)
    plot_hours()
    effect = __init__.effect(
        c=c, response_type=response_type, points=[point], temps=temp["temp"]
    )[0]
    plt.scatter(
        temp["datetime"],
        effect * 1000,
        c=temp["missing"],
        cmap=mpl.cm.get_cmap("bwr"),
        s=1,
    )
    plt.ylabel(f"{response_type.name()} (mm)")
    plt.xlabel("Date")
    plt.gcf().autofmt_xdate()
    plt.title(f"{response_type.name()} to unit thermal loading in {month}")
    # Save.
    plt.tight_layout()
    plt.savefig(c.get_image_path("classify/temperature", f"{month}.png"))
    plt.savefig(c.get_image_path("classify/temperature", f"{month}.pdf"))
    plt.close()
Example #7
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()
Example #8
0
def traffic_response_plots(c: Config, times: int = 3):
    """Response to normal traffic per scenarios scenario at multiple time steps."""
    response_type = ResponseType.YTranslation
    # 10 x 10 grid of points on the bridge deck where to record fem.
    points = [
        Point(x=x, y=0, z=z) for x, z in itertools.product(
            np.linspace(c.bridge.x_min, c.bridge.x_max, 10),
            np.linspace(c.bridge.z_min, c.bridge.z_max, 10),
        )
    ]
    # for damage_scenario in all_scenarios(c):
    for damage_scenario in [unit_temp_scenario]:
        response_array = responses_to_traffic_array(
            c=c,
            traffic_array=load_normal_traffic_array(c, mins=1)[0],
            response_type=response_type,
            bridge_scenario=damage_scenario,
            points=points,
            sim_runner=OSRunner,
        )
        print(response_array.shape)
        mean_response_array = np.mean(response_array, axis=0).T
        print(mean_response_array.shape)
        print(mean_response_array.shape)

        for t in range(times):
            time_index = -1 + abs(t)
            top_view_bridge(c.bridge, abutments=True, piers=True)
            responses = Responses.from_responses(
                response_type=response_type,
                responses=[(response_array[time_index][p], point)
                           for p, point in enumerate(points)],
            )
            plot_contour_deck(c=c,
                              responses=responses,
                              center_norm=True,
                              levels=100)
            plt.title(damage_scenario.name)
            plt.savefig(
                c.get_image_path(
                    "contour-traffic-response",
                    f"{damage_scenario.name}-time={time_index}",
                ))
            plt.close()
Example #9
0
def plot_distributions(
    response_array: List[float],
    response_type: ResponseType,
    titles: List[str],
    save: str,
    cols: int = 5,
    expected: List[List[float]] = None,
    xlim: Optional[Tuple[float, float]] = None,
):
    # Transpose so points are indexed first.
    response_array = response_array.T
    # response_array, unit_str = resize_and_units(response_array, response_type)
    num_points = response_array.shape[0]
    amax, amin = np.amax(response_array), np.amin(response_array)

    # Determine the number of rows.
    rows = int(num_points / cols)
    if rows != num_points / cols:
        print_w(
            f"Cols don't divide number of points {num_points}, cols = {cols}")
        rows += 1

    # Plot fem.
    for i in range(num_points):
        plt.subplot(rows, cols, i + 1)
        plt.xlim((amin, amax))
        plt.title(titles[i])
        label = None
        if expected is not None:
            if response_array.shape != expected.shape:
                expected = expected.T
                expected, _ = resize_and_units(expected, response_type)
            assert response_array.shape == expected.shape
            label = chisquare(response_array[i], expected[i])
        plt.hist(response_array[i], label=label)
        if label is not None:
            plt.legend()
        if xlim is not None:
            plt.xlim(xlim)

    plt.savefig(save)
    plt.close()
Example #10
0
def gradient_pier_displacement_plot(
    c: Config,
    pier_disp: PierSettlementScenario,
    response_type: ResponseType,
    title: str,
):
    """Contour plot of piers displaced in an increasing gradient."""

    # 10 x 10 grid of points on the bridge deck where to record fem.
    points = [
        Point(x=x, y=0, z=z) for x, z in itertools.product(
            np.linspace(c.bridge.x_min, c.bridge.x_max, 10),
            np.linspace(c.bridge.z_min, c.bridge.z_max, 10),
        )
    ]

    # Create empty traffic array and collect fem.
    response_array = responses_to_traffic_array(
        c=c,
        traffic_array=np.zeros(
            (1, len(c.bridge.wheel_tracks(c)) * c.il_num_loads)),
        response_type=response_type,
        bridge_scenario=pier_disp,
        points=points,
        fem_runner=OSRunner(c),
    )

    top_view_bridge(c.bridge, abutments=True, piers=True)
    responses = Responses.from_responses(
        response_type=response_type,
        responses=[(response_array[0][p], point)
                   for p, point in enumerate(points)],
    )
    plot_contour_deck(c=c, responses=responses, center_norm=True)
    plt.title(title)
    plt.savefig(
        c.get_image_path("pier-scenarios",
                         f"pier-displacement-{safe_str(title)}"))
    plt.close()
Example #11
0
def time_series_plot(c: Config, n: float):
    """Plot 24min time series of cracking, for multiple cracked bridges.

    For each bridge (hard-coded), a time series of strain fem is plotted.
    For each bridge it is initially in healthy condition, and the crack occurs
    halfway through.

    Args:
        n: float, meters in front of the crack zone where to place sensor.

    """

    # First construct one day (24 minutes) of traffic.
    total_mins = 24
    total_seconds = total_mins * 60
    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=total_seconds,
    )
    traffic_array.shape

    # Temperatures for one day.
    temps_day = temperature.from_to_mins(
        temperature.load("holly-springs"),
        datetime.fromisoformat(f"2019-07-03T00:00"),
        datetime.fromisoformat(f"2019-07-03T23:59"),
    )
    print(f"len temps = {len(temps_day['solar'])}")
    print(f"len temps = {len(temps_day['temp'])}")

    # Then generate some cracking time series.
    damages = [
        HealthyDamage(),
        transverse_crack(),
        transverse_crack(length=14.0, at_x=48.0),
    ]
    sensors = [
        Point(x=52, z=-8.4),  # Sensor in middle of lane.
        Point(x=damages[1].crack_area(c.bridge)[0] - n,
              z=-8.4),  # Sensor in front of crack zone.
        Point(x=damages[2].crack_area(c.bridge)[0] - n,
              z=-8.4),  # Sensor in front of crack zone.
    ]
    [print(f"Sensor {i} = {sensors[i]}") for i in range(len(sensors))]
    time_series = [
        crack_time_series(
            c=c,
            traffic_array=traffic_array,
            traffic_array_mins=total_mins,
            sensor=sensor,
            crack_frac=0.5,
            damage=damage,
            temps=temps_day["temp"],
            solar=temps_day["solar"],
        ) for damage, sensor in zip(damages, sensors)
    ]
    plt.portrait()
    for i, (y_trans, strain) in enumerate(time_series):
        x = np.arange(len(strain)) * c.sensor_hz / 60
        x_m = sensors[i].x
        damage_str = "Healthy Bridge"
        if i == 1:
            damage_str = "0.5 m crack zone"
        if i == 2:
            damage_str = "14 m crack zone"
        plt.subplot(len(time_series), 2, i * 2 + 1)
        plt.plot(x, y_trans * 1000, color="tab:blue")
        if i < len(time_series) - 1:
            plt.tick_params(axis="x", bottom=False, labelbottom=False)
        else:
            plt.xlabel("Hours")
        plt.title(f"At x = {x_m} m\n{damage_str}")
        plt.ylabel("Y trans. (mm)")

        plt.subplot(len(time_series), 2, i * 2 + 2)
        plt.plot(x, strain * 1e6, color="tab:orange")
        if i < len(time_series) - 1:
            plt.tick_params(axis="x", bottom=False, labelbottom=False)
        else:
            plt.xlabel("Hours")
        plt.title(f"At x = {x_m} m,\n{damage_str}")
        plt.ylabel("Microstrain XXB")
    plt.tight_layout()
    plt.savefig(c.get_image_path("crack", "time-series-q5.pdf"))
    plt.close()
Example #12
0
def piers_displaced(c: Config):
    """Contour plots of pier displacement for the given pier indices."""
    pier_indices = [4, 5]
    response_types = [ResponseType.YTranslation, ResponseType.Strain]
    axis_values = pd.read_csv("validation/axis-screenshots/piers-min-max.csv")
    for r_i, response_type in enumerate(response_types):
        for p in pier_indices:
            # Run the simulation and collect fem.
            sim_responses = load_fem_responses(
                c=c,
                response_type=response_type,
                sim_runner=OSRunner(c),
                sim_params=SimParams(displacement_ctrl=PierSettlement(
                    displacement=c.pd_unit_disp, pier=p), ),
            )

            # In the case of stress we map from kn/m2 to kn/mm2 (E-6) and then
            # divide by 1000, so (E-9).
            assert c.pd_unit_disp == 1
            if response_type == ResponseType.Strain:
                sim_responses.to_stress(c.bridge).map(lambda r: r * 1e-9)

            # Get min and max values for both Axis and OpenSees.
            rt_str = ("displa" if response_type == ResponseType.YTranslation
                      else "stress")
            row = axis_values[axis_values["name"] == f"{p}-{rt_str}"]
            dmin, dmax = float(row["dmin"]), float(row["dmax"])
            omin, omax = float(row["omin"]), float(row["omax"])
            amin, amax = max(dmin, omin), min(dmax, omax)
            levels = np.linspace(amin, amax, 16)

            # Plot and save the image. If plotting strains use Axis values for
            # colour normalization.
            # norm = None
            from plot import axis_cmap_r

            cmap = axis_cmap_r
            top_view_bridge(c.bridge, abutments=True, piers=True)
            plot_contour_deck(c=c,
                              cmap=cmap,
                              responses=sim_responses,
                              levels=levels)
            plt.tight_layout()
            plt.title(
                f"{sim_responses.response_type.name()} from 1mm pier settlement with OpenSees"
            )
            plt.savefig(
                c.get_image_path(
                    "validation/pier-displacement",
                    safe_str(f"pier-{p}-{sim_responses.response_type.name()}")
                    + ".pdf",
                ))
            plt.close()

            # First plot and clear, just to have the same colorbar.
            plot_contour_deck(c=c,
                              responses=sim_responses,
                              cmap=cmap,
                              levels=levels)
            plt.cla()
            # Save the axis plots.
            axis_img = mpimg.imread(
                f"validation/axis-screenshots/{p}-{rt_str}.png")
            top_view_bridge(c.bridge, abutments=True)
            plt.imshow(
                axis_img,
                extent=(
                    c.bridge.x_min,
                    c.bridge.x_max,
                    c.bridge.z_min,
                    c.bridge.z_max,
                ),
            )
            # Plot the load and min, max values.
            for point, leg_label, color in [
                ((0, 0), f"min = {np.around(dmin, 3)} {sim_responses.units}",
                 "r"),
                ((0, 0), f"max = {np.around(dmax, 3)} {sim_responses.units}",
                 "r"),
                (
                    (0, 0),
                    f"|min-max| = {np.around(abs(dmax - dmin), 3)} {sim_responses.units}",
                    "r",
                ),
            ]:
                plt.scatter(
                    [point[0]],
                    [point[1]],
                    label=leg_label,
                    marker="o",
                    color=color,
                    alpha=0,
                )
            if response_type == ResponseType.YTranslation:
                plt.legend()
            # Title and save.
            plt.title(
                f"{response_type.name()} from 1mm pier settlement with AxisVM")
            plt.xlabel("X position (m)")
            plt.ylabel("Z position (m)")
            plt.tight_layout()
            plt.savefig(
                c.get_image_path(
                    "validation/pier-displacement",
                    f"{p}-axis-{rt_str}.pdf",
                ))
            plt.close()
Example #13
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()
Example #14
0
def experiment_noise(c: Config):
    """Plot displacement and strain noise from dynamic test 1"""
    ################
    # Displacement #
    ################
    plt.portrait()
    # Find points of each sensor.
    displa_labels = ["U13", "U26", "U29"]
    displa_points = []
    for displa_label in displa_labels:
        sensor_x, sensor_z = _displa_sensor_xz(displa_label)
        displa_points.append(Point(x=sensor_x, y=0, z=sensor_z))
    # For each sensor plot and estimate noise.
    side = 700
    for s_i, displa_label in enumerate(displa_labels):
        # First plot the signal, and smoothed signal.
        plt.subplot(len(displa_points), 2, (s_i * 2) + 1)
        with open(f"validation/experiment/D1a-{displa_label}.txt") as f:
            data = list(map(float, f.readlines()))
        # 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
        data = data[data_center - side:data_center + side]
        smooth = savgol_filter(data, 31, 3)
        plt.plot(data, linewidth=1)
        plt.plot(smooth, linewidth=1)
        plt.ylim(-0.8, 0.3)
        plt.title(f"{displa_label} in dynamic test")
        # Then plot subtraction of smoothed from noisey.
        plt.subplot(len(displa_points), 2, (s_i * 2) + 2)
        noise = data - smooth
        plt.plot(noise, label=f"σ = {np.around(np.std(noise), 4)}")
        plt.legend()
        plt.title(f"Noise from {displa_label}")
    plt.tight_layout()
    plt.savefig(c.get_image_path("params", "noise-displa.pdf"))
    plt.close()

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

    plt.portrait()
    # Find points of each sensor.
    strain_labels = ["T1", "T10", "T11"]
    strain_points = []
    for strain_label in strain_labels:
        sensor_x, sensor_z = _strain_sensor_xz(strain_label)
        strain_points.append(Point(x=sensor_x, y=0, z=sensor_z))
    # For each sensor plot and estimate noise.
    side = 700
    xmin, xmax = np.inf, -np.inf
    for s_i, strain_label in enumerate(strain_labels):
        # First plot the signal, and smoothed signal.
        plt.subplot(len(strain_points), 2, (s_i * 2) + 1)
        with open(f"validation/experiment/D1a-{strain_label}.txt") as f:
            data = list(map(float, f.readlines()))
        # 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
        data = data[data_center - side:data_center + side]
        smooth = savgol_filter(data, 31, 3)
        plt.plot(data, linewidth=1)
        plt.plot(smooth, linewidth=1)
        plt.title(f"{strain_label} in dynamic test")
        # Then plot subtraction of smoothed from noisey.
        plt.subplot(len(strain_points), 2, (s_i * 2) + 2)
        noise = data - smooth
        plt.plot(noise, label=f"σ = {np.around(np.std(noise), 4)}")
        plt.legend()
        plt.title(f"Noise from {strain_label}")
    plt.tight_layout()
    plt.savefig(c.get_image_path("params", "noise-strain.pdf"))
    plt.close()
Example #15
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
Example #16
0
def comparison_plots_705(c: Config, run_only: bool, scatter: bool):
    """Make contour plots for all verification points on bridge 705."""
    # from classify.scenario.bridge import transverse_crack
    # c = transverse_crack().use(c)[0]
    positions = [
        # (52, -8.4, "a"),
        (34.95459, 26.24579 - 16.6, "a"),
        (51.25051, 16.6 - 16.6, "b"),
        (89.98269, 9.445789 - 16.6, "c"),
        (102.5037, 6.954211 - 16.6, "d"),
        # (34.95459, 29.22606 - 16.6, "a"),
        # (51.25051, 16.6 - 16.6, "b"),
        # (92.40638, 12.405 - 16.6, "c"),
        # (101.7649, 3.973938 - 16.6, "d"),
    ]
    diana_values = pd.read_csv("validation/diana-screenshots/min-max.csv")
    response_types = [ResponseType.YTranslation, ResponseType.Strain]
    # For each response type and loading position first create contour plots for
    # OpenSees. Then finally create subplots comparing to Diana.
    cmap = diana_cmap_r
    for load_x, load_z, label in positions:
        for response_type in response_types:
            # Setup the metadata.
            if response_type == ResponseType.YTranslation:
                rt_str = "displa"
                unit_str = "mm"
            elif response_type == ResponseType.Strain:
                rt_str = "strain"
                unit_str = "E-6"
            else:
                raise ValueError("Unsupported response type")
            row = diana_values[diana_values["name"] == f"{label}-{rt_str}"]
            dmin, dmax = float(row["dmin"]), float(row["dmax"])
            omin, omax = float(row["omin"]), float(row["omax"])
            amin, amax = max(dmin, omin), min(dmax, omax)
            levels = np.linspace(amin, amax, 16)

            # Create the OpenSees plot.
            loads = [
                PointLoad(
                    x_frac=c.bridge.x_frac(load_x),
                    z_frac=c.bridge.z_frac(load_z),
                    kn=100,
                )
            ]
            fem_responses = load_fem_responses(
                c=c,
                response_type=response_type,
                sim_runner=OSRunner(c),
                sim_params=SimParams(ploads=loads,
                                     response_types=response_types),
            )
            if run_only:
                continue
            title = (
                f"{response_type.name()} from a {loads[0].kn} kN point load at"
                + f"\nx = {load_x:.3f}m, z = {load_z:.3f}m, with ")
            save = lambda prefix: c.get_image_path(
                "validation/diana-comp",
                safe_str(f"{prefix}{response_type.name()}") + ".pdf",
            )
            top_view_bridge(c.bridge, piers=True, abutments=True)
            fem_responses = fem_responses.resize()
            sci_format = response_type == ResponseType.Strain
            plot_contour_deck(
                c=c,
                responses=fem_responses,
                ploads=loads,
                cmap=cmap,
                levels=levels,
                sci_format=sci_format,
                decimals=4,
                scatter=scatter,
            )
            plt.title(title + "OpenSees")
            plt.tight_layout()
            plt.savefig(save(f"{label}-"))
            plt.close()

            # Finally create label/title the Diana plot.
            if label is not None:
                # First plot and clear, just to have the same colorbar.
                plot_contour_deck(c=c,
                                  responses=fem_responses,
                                  ploads=loads,
                                  cmap=cmap,
                                  levels=levels)
                plt.cla()
                # Then plot the bridge and
                top_view_bridge(c.bridge, piers=True, abutments=True)
                plt.imshow(
                    mpimg.imread(
                        f"validation/diana-screenshots/{label}-{rt_str}.png"),
                    extent=(
                        c.bridge.x_min,
                        c.bridge.x_max,
                        c.bridge.z_min,
                        c.bridge.z_max,
                    ),
                )
                dmin_s = f"{dmin:.4e}" if sci_format else f"{dmin:.4f}"
                dmax_s = f"{dmax:.4e}" if sci_format else f"{dmax:.4f}"
                dabs_s = (f"{abs(dmin - dmax):.4e}"
                          if sci_format else f"{abs(dmin - dmax):.4f}")
                for point, leg_label, color, alpha in [
                    ((load_x, load_z), f"{loads[0].kn} kN load", "r", 1),
                    ((0, 0), f"min = {dmin_s} {fem_responses.units}", "r", 0),
                    ((0, 0), f"max = {dmax_s} {fem_responses.units}", "r", 0),
                    ((0, 0), f"|min-max| = {dabs_s} {fem_responses.units}",
                     "r", 0),
                ]:
                    plt.scatter(
                        [point[0]],
                        [point[1]],
                        label=leg_label,
                        marker="o",
                        color=color,
                        alpha=alpha,
                    )
                plt.legend()
                plt.title(title + "Diana")
                plt.xlabel("X position (m)")
                plt.ylabel("Z position (m)")
                plt.tight_layout()
                plt.savefig(save(f"{label}-diana-"))
                plt.close()
Example #17
0
def plot_mmm_strain_convergence(
    c: Config,
    pier: int,
    df: pd.DataFrame,
    all_strains: Dict[float, Responses],
    title: str,
    without: Optional[Callable[[Point], bool]] = None,
    append: Optional[str] = None,
):
    """Plot convergence of given fem as model size grows."""
    # A grid of points 1m apart, over which to calculate fem.
    grid = [
        Point(x=x, y=0, z=z)
        for x, z in itertools.product(
            np.linspace(c.bridge.x_min, c.bridge.x_max, int(c.bridge.length)),
            np.linspace(c.bridge.z_min, c.bridge.z_max, int(c.bridge.width)),
        )
    ]
    # If requested, remove some values from the fem.
    if without is not None:
        grid = [point for point in grid if not without(point)]
        for msl, strains in all_strains.items():
            print(f"Removing points from strains with max_shell_len = {msl}")
            all_strains[msl] = strains.without(without)
    # Collect fem over all fem, and over the grid. Iterate by
    # decreasing max_shell_len.
    mins, maxes, means = [], [], []
    gmins, gmaxes, gmeans = [], [], []
    max_shell_lens = []
    for msl, strains in sorted(all_strains.items(), key=lambda kv: -kv[0]):
        max_shell_lens.append(msl)
        print_i(f"Gathering strains with max_shell_len = {msl}", end="\r")
        grid_strains = np.array([strains.at_deck(point, interp=True) for point in grid])
        gmins.append(scalar(np.min(grid_strains)))
        gmaxes.append(scalar(np.max(grid_strains)))
        gmeans.append(scalar(np.mean(grid_strains)))
        strains = np.array(list(strains.values()))
        mins.append(scalar(np.min(strains)))
        maxes.append(scalar(np.max(strains)))
        means.append(scalar(np.mean(strains)))
    print()
    # Normalize and plot the mins, maxes, and means.
    def normalize(ys):
        print(ys)
        return ys / np.mean(ys[-5:])

    mins, maxes, means = normalize(mins), normalize(maxes), normalize(means)
    gmins, gmaxes, gmeans = normalize(gmins), normalize(gmaxes), normalize(gmeans)
    deck_nodes = [df.at[msl, "deck-nodes"] for msl in max_shell_lens]
    pier_nodes = [df.at[msl, "pier-nodes"] for msl in max_shell_lens]
    num_nodes = np.array(deck_nodes) + np.array(pier_nodes)
    print(f"MSLs = {max_shell_lens}")
    print(f"num_nodes = {num_nodes}")
    # Plot all lines, for debugging.
    plt.landscape()
    plt.plot(num_nodes, mins, label="mins")
    plt.plot(num_nodes, maxes, label="maxes")
    plt.plot(num_nodes, means, label="means")
    plt.plot(num_nodes, gmins, label="gmins")
    plt.plot(num_nodes, gmaxes, label="gmaxes")
    plt.plot(num_nodes, gmeans, label="gmeans")
    plt.grid(axis="y")
    plt.xlabel("Nodes in FEM")
    plt.ylabel("Strain")
    plt.title(title)
    plt.tight_layout()
    plt.legend()
    plt.savefig(
        c.get_image_path("convergence-pier-strain", f"mmm-{append}-all.pdf", acc=False)
    )
    plt.close()
    # Only plot some lines, for the thesis.
    plt.landscape()
    plt.plot(num_nodes, gmins, label="Minimum")
    plt.plot(num_nodes, gmaxes, label="Maximum")
    plt.plot(num_nodes, gmeans, label="Mean")
    plt.grid(axis="y")
    plt.title(title)
    plt.xlabel("Nodes in FEM")
    plt.ylabel("Strain")
    plt.legend()
    plt.tight_layout()
    plt.savefig(
        c.get_image_path("convergence-pier-strain", f"mmm-{append}.pdf", acc=False)
    )
    plt.close()
Example #18
0
def point_load_response_plots(c: Config,
                              x: float,
                              z: float,
                              kn: int = 1000,
                              run: bool = False):
    """Response to a point load per scenarios scenario."""
    response_types = [ResponseType.YTranslation, ResponseType.Strain]
    # scenarios = all_scenarios(c)
    damage_scenarios = [HealthyScenario(), transverse_crack()]

    # 10 x 10 grid of points on the bridge deck where to record fem.
    points = [
        Point(x=x, y=0, z=z) for x, z in itertools.product(
            np.linspace(c.bridge.x_min, c.bridge.x_max, 30),
            np.linspace(c.bridge.z_min, c.bridge.z_max, 100),
        )
    ]

    for response_type in response_types:
        all_responses = []
        for damage_scenario in damage_scenarios:
            sim_params = SimParams(
                response_types=[response_type],
                ploads=[
                    PointLoad(x_frac=c.bridge.x_frac(x),
                              z_frac=c.bridge.z_frac(z),
                              kn=kn)
                ],
            )
            use_c, sim_params = damage_scenario.use(c=c, sim_params=sim_params)
            all_responses.append(
                load_fem_responses(
                    c=use_c,
                    sim_params=sim_params,
                    response_type=response_type,
                    sim_runner=OSRunner(use_c),
                    run=run,
                ).resize())
        amin, amax = np.inf, -np.inf
        for sim_responses in all_responses:
            responses = np.array(list(sim_responses.values()))
            amin = min(amin, min(responses))
            amax = max(amax, max(responses))
        for d, damage_scenario in enumerate(damage_scenarios):
            top_view_bridge(c.bridge, abutments=True, piers=True)
            plot_contour_deck(
                c=c,
                responses=all_responses[d],
                levels=100,
                norm=colors.Normalize(vmin=amin, vmax=amax),
                decimals=10,
            )
            plt.title(damage_scenario.name)
            plt.tight_layout()
            plt.savefig(
                c.get_image_path(
                    "contour/point-load",
                    safe_str(
                        f"x-{x:.2f}-z-{z:.2f}-kn-{kn}-{response_type.name()}-{damage_scenario.name}"
                    ) + ".pdf",
                ))
            plt.close()