# -*- coding: utf-8 -*- """An opening that all but reaches an edge must not leave a fibre behind. A real piece had an opening drawn to 11.1041 ft on a panel 11.1042 ft wide. The 0.001 in of concrete left over was, arithmetically, the outermost material in the section -- so every in-plane stress was reported at a fibre 110 in from the centroid instead of 23 in, on a sliver nothing could be cast into. The piece came back at 432 psi where a commercial check of the same piece said 162, and it was one of only two failures in a 194-piece sweep. The stress at a fibre that is not really there is a stress nobody has. """ import pytest from panellift import section from panellift.model import Blockout from conftest import make_panel def _panel_with_opening(gap_ft): """A panel whose only opening stops `gap_ft` short of the far edge.""" panel = make_panel() panel.blockouts = [Blockout( name='O1', x0=10.0, y0=3.0, length=4.0, width=panel.width_ft - 3.0 - gap_ft)] return panel @pytest.mark.parametrize('gap_ft', [0.0, 1e-4, 1e-3, 0.004]) def test_a_drafting_sliver_is_not_the_extreme_fibre(gap_ft): """Whether the opening lands exactly on the edge or a thousandth short, the section has to be the same piece of concrete.""" exact = section.NetSection(_panel_with_opening(0.0), 12.0) nearly = section.NetSection(_panel_with_opening(gap_ft), 12.0) assert nearly.width_in == pytest.approx(exact.width_in, abs=0.1) assert nearly.y_extremes_in[1] == pytest.approx(exact.y_extremes_in[1], abs=0.1) assert nearly.iy_in4 == pytest.approx(exact.iy_in4, rel=0.01) def test_the_extreme_fibre_is_inside_the_concrete(): """The outermost fibre cannot be further from the centroid than the material is. This is what the sliver broke: 110 in of lever arm on a section only 46 in wide.""" net = section.NetSection(_panel_with_opening(1e-3), 12.0) reach = max(abs(v) for v in net.y_extremes_in) assert reach <= net.width_in, ( 'extreme fibre %.1f in from the centroid, but the section is only ' '%.1f in wide' % (reach, net.width_in)) def test_an_opening_well_short_of_the_edge_keeps_its_strip(): """The snap is a noise floor, not a licence to delete real concrete. A strip an inch and a half wide is still a strip.""" panel = _panel_with_opening(0.125) # 1.5 in of concrete left net = section.NetSection(panel, 12.0) strips = section.strips_at(panel, 12.0) assert len(strips) == 2 assert net.y_extremes_in[1] > 0.5 * panel.width_ft * 12.0