Example 4: Joist prototypes#

The notebook and its PDF are in Examples/Example 4 in the repository.

%matplotlib inline
from decimal import Decimal
from papermodels.paper.pdf import load_pdf_annotations
from papermodels.datatypes.geometry_graph import GeometryGraph
from papermodels.datatypes.joist_models import JoistArrayModel

1. Create the graph#

graph = GeometryGraph.from_pdf_file("sketch_to_scale-vertical-loads.pdf", scale=Decimal(1 / 72 * 4))
graph.assign_collector_behaviour(JoistArrayModel, spacing=1.0)
les = graph.create_loaded_elements()
graph.plot_annotations(2)
../../_images/0b3da907d0e9e23fa2725701c9071451929ec1b76ec4f30b20cd1f8dbf3e9f17.png
les['FB2.1'].model()
{'element_attributes': {'tag': 'FB2.1',
  'length': 18.282,
  'orientation': 'horizontal',
  'vert_correspondent_below': [],
  'vert_correspondent_above': [],
  'horz_intersects_above': ['J2.0'],
  'horz_intersects_below': ['CT2.2', 'CT2.3', 'CT2.4']},
 'element_geometry': {'geometry': 'LINESTRING (33.2588 33.4529, 14.9768 33.4529)',
  'supports': [{'location': 18.107899999999997, 'fixity': 'pin'},
   {'location': 0.47669999999999924, 'fixity': 'roller'},
   {'location': 13.572599999999998, 'fixity': 'roller'}]},
 'loads': {'point_loads': [],
  'distributed_loads': [{'transfer_source': 'J2.0',
    'transfer_reaction_index': 2,
    'occupancy': '',
    'load_components': {},
    'applied_area': 0.0,
    'start_loc': 0.215,
    'start_magnitude': 1.0,
    'end_loc': 18.282,
    'end_magnitude': 1.0,
    'direction': 'gravity'}]}}
# Note: The "Wall bottom" annotation transfers as a line load onto the FB2.2 beam and not onto the WT1.0 element on the page below
# The extent of the distributed load matches its location on the FB2.2 beam
# J2.0 is a joist prototype: JoistArrayModel generates J2.0-0, J2.0-1, ...
les['J2.0-0'].model()
{'element_attributes': {'tag': 'J2.0',
  'length': 11.515100000000004,
  'orientation': 'horizontal',
  'vert_correspondent_below': [],
  'vert_correspondent_above': [],
  'horz_intersects_above': [],
  'horz_intersects_below': ['FB2.0', 'FB2.1', 'FB2.2']},
 'element_geometry': {'geometry': 'LINESTRING (24.4456 33.6833, 24.4456 22.1682)',
  'supports': [{'location': 0.13180000000000192, 'fixity': 'pin'},
   {'location': 11.2847, 'fixity': 'roller'},
   {'location': 5.694400000000002, 'fixity': 'roller'}]},
 'loads': {'point_loads': [],
  'distributed_loads': [{'transfer_source': '',
    'transfer_reaction_index': '',
    'occupancy': 'residential',
    'load_components': [],
    'applied_area': 11.515100000001004,
    'start_loc': 0,
    'start_magnitude': 0.086842,
    'end_loc': 11.515099999999004,
    'end_magnitude': 0.086842}]}}

2. Output the model files#

Each LoadedElement is written to a JSON file, which can be read back into a dictionary with the standard library json module.

import pathlib
output_dir = pathlib.Path("model_files") / "json"
output_dir.mkdir(parents=True, exist_ok=True)

for tag, loaded_element in les.items():
    with open(output_dir / f"{tag}.json", "w") as file:
        loaded_element.dump_json(file)