Beispiel #1
0
 def get_node(self,
              x: float,
              y: float,
              z: float,
              deck: bool,
              comment: Optional[str] = None) -> Node:
     x, y, z = round_m(x), round_m(y), round_m(z)
     pos = (x, y, z)
     if pos not in self.nodes_by_pos:
         n_id = self.new_n_id()
         node = Node(n_id=n_id, x=x, y=y, z=z, deck=deck, comment=comment)
         self.nodes_by_id[n_id] = node
         self.nodes_by_pos[pos] = node
         self.nodes_by_pos_dict[x][y][z] = node
     return self.nodes_by_pos[pos]
Beispiel #2
0
 def to_wheel_track_xs(
     self, c: "Config", wheel_x: float, wheel_track_xs: Optional[List[float]] = None
 ) -> Tuple[Tuple[float, float], Tuple[float, float]]:
     """X positions (and weighting) of unit loads for a x position.
     This implements wheel track bucketing!
     """
     wheel_x = round_m(wheel_x)
     if wheel_track_xs is None:
         wheel_track_xs = c.bridge.wheel_track_xs(c)
     unit_load_x_ind = np.searchsorted(wheel_track_xs, wheel_x)
     unit_load_x = lambda: wheel_track_xs[unit_load_x_ind]
     if unit_load_x() > wheel_x:
         unit_load_x_ind -= 1
     assert unit_load_x() <= wheel_x
     # If the unit load is an exact match just return it.
     if np.isclose(wheel_x, unit_load_x()):
         return ((wheel_x, 1), (0, 0))
     # Otherwise, return a combination of two unit loads. In this case the
     # unit load's position is less than the wheel.
     unit_load_x_lo = unit_load_x()
     unit_load_x_hi = wheel_track_xs[unit_load_x_ind + 1]
     assert unit_load_x_hi > wheel_x
     dist_lo = abs(unit_load_x_lo - wheel_x)
     dist_hi = abs(unit_load_x_hi - wheel_x)
     dist = dist_lo + dist_hi
     return ((unit_load_x_lo, dist_hi / dist), (unit_load_x_hi, dist_lo / dist))
Beispiel #3
0
 def __init__(
     self,
     n_id: int,
     x: float,
     y: float,
     z: float,
     deck: bool,
     pier: Optional[Support] = None,
     comment: Optional[str] = None,
     support: Optional[Support] = None,
 ):
     self.n_id = n_id
     self.x = round_m(x)
     self.y = round_m(y)
     self.z = round_m(z)
     self.pier = pier
     self.deck = deck
     self.comment = comment
     self.support = support
Beispiel #4
0
 def id_str(
     c: Config,
     response_type: ResponseType,
     sim_runner: FEMRunner,
     wheel_zs: List[float],
 ):
     wheel_zs_str = [round_m(wheel_z) for wheel_z in wheel_zs]
     return (
         f"il-{response_type.name()}-{sim_runner.name}-{c.il_unit_load_kn}"
         + f"-{c.il_num_loads}-z={wheel_zs_str}")
Beispiel #5
0
    def _crack_deck(self, bridge: Bridge):
        """Adds cracked sections to the given bridge's deck."""
        c_x_start, c_z_start, c_x_end, c_z_end = list(
            map(round_m, self.crack_area(bridge))
        )
        # print(f"crack x: (start, end) = ({c_x_start}, {c_x_end})")
        # print(f"crack z: (start, end) = ({c_z_start}, {c_z_end})")

        if callable(bridge.sections):
            raise NotImplementedError()

        # Find where the cracked area and current sections overlap.
        overlaps: List[Tuple[Section3D, float, float, float, float]] = []
        for section in bridge.sections:
            s_x_start = round_m(bridge.x(section.start_x_frac))
            s_z_start = round_m(bridge.z(section.start_z_frac))
            s_x_end = round_m(bridge.x(section.end_x_frac))
            s_z_end = round_m(bridge.z(section.end_z_frac))

            # print()
            # print(f"section x: (start, end) = ({s_x_start}, {s_x_end})")
            # print(f"section z: (start, end) = ({s_z_start}, {s_z_end})")

            overlap_x_start = max(c_x_start, s_x_start)
            overlap_z_start = max(c_z_start, s_z_start)
            overlap_x_end = min(c_x_end, s_x_end)
            overlap_z_end = min(c_z_end, s_z_end)

            # print(f"overlap x (start, end) = ({overlap_x_start}, {overlap_x_end})")
            # print(f"overlap z (start, end) = ({overlap_z_start}, {overlap_z_end})")

            overlap_x = overlap_x_end - overlap_x_start
            overlap_z = overlap_z_end - overlap_z_start

            # print(f"overlap x = {overlap_x}")
            # print(f"overlap z = {overlap_z}")

            if overlap_x > 0 and overlap_z > 0:
                overlaps.append(
                    (
                        section,
                        overlap_x_start,
                        overlap_z_start,
                        overlap_x_end,
                        overlap_z_end,
                    )
                )

        # Create new cracked sections for each of these overlaps.
        cracked_sections, max_id = [], 1000000
        for i, (section, x_start, z_start, x_end, z_end) in enumerate(overlaps):
            # print(f"x (start, end) = ({x_start}, {x_end})")
            # print(f"z (start, end) = ({z_start}, {z_end})")
            cracked_section = deepcopy(section)
            cracked_section.id = max_id + i + 1
            y_x = cracked_section.youngs_x()
            cracked_section.youngs_x = lambda: 0.5 * y_x
            cracked_section.start_x_frac = bridge.x_frac(x_start)
            cracked_section.start_z_frac = bridge.z_frac(z_start)
            cracked_section.end_x_frac = bridge.x_frac(x_end)
            cracked_section.end_z_frac = bridge.z_frac(z_end)
            cracked_sections.append(cracked_section)

        bridge.sections = cracked_sections + bridge.sections
Beispiel #6
0
 def wheel_track_xs(self, c: "Config"):
     """Unit load x positions for wheel tracks on this bridge."""
     return round_m(np.linspace(c.bridge.x_min, c.bridge.x_max, c.il_num_loads))
Beispiel #7
0
 def __init__(self, z0: float, z1: float, ltr: bool):
     self.z_min: float = round_m(min(z0, z1))
     self.z_max: float = round_m(max(z0, z1))
     self.ltr: bool = ltr
     self.width = round_m(self.z_max - self.z_min)
     self.z_center = round_m(self.z_min + (self.width / 2))
Beispiel #8
0
 def z_min_max_bottom(self) -> Tuple[float, float]:
     """The min and max z positions for the bottom of this pier."""
     half_bottom = self.width_bottom / 2
     return round_m(self.z - half_bottom), round_m(self.z + half_bottom)
Beispiel #9
0
 def z_min_max_top(self) -> Tuple[float, float]:
     """The min and max z positions for the top of this pier."""
     half_top = self.width_top / 2
     return round_m(self.z - half_top), round_m(self.z + half_top)
Beispiel #10
0
 def y_min_max(self) -> Tuple[float, float]:
     """The min and max y positions for this pier."""
     return round_m(-self.height), 0
Beispiel #11
0
 def x_min_max_top(self) -> Tuple[float, float]:
     """The min and max x positions for the top of this pier."""
     half_length = self.length / 2
     return round_m(self.x - half_length), round_m(self.x + half_length)
Beispiel #12
0
 def get_nodes_at_xy(self, x: float, y: float):
     x, y = round_m(x), round_m(y)
     return self.nodes_by_pos_dict[x][y].values()