Пример #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 id_str(self, msl: bool = True, data_id: bool = True):
        """Name with accuracy information.

        Args:
            msl: bool, include msl in identifier.
            data_id: bool, include data_id in identifier.

        """
        acc_str = f"-{self.msl}" if msl else ""
        data_id_str = f"-{self.data_id}" if data_id else ""
        return safe_str(f"{self.name}{acc_str}{data_id_str}")
Пример #3
0
    def sim_model_path(
        self,
        sim_params: SimParams,
        ext: str,
        append: str = "",
        dirname: Optional[str] = None,
    ) -> str:
        """Deterministic path for a FE model file.

        :param sim_params: simulation parameters.
        :param ext: extension of the output file without the dot.
        :param dirname: directory name of output file. Defaults to FEMRunner.name.
        :param append: append to the filename (before the extension).
        :return: path for the output file.
        """
        param_str = sim_params.id_str()
        append = append if len(append) == 0 else f"-{append}"
        filename = f"{self.c.bridge.id_str()}-params={param_str}{append}"
        if dirname is None:
            dirname = self.name
        dirname = safe_str(dirname)
        return shorten_path(
            self.c,
            safe_str(self.c.get_data_path(dirname, filename)) + f".{ext}")
Пример #4
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()
Пример #5
0
def uls_contour_plot(c: Config, x_i: int, z_i: int,
                     response_type: ResponseType):
    wheel_xs = c.bridge.wheel_track_xs(c)
    wheel_x = wheel_xs[x_i]
    wheel_zs = c.bridge.wheel_track_zs(c)
    wheel_z = wheel_zs[z_i]
    print_i(f"Wheel (x, z) = ({wheel_x}, {wheel_z})")
    plt.landscape()
    plt.subplot(2, 1, 1)
    healthy = list(
        ILMatrix.load_wheel_track(
            c=c,
            response_type=response_type,
            fem_runner=OSRunner(c),
            load_z_frac=c.bridge.z_frac(wheel_z),
            run_only=False,
            indices=[x_i],
        ))[0].resize()
    top_view_bridge(bridge=c.bridge, compass=False, abutments=True, piers=True)
    plot_contour_deck(c=c, responses=healthy, sci_format=True, decimals=6)
    plt.title("Healthy")
    c = transverse_crack().use(c)[0]
    cracked = list(
        ILMatrix.load_wheel_track(
            c=c,
            response_type=response_type,
            fem_runner=OSRunner(c),
            load_z_frac=c.bridge.z_frac(wheel_z),
            run_only=False,
            indices=[x_i],
        ))[0].resize()
    plt.subplot(2, 1, 2)
    top_view_bridge(bridge=c.bridge, compass=False, abutments=True, piers=True)
    plot_contour_deck(c=c, responses=cracked, sci_format=True, decimals=6)
    plt.title("Cracked")
    plt.tight_layout()
    plt.savefig(
        c.get_image_path(
            "verification",
            safe_str(
                f"uls-contour-x-{wheel_x}-z-{wheel_z}-{response_type.name()}")
            + ".pdf",
        ))
Пример #6
0
def make_normal_mv_load_animations(c: Config, per_axle: bool = False):
    """Make animations of a pload moving across a bridge."""
    plt.close()
    mv_load = MovingLoad.from_vehicle(x_frac=0,
                                      vehicle=sample_vehicle(c),
                                      lane=0)
    per_axle_str = f"-peraxle" if per_axle else ""
    for response_type in ResponseType:
        animate_mv_load(
            c,
            mv_load,
            response_type,
            OSRunner(c),
            per_axle=per_axle,
            save=safe_str(
                c.image_path(f"animations/{c.bridge.name}-{OSRunner(c).name}" +
                             f"-{response_type.name()}{per_axle_str}" +
                             f"-load-{mv_load.str_id()}")).lower() + ".mp4",
        )
Пример #7
0
 def build_with_refinement(refinement_radii):
     sim_params = SimParams(
         response_types=[response_type],
         ploads=[pload],
         refinement_radii=refinement_radii,
     )
     # Build and save the model file.
     if build:
         build_model_3d(
             c=min_config,
             expt_params=ExptParams([sim_params]),
             os_runner=OSRunner(min_config),
         )
     # Load and plot fem.
     if plot:
         sim_responses = load_fem_responses(
             c=min_config,
             sim_runner=OSRunner(min_config),
             response_type=response_type,
             sim_params=sim_params,
             run=True,
         )
         for scatter in [True, False]:
             top_view_bridge(min_config.bridge,
                             abutments=True,
                             piers=True,
                             lanes=True)
             plot_contour_deck(
                 c=min_config,
                 responses=sim_responses,
                 scatter=scatter,
                 levels=100,
             )
             plt.title(f"{refinement_radii}")
             plt.savefig(
                 min_config.get_image_path(
                     "debugging",
                     safe_str(
                         f"{response_type.name()}-{refinement_radii}-scatter-{scatter}"
                     ) + ".pdf",
                 ))
             plt.close()
Пример #8
0
    def id_str(self):
        """String representing the simulation parameters.

        NOTE: Response types are not included in the ID string because it is
        currently assumed that a simulation saves all output files.

        """
        load_str = ""
        for pier_settlement in self.pier_settlement:
            load_str += pier_settlement.id_str()
        if self.axial_delta_temp is not None:
            load_str += f"temp-axial-{self.axial_delta_temp}"
        if self.moment_delta_temp is not None:
            load_str += f"temp-moment-{self.moment_delta_temp}"
        if len(self.ploads) > 0:
            pl_str = ",".join(pl.id_str() for pl in self.ploads)
            load_str += f"[{pl_str}]"
        if len(self.pier_settlement) > 0:
            load_str += ",".join(ps.id_str() for ps in self.pier_settlement)
        return safe_str(load_str)
Пример #9
0
def make_event_plots(c: Config):
    """Make plots of events in different scenarios."""
    from plot.features import plot_events_from_traffic

    fem_runner = OSRunner(c)
    bridge_scenario = BridgeScenarioNormal()
    max_time, time_step, lam, min_d = 20, 0.01, 5, 2
    c.time_step = time_step
    sensor_zs = [lane.z_center() for lane in c.bridge.lanes]
    points = [Point(x=35, y=0, z=z) for z in sensor_zs]

    for response_type in [ResponseType.YTranslation]:
        for traffic_scenario in [
                normal_traffic(c=c, lam=lam, min_d=min_d),
                heavy_traffic_1(c=c, lam=lam, min_d=min_d, prob_heavy=0.01),
        ]:

            # Generate traffic under a scenario.
            traffic, start_index = traffic_scenario.traffic(
                bridge=c.bridge, max_time=max_time, time_step=time_step)
            traffic = traffic[start_index:]

            # Plot events from traffic.
            plot_events_from_traffic(
                c=c,
                bridge=c.bridge,
                bridge_scenario=bridge_scenario,
                traffic_name=traffic_scenario.name,
                traffic=traffic,
                start_time=start_index * time_step,
                time_step=time_step,
                response_type=ResponseType.YTranslation,
                points=points,
                fem_runner=OSRunner(c),
                save=c.get_image_path(
                    "events",
                    safe_str(
                        f"bs-{bridge_scenario.name}-ts-{traffic_scenario.name}"
                        f"-rt-{response_type.name()}"),
                ),
            )
Пример #10
0
def transverse_crack(
    length: float = 0.5,
    width: Optional[float] = None,
    at_x: Optional[float] = None,
    at_z: Optional[float] = None,
) -> CrackedScenario:
    """A bridge with a transverse crack."""

    def crack_area(bridge: Bridge) -> CrackArea:
        nonlocal width
        nonlocal at_x
        nonlocal at_z
        if width is None:
            width = bridge.width / 2
        if at_x is None:
            at_x = bridge.x_min + (bridge.length / 2)
        if at_z is None:
            at_z = bridge.z_min
        return at_x, at_z, at_x + length, at_z + width

    return CrackedScenario(
        name=safe_str(f"transverse-{length}-{width}-{at_x}-{at_z}"),
        crack_area=crack_area,
    )
Пример #11
0
def crack_time_series(
    c: Config,
    traffic_array,
    traffic_array_mins: float,
    sensor: Point,
    crack_frac: float,
    damage,
    temps: List[float],
    solar: List[float],
):
    """Time series of sensor fem, vertical translation and strain XXB.

    Returns a NumPy array of dimensions (2 x len(traffic_array)).

    Args:
        c: Config, global configuration object.
        traffic_array: TrafficArray, traffic flowing over the bridge.
        traffic_array_mins: float, minutes of the the traffic flow.
        sensor: Point, point at which to collect fem.
        crack_frac: float, fraction of time series where crack occurs.
        damage: DamageScenario, scenarios that occurs at crack_frac.
        temps: List[float], list of air temperature, per temperature minute.
        solar: List[float], list of solar radiance, per temperature minute.

    """
    assert 0 <= crack_frac <= 1
    response_types = [ResponseType.YTranslation, ResponseType.Strain]
    half_i = int(len(traffic_array) * crack_frac)
    traffic_array_0, traffic_array_1 = traffic_array[:half_i], traffic_array[
        half_i:]
    assert len(traffic_array_0) + len(traffic_array_1) == len(traffic_array)

    half_t = int(len(temps) * crack_frac)
    assert len(temps) == len(solar)

    # Get the effect of temperature for both response types and damages.
    # In each case we have the full days worth of temperature fem.
    temp_effect = []
    for response_type in response_types:
        temp_effect_damages = []
        for di, ds in enumerate([HealthyDamage(), damage]):
            bots_tops, new_temp_effect = temperature.effect(
                c=ds.use(c)[0],
                response_type=response_type,
                points=[sensor],
                # One hour temperature data per minute of traffic data.
                len_per_hour=int(len(traffic_array) /
                                 traffic_array_mins) if di == 0 else None,
                temps=temps if di == 0 else None,
                solar=solar if di == 0 else None,
                temps_bt=bots_tops.T[int(len(bots_tops.T) /
                                         2):].T if di == 1 else None,
                ret_temps_bt=True,
            )
            bots_tops = np.array(bots_tops)
            temp_effect_damages.append(
                new_temp_effect[0] if di ==
                1 else new_temp_effect[0][:int(len(new_temp_effect[0]) / 2)])
        temp_effect.append(np.concatenate(temp_effect_damages))
        print(f"len(temps) = {len(temps)}")
        print(f"len_per_hour = {int(len(traffic_array) / traffic_array_mins)}")
        print(f"Temperature shape = {temp_effect[-1].shape}")
        plt.plot(temp_effect[-1])
        plt.savefig(
            c.get_image_path("crack",
                             safe_str(f"save-temps-{response_type}.pdf")))
        plt.close()

    responses = []
    for ri, rt in enumerate(response_types):
        responses_healthy_cracked = []
        for ds, ta in [(HealthyDamage(), traffic_array_0),
                       (damage, traffic_array_1)]:
            print(
                f"Sections in scenarios scenario = {len(ds.use(c)[0].bridge.sections)}"
            )
            responses_healthy_cracked.append(
                responses_to_traffic_array(
                    c=c,
                    traffic_array=ta,
                    response_type=rt,
                    damage_scenario=ds,
                    points=[sensor],
                ).T[0])  # Responses from a single point.
        responses.append(np.concatenate(responses_healthy_cracked))
        print(f"shape fem without temp = {responses[-1].shape}")
        print(f"shape of temp effect = {temp_effect[ri].shape}")
        if rt == ResponseType.Strain:
            responses[ri] = resize_units("")[0](responses[ri])
        responses[ri] += temperature.apply(temp_effect[ri], responses[ri])
    responses = np.array(responses)
    print(f"Responses shape = {responses.shape}")
    return responses
Пример #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()
Пример #13
0
def _traffic_name(c: Config, traffic_scenario: TrafficScenario, max_time: float):
    return safe_str(
        f"{traffic_scenario.name} {c.il_num_loads} {max_time} {c.sensor_hz}"
    )
Пример #14
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()
Пример #15
0
def wagen_1_contour_plot(
    c: Config,
    x: int,
    crack_x: float,
    response_type: ResponseType,
    scatter: bool,
    run: bool,
    length: float,
    outline: bool,
    wheels: bool,
    temp: bool,
):
    original_c = c
    LOADS = False
    temp_bottom, temp_top = [17, 25]
    time = wagen1.time_at(x=x, bridge=c.bridge)

    def plot_wheels():
        if wheels:
            wagen1.plot_wheels(c=c,
                               time=time,
                               label="Truck 1 wheels",
                               zorder=100)

    center = c.bridge.x_max / 2
    min_x, max_x = center - 20, center + 20
    min_z, max_z = c.bridge.z_min, c.bridge.z_max

    def zoom_in():
        plt.ylim(min_z, max_z)
        plt.xlim(min_x, max_x)

    loads = wagen1.to_wheel_track_loads(c=c, time=time, flat=True)

    crack_f = lambda: transverse_crack(length=length, at_x=crack_x)
    c = healthy_damage_w_transverse_crack_nodes(crack_f).use(original_c)[0]
    deck_shells = get_bridge_shells(c.bridge)[0]
    healthy_responses = load_fem_responses(
        c=c,
        sim_params=SimParams(ploads=loads),
        response_type=response_type,
        sim_runner=OSRunner(c),
        run=run,
    ).at_shells(deck_shells)  # Convert fem to one per shell.
    if response_type in [ResponseType.Strain, ResponseType.StrainZZB]:
        # Resize by E-6 from microstrain to strain to match temperature units.
        healthy_responses = healthy_responses.resize()
    before_temp = healthy_responses.at_deck(Point(x=51, z=-8.4), interp=False)
    if temp:
        healthy_deck_points = healthy_responses.deck_points()  # Point of fem.
        temp_effect = temperature.effect(
            c=c,
            response_type=response_type,
            points=healthy_deck_points,
            temps_bt=([temp_bottom], [temp_top]),
        ).T[0]  # Temperature effect at existing response points.
        healthy_responses = healthy_responses.add(temp_effect,
                                                  healthy_deck_points)
    after_temp = healthy_responses.at_deck(Point(x=51, z=-8.4), interp=False)
    print_i(f"Healthy, before/after = {before_temp}, {after_temp}")
    if response_type in [ResponseType.Strain, ResponseType.StrainZZB]:
        healthy_responses = healthy_responses.map(lambda x: x * 1e6)
    else:
        healthy_responses = healthy_responses.resize()

    # Responses in cracked scenario.
    c = crack_f().use(original_c)[0]
    crack_responses = load_fem_responses(
        c=c,
        sim_params=SimParams(ploads=loads),
        response_type=response_type,
        sim_runner=OSRunner(c),
        run=run,
    ).at_shells(deck_shells)
    if response_type in [ResponseType.Strain, ResponseType.StrainZZB]:
        # Resize by E-6 from microstrain to strain to match temperature units.
        crack_responses = crack_responses.resize()
    before_temp = crack_responses.at_deck(Point(x=51, z=-8.4), interp=False)
    if temp:
        crack_deck_points = crack_responses.deck_points()  # Point of fem.
        temp_effect = temperature.effect(
            c=c,
            response_type=response_type,
            points=healthy_deck_points,
            temps_bt=([temp_bottom], [temp_top]),
        ).T[0]  # Temperature effect at existing response points.
        crack_responses = crack_responses.add(temp_effect, healthy_deck_points)
    after_temp = crack_responses.at_deck(Point(x=51, z=-8.4), interp=False)
    print_i(f"Crack, before/after = {before_temp}, {after_temp}")
    if response_type in [ResponseType.Strain, ResponseType.StrainZZB]:
        crack_responses = crack_responses.map(lambda x: x * 1e6)
    else:
        crack_responses = crack_responses.resize()

    # Limit to points in crack zone.
    without_cm = 35
    print(f"Avoid {without_cm} cm around crack zone")
    _without_crack_zone = crack_f().without(c.bridge, without_cm / 100)
    without_crack_zone = lambda p: not _without_crack_zone(p)
    if response_type in [ResponseType.Strain, ResponseType.StrainZZB]:
        healthy_responses = healthy_responses.without(without_crack_zone)
        crack_responses = crack_responses.without(without_crack_zone)

    # Norm calculation.
    vmin = min(healthy_responses.values())
    vmax = max(healthy_responses.values())
    vmin = min(vmin, min(crack_responses.values()))
    vmax = max(vmax, max(crack_responses.values()))
    norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax)
    print(f"Norm min/max = {vmin}, {vmax}")

    plt.portrait()
    plt.subplot(3, 1, 1)
    plot_contour_deck(
        c=c,
        responses=healthy_responses,
        ploads=loads if LOADS else [],
        scatter=scatter,
        norm=norm,
        decimals=2,
    )

    c_x_start, c_z_start, c_x_end, c_z_end = list(
        map(round_m,
            crack_f().crack_area(c.bridge)))

    def plot_outline(label="Crack zone"):
        if outline:
            plt.gca().add_patch(
                mpl.patches.Rectangle(
                    (c_x_start, c_z_start),
                    c_x_end - c_x_start,
                    c_z_end - c_z_start,
                    fill=not scatter,
                    edgecolor="black",
                    facecolor="white",
                    alpha=1,
                    label=label,
                ))

    top_view_bridge(bridge=c.bridge, compass=False, abutments=True, piers=True)
    plot_outline(label="Responses not considered")
    plot_wheels()
    zoom_in()

    def legend():
        plt.legend(
            loc="upper right",
            borderpad=0.2,
            labelspacing=0.2,
            borderaxespad=0,
            handletextpad=0.2,
            columnspacing=0.2,
        )

    legend()
    plt.title(f"Healthy bridge")
    plt.xlabel("")
    plt.tick_params(bottom=False, labelbottom=False)

    plt.subplot(3, 1, 2)
    plot_contour_deck(
        c=c,
        responses=crack_responses,
        ploads=loads if LOADS else [],
        scatter=scatter,
        norm=norm,
        decimals=2,
    )

    top_view_bridge(bridge=c.bridge, compass=False, abutments=True, piers=True)
    plot_outline()
    plot_wheels()
    zoom_in()

    legend()
    plt.title(f"Cracked bridge")
    plt.xlabel("")
    plt.tick_params(bottom=False, labelbottom=False)

    plt.subplot(3, 1, 3)
    responses = []
    for x in healthy_responses.deck_xs:
        for z in healthy_responses.zs[x][0]:
            responses.append((
                bridge_sim.sim.responses.responses[0][x][0][z] -
                crack_responses.at_deck(Point(x=x, z=z), interp=False),
                Point(x=x, z=z),
            ))
            # try:
            #     fem.append((
            #         healthy_responses.fem[0][x][0][z]
            #         - crack_responses.fem[0][x][0][z],
            #         Point(x=x, z=z)
            #     ))
            # except KeyError:
            #     pass
            #
    diff_responses = responses = Responses(
        response_type=response_type,
        responses=responses,
        units=healthy_responses.units,
    )
    plot_contour_deck(
        c=c,
        responses=diff_responses,
        ploads=loads if LOADS else [],
        cmap=mpl.cm.get_cmap("PiYG"),
        scatter=scatter,
        decimals=2,
    )

    print("********")
    print("********")
    print("********")
    grid_x, grid_z = 600, 200
    grid_points = list(
        filter(
            lambda p: not without_crack_zone(p),
            [
                Point(x=x, y=0, z=z)
                for x in np.linspace(c.bridge.x_min, c.bridge.x_max, grid_x)
                for z in np.linspace(c.bridge.z_min, c.bridge.z_max, grid_z)
            ],
        ))
    print(f"Amount grid points = {len(grid_points)}")
    grid_x_len = c.bridge.length / grid_x
    grid_z_len = c.bridge.width / grid_z
    grid_area = grid_x_len * grid_z_len
    print(f"Grid area = {grid_area}")
    print("Interpolating diff fem")
    interp_diff_responses = diff_responses.at_decks(grid_points)
    count_interp = len(interp_diff_responses)
    interp_diff_responses = interp_diff_responses[~np.
                                                  isnan(interp_diff_responses)]
    print(
        f"Removed {count_interp - len(interp_diff_responses)} of {count_interp} fem, remaining = {len(interp_diff_responses)}"
    )
    print("Finished interpolating diff fem")
    count_min, count_max = 0, 0
    d_min, d_max = min(diff_responses.values()), max(diff_responses.values())
    print(f"diff min, max = {d_min}, {d_max}")
    d_min08, d_max08 = d_min * 0.8, d_max * 0.8
    for interp_r in interp_diff_responses:
        if interp_r < d_min08:
            count_min += 1
        if interp_r > d_max08:
            count_max += 1
    print(f"Count = {count_min}, {count_max}")
    save_path = original_c.get_image_path(
        "verification",
        safe_str(
            f"truck1-contour-x-{x}{crack_x}{length}-{response_type.name()}-{temp}"
        ),
    )
    with open(save_path + ".txt", "w") as f:
        f.write(f"{count_min}, {count_max}\n")
        f.write(f"{count_min * grid_area}, {count_max * grid_area}")
    print(f"Wrote results to {save_path}.txt")

    top_view_bridge(bridge=c.bridge, compass=False, abutments=True, piers=True)
    plot_outline()
    plot_wheels()
    zoom_in()

    legend()
    temp_str = f"\nT_bot = {temp_bottom} °C, T_top = {temp_top} °C" if temp else ""
    plt.title(f"Difference of healthy & cracked bridge")
    rt_name = (f"Microstrain {response_type.ss_direction()}" if response_type
               in [ResponseType.Strain, ResponseType.StrainZZB
                   ] else response_type.name())

    plt.suptitle(f"{rt_name}: Truck 1 on healthy & cracked bridge{temp_str}")
    plt.tight_layout(rect=[0, 0.03, 1, 0.93 if temp else 0.95])
    plt.savefig(save_path + ".pdf")
Пример #16
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
Пример #17
0
 def id_str(self):
     return safe_str(f"{np.around(self.settlement, 3)}-{self.pier}")
Пример #18
0
 def id_str(self):
     """String uniquely representing this point load."""
     return safe_str(
         f"({np.around(self.x, DIST_DECIMALS)}, {np.around(self.z, DIST_DECIMALS)}, {np.around(self.load, DIST_DECIMALS)})"
     )
Пример #19
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()