# -*- coding: utf-8 -*- """Shared fixtures, built from the ASPIRE Winter 2019 worked examples. Brown, K. "Calculations for Handling and Shipping Precast Concrete Deck Panels." ASPIRE, Winter 2019, pp. 24-27. The article reproduces PCI Design Handbook Table 8.3.1 and Figure 8.3.2 and works two examples end to end, which makes it the one published check available without a PCI licence. Panel: 10 ft x 32 ft x 8.75 in., normalweight, f'ci = 4000, f'c = 5000, four-point pick at the Figure 8.3.2 locations. """ import sys from pathlib import Path import pytest sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'src')) from panellift.model import Blockout, Lifter, Panel, Rigging, Stage # noqa: E402 from panellift import pci # noqa: E402 WIDTH_FT = 10.0 LENGTH_FT = 32.0 THICKNESS_IN = 8.75 # The article's rounded values, quoted so a failure names the source number. ASPIRE = { 'w_psf': 109.4, 'moment_lbft': 23973.0, 's_solid_in3': 1531.0, 's_pocketed_in3': 1148.0, 'strip_stress_psi': 244.0, 'strip_allowable_psi': 316.0, 'ship_stress_psi': 282.0, 'ship_allowable_psi': 354.0, 'pocketed_strip_stress_psi': 326.0, 'pocketed_ship_stress_psi': 376.0, } def four_point_lifters(length_ft=LENGTH_FT, width_ft=WIDTH_FT): """Two lines of two, at the Figure 8.3.2 equalising positions.""" left, right = pci.optimal_two_line_supports(length_ft) ys = (0.25 * width_ft, 0.75 * width_ft) return [Lifter(mark='L{0}'.format(i + 1), family='TEST_LIFTER', x=x, y=y, role='strip', capacity_lb=8000.0) for i, (x, y) in enumerate([(left, ys[0]), (left, ys[1]), (right, ys[0]), (right, ys[1])])] def make_panel(mark='ASPIRE-1', blockouts=None): """A fresh panel every time. Built by a plain function rather than by one fixture mutating another: pytest caches a fixture per test, so a test asking for both the solid and the pocketed panel would otherwise be handed the same object twice and quietly compare it with itself. """ return Panel( mark=mark, length_ft=LENGTH_FT, width_ft=WIDTH_FT, thickness_in=THICKNESS_IN, unit_weight_pcf=150.0, fci_psi=4000.0, fc_psi=5000.0, finish='smooth', product_type='flat', lifters=four_point_lifters(), blockouts=list(blockouts or []), ) def aspire_pockets(): """Five 6 in. x 24 in. full-depth pockets in one row across the width. The article puts them 'at or near the lifting points' and notes that is not good practice -- it is the location of maximum moment. Five pockets six inches wide take 2.5 ft out of a 10 ft width, giving S = 1148 in^3. """ left, _ = pci.optimal_two_line_supports(LENGTH_FT) return [Blockout(name='P{0}'.format(i + 1), x0=left - 1.0, y0=1.0 + i * 1.5, length=2.0, width=0.5) for i in range(5)] @pytest.fixture def solid_panel(): return make_panel() @pytest.fixture def pocketed_panel(): return make_panel(mark='ASPIRE-2', blockouts=aspire_pockets()) @pytest.fixture def stripping(): return Stage(name='stripping', multiplier=pci.stripping_multiplier('flat', 'smooth'), fc_psi=4000.0) @pytest.fixture def shipping(): return Stage(name='transportation', multiplier=pci.TRANSPORTATION_MULTIPLIER, fc_psi=5000.0) @pytest.fixture def rolling(): return Rigging(mode='rolling', sling_angle_deg=90.0) @pytest.fixture def static_lift(): return Rigging(mode='static', sling_angle_deg=90.0) # ============================================================================ # Appended by tools/make_dist.py -- knowledge-content test exclusion # ============================================================================ # See knowledge/catalogue.yaml's own header. test_safety_factors.py already # self-skips its whole module when knowledge/catalogue.yaml is ABSENT (see # its own pytestmark) -- but this distribution's carve-out ships that file # with `catalogue.inserts` EMPTY, so the file-existence check alone no # longer catches the 1 test(s) below that need real ALP rows in it. # AUTO-DETECTING the same way: real inserts present, and these run normally. _KNOWLEDGE_CONTENT_TESTS = ['test_the_catalogue_publishes_four_to_one_in_shear_for_every_qlpd_row'] def _dist_real_inserts_present(): import io as _io import os as _os here = _os.path.dirname(_os.path.dirname(_os.path.abspath(__file__))) path = _os.path.join(_os.path.dirname(here), 'knowledge', 'catalogue.yaml') try: import yaml as _yaml with _io.open(path, encoding='utf-8') as fh: data = _yaml.safe_load(fh.read()) or {} except Exception: return False return bool(((data.get('catalogue') or {}).get('inserts')) or None) def pytest_collection_modifyitems(config, items): import pytest as _pytest if _dist_real_inserts_present(): return skip = _pytest.mark.skip( reason='knowledge-content test: asserts the owner\'s real product ' 'capacity data, which this distribution does not ship -- ' 'see knowledge/catalogue.yaml\'s header and CONTRIBUTING.md') for item in items: if item.originalname in _KNOWLEDGE_CONTENT_TESTS or item.name in _KNOWLEDGE_CONTENT_TESTS: item.add_marker(skip)