jerbaroo / bridge-sim

Python library for concrete slab bridge simulation.
MIT License
1 stars 0 forks source link

This document provides installation instructions and usage examples.

API documentation is available at [[https://jerbaroo.github.io/bridge-sim]]

Table of Contents

If you are interested in using this library, please open an issue to ask any questions (one issue per question)! I welcome all feedback, so don't hesitate to communicate any thoughts. Please star the project if you like it. Read the [[./LICENSE][license]] before use.

[[./data/images/animation.png]] ** Installation Three installation methods are provided. You can install =bridge-sim= from PyPI using your preferred Python package manager. We also provide a Docker image with =bridge-sim= and all dependencies already installed. And finally you can clone this repository if you intend on contributing to the =bridge-sim= project. *** PyPI First make sure you are using Python 3.8+. You will also need [[https://opensees.berkeley.edu/][OpenSees]] to run FE simulations which you can download [[https://opensees.berkeley.edu/OpenSees/user/download.php][here]]. If you are installing OpenSees on Linux then the top answer [[https://www.researchgate.net/post/How_to_install_opensees_in_UBUNTU][here]] may be of some help.

Using pip: inside your Python virtual environment run this command =pip install bridge-sim=.

If you are starting a project from scratch I recommend the [[https://python-poetry.org/docs/][Poetry]] package manager. Initialize a project named /foobar/ with =poetry new foobar && cd foobar=, then add =bridge-sim= as a dependency with =poetry add bridge-sim=.

Now that you have =bridge-sim= installed you probably want to run some code, for that see the examples section [[#examples][below]]. *** Docker Make sure you have [[https://docs.docker.com/get-docker/][Docker]] installed. Then in a terminal run the following to jump into a Docker image that already has all dependencies installed:

+BEGIN_SRC bash

$ docker run -it jerbaroo/bridge-sim:v0.0.8.9

+END_SRC

You are now in the =/bridge-sim= directory of the Docker container. You can run the provided example file =example.py= with =poetry run python example.py=. This will generate a file =/root/docker-1.png=.

To copy =docker-1.png= to your host system run the following commands in another terminal. The first command lists all running Docker containers. Copy the container ID and then use the =docker cp= command to copy =docker-1.png= to your host system.

+BEGIN_SRC bash

$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d297a50ff165 jerbaroo/bridge-sim:v0.0.8.9 "/bin/bash" 37 seconds ago Up 37 seconds vigorous_leavitt $ docker cp d297a50ff165:/root/docker-1.png docker-1.png

+END_SRC

The Docker image that you enter with =docker run= has OpenSees installed at =/root/bin/OpenSees=. The =bridge-sim= source code along with all installed Python dependencies are in =/bridge-sim=. We have shown how to run the provided =example.py= file but you could modify this file and run a different example, some examples are provided [[#examples][below]]. **** Lisa

These instructions may be useful if you are running simulations on the [[https://userinfo.surfsara.nl/systems/lisa][SURF SARA Lisa]] cluster or another system that supports [[https://sylabs.io/docs/#singularity][Singularity]].

Once you have SSHed into the Lisa cluster you can build a Singularity image of =bridge_sim= on Lisa with =singularity pull docker://jerbaroo/bridge-sim:v0.0.8.9=. If the =pull= command fails or the generated =.sif= file is corrupted then try deleting the =.sif= file and run the =pull= command again.

To run a simulation you need a script to interact with the scheduler. See [[docker/run-lisa.sh][run-lisa.sh]] for an example of such a script and see the Lisa [[https://userinfo.surfsara.nl/systems/lisa/user-guide/creating-and-running-jobs][user guide]] for further instructions. The way I use the =run-lisa.sh= script, is I configure scheduling parameters in the =run-lisa.sh= script but define my actual job in a second script [[docker/sim.sh][sim.sh]].

To view jobs in the queue I run =squeue | grep brjeremy=, where =brjeremy= is my username. Job output is saved in a =slurm-XXXXX.out= file where =XXXXX= is the job ID. I always delete the output from old jobs, so to delete the old output and run a new job I type =rm slurm*.out; sbatch run-lisa.sh=. Then the output can be viewed with =cat slurm-XXXXX.out=. To cancel a job run =scancel XXXXX=.

*** Development First make sure you are using Python 3.8+ and [[https://python-poetry.org/docs/][install Poetry]]. You will also need [[https://opensees.berkeley.edu/][OpenSees]] to run FE simulations which you can download [[https://opensees.berkeley.edu/OpenSees/user/download.php][here]]. If you are installing OpenSees on Linux then the top answer [[https://www.researchgate.net/post/How_to_install_opensees_in_UBUNTU][here]] may be of some help.

Now clone this repository, change into the directory and once in the =bridge-sim= directory install project dependencies:

+BEGIN_SRC bash

$ git clone https://github.com/jerbaroo/bridge-sim $ cd bridge-sim $ poetry install

+END_SRC

* Installation notes After installation you can find your poetry created virtual environment by using =poetry show -v=. You might need to add the path to the python executable manually in your IDE. Introduction A brief introduction to some of the Python classes provided. A =Bridge= describes the material properties, geometry and boundary conditions of a bridge. A =FEMRunner= is capable of transforming a =Bridge= along with some additional simulation parameters into a model file, running that file, and returning the responses from simulation. This project currently provides one instance of =FEMRunner= which is called =OSRunner= and is capable of running simulations with OpenSees. A =Config= contains some additional global configuration but is also used as a container for a =Bridge= and =FEMRunner=. This is useful because all three of these objects are required in many situations and combining them into one object makes life a bit easier than passing these three objects around separately.

[[./data/images/config-composition.png]]

** Examples If you have managed to install the software then the next step is to run an example such as =example.py=. You will need to make sure that OpenSees is on your PATH, if you have followed the Docker installation instructions then this is already done for you. The file =example.py= can be run with =poetry run python example.py=. *** Example 1: applying a point load Narrow example bridge with a single point load applied.

+BEGIN_SRC python

import matplotlib.pyplot as plt from bridge_sim import bridges, configs, model, plot, sim

config = configs.opensees_default(bridges.bridge_narrow) point_loads = [model.PointLoad(x=5, z=0, load=100)] responses = sim.responses.load(config, model.RT.YTrans, point_loads) plot.contour_responses(config, responses, point_loads) plot.top_view_bridge(config.bridge, piers=True) plt.tight_layout() plt.show()

+END_SRC

*** Example 2: defining a vehicle Narrow example bridge with a 5-axled vehicle on it, each wheel is a point load.

+BEGIN_SRC python

import matplotlib.pyplot as plt from bridge_sim import bridges, configs, model, plot, sim

config = configs.opensees_default(bridges.bridge_narrow, shorten_paths=True) point_loads = model.Vehicle(

Load intensity of each axle.

load=[5000, 4000, 4000, 5000, 7000],
# Distance between each pair of axles.
axle_distances=[2, 2, 2, 1],
# Width of each axle, distance between point loads.
axle_width=2.5,
# Speed of the vehicles.
kmph=20,

).point_load_pw(config=config, time=3.5, list=True) responses = sim.responses.load(config, model.RT.YTrans, point_loads) plot.contour_responses(config, responses, point_loads) plot.top_view_bridge(config.bridge, piers=True) plt.tight_layout() plt.show()

+END_SRC

*** Example 3: pier settlement Wide example bridge with two supporting piers, one pier settled by 1.2 m.

+BEGIN_SRC python

import matplotlib.pyplot as plt from bridge_sim import bridges, configs, sim, model, plot

config = configs.opensees_default(bridges.bridge_wide) responses = sim.responses.load( config, model.RT.YTrans, pier_settlement=[model.PierSettlement(0, 1.2)] ) plot.contour_responses(config, responses) plot.top_view_bridge(config.bridge, piers=True) plt.tight_layout() plt.show()

+END_SRC

*** Example 4: multiple response types Like the previous pier settlement example but plotting multiple response types.

+BEGIN_SRC python

import matplotlib.pyplot as plt from bridge_sim import bridges, configs, model, plot, sim

config = configs.opensees_default(bridges.bridge_wide) plt.figure(figsize=(12, 8)) for subplot, response_type in enumerate([ model.RT.YTrans, model.RT.ZTrans, model.RT.StrainXXB, model.RT.StrainZZB, ]): responses = sim.responses.load( config, response_type, pier_settlement=[model.PierSettlement(0, 1.2)], ) plt.subplot(2, 2, subplot + 1) plot.contour_responses(config, responses, interp=(200, 60)) plot.top_view_bridge(config.bridge, piers=True) plt.title(response_type.name()) plt.tight_layout() plt.show()

+END_SRC

*** Example 5: defining a bridge Like the first point-load example but with a custom square bridge.

+BEGIN_SRC python

import matplotlib.pyplot as plt from bridge_sim import bridges, configs, model, plot, sim from bridge_sim.bridges import Bridge, Lane, MaterialDeck, MaterialSupport, Support

def new_bridge(): return Bridge( name="square", # Name used to identify saved/loaded data. msl=0.5, # Maximum shell length. length=10, # Length of this bridge. width=10, # Width of this bridge. supports=[ Support( x=5, # X position of center of the support. z=0, # Z position of center of the support. length=2, # Length between support columns (X direction). height=2, # Height from top to bottom of support. width_top=2, # Width of support column at top (Z direction). width_bottom=1, # Width of support column at bottom (Z direction). materials=[ # List of materials for the support columns. MaterialSupport( density=0.7, thickness=0.7, youngs=40000, poissons=0.2, start_frac_len=0, ) ], fix_z_translation=True, fix_x_translation=True, ) ],

List of materials for the bridge deck.

    materials=[MaterialDeck(thickness=0.7, youngs=40000, poissons=0.2,)],
    # List of lanes where traffic can drive on the bridge.
    lanes=[Lane(-1, 1, True)],
)

config = configs.opensees_default(new_bridge) point_loads = [model.PointLoad(x=8, z=0, load=100)] responses = sim.responses.load(config, model.RT.YTrans, point_loads) plot.contour_responses(config, responses, point_loads) plot.top_view_bridge(config.bridge, piers=True, lanes=True) plt.tight_layout() plt.show()

+END_SRC

*** Example 6: generating traffic Generate 10 seconds of traffic and animate it moving over bridge 705.

+BEGIN_SRC python

from bridge_sim import bridges, configs, plot, traffic

config = configs.opensees_default(bridges.bridge_705(0.5)) time = 10 config.sensor_freq = 1 / 10 traffic_scenario = traffic.normal_traffic(config) traffic_sequence = traffic_scenario.traffic_sequence(config, time) traffic = traffic_sequence.traffic() plot.animate.animate_traffic( config=config, traffic_sequence=traffic_sequence, traffic=traffic, save="animation.mp4" )

+END_SRC

*** Example 7: animating traffic flow First generating traffic. Then animating the responses of the bridge to that traffic, to pier settlement, to temperature effect and to shrinkage.

NOTE: This example will a long time to run because responses are calculated based on superposition of many "unit" load simulations that must be run.

+BEGIN_SRC python

from bridge_sim import bridges, configs, model, plot, temperature, traffic

config = configs.opensees_default(bridges.bridge_705(10), il_num_loads=100) time = 10 config.sensor_freq = 1 / 10 traffic_scenario = traffic.normal_traffic(config) traffic_sequence = traffic_scenario.traffic_sequence(config, time) weather = temperature.load("holly-springs-19") weather["temp"] = temperature.resize(weather["temp"], tmin=-5, tmax=35) plot.animate.animate_responses( config=config, traffic_sequence=traffic_sequence, response_type=model.ResponseType.YTrans, units="mm", save="traffic-responses.mp4", pier_settlement=[ (model.PierSettlement(4, 1.2), model.PierSettlement(4, 2))], weather=weather, start_date="01/05/2019 00:00", end_date="01/05/2019 23:59", install_day=30, start_day=365, end_day=366, with_creep=True, )

+END_SRC

*** Example 8: contour plot of temperature effect Contour plot of temperature when the bottom and top temperatures of the bridge are 20 and 22 degrees celcius respectively.

+BEGIN_SRC python

import matplotlib.pyplot as plt import numpy as np from bridge_sim import bridges, configs, model, sim, plot, temperature

config = configs.opensees_default(bridges.bridge_705(msl=10)) bridge = config.bridge response_type = model.RT.StrainXXB

points = [ model.Point(x=x, y=0, z=z) for x in np.linspace(bridge.x_min, bridge.x_max, num=int(bridge.length 2)) for z in np.linspace(bridge.z_min, bridge.z_max, num=int(bridge.width 2)) ] temp_effect = temperature.effect( config=config, response_type=response_type, points=points, temps_bt=[[20], [22]] ).T[0] # Only considering a single temperature profile. responses = sim.model.Responses( # Converting to "Responses" for plotting. response_type=response_type, responses=[(temp_effect[p], points[p]) for p in range(len(points))], ).without_nan_inf() plot.contour_responses(config, responses) plot.top_view_bridge(config.bridge, piers=True) plt.tight_layout() plt.show()

+END_SRC

*** Example 9: time series of temperature effect Generating traffic, then calculating time series of responses to that traffic over a wide example bridge. Then also calculating the responses to temperature.

NOTE: This example will a long time to run because responses are calculated based on superposition of many "unit" load simulations that must be run.

+BEGIN_SRC python

import matplotlib.pyplot as plt from bridge_sim import bridges, configs, model, sim, temperature, traffic

config = configs.opensees_default(bridges.bridge_705(10), il_num_loads=100) points = [model.Point(x=10), model.Point(x=20)] response_type = model.RT.YTrans

First generate some traffic data.

traffic_sequence = traffic.normal_traffic(config).traffic_sequence(config, 10) traffic_array = traffic_sequence.traffic_array() responses_to_traffic = sim.responses.to_traffic_array( config=config, traffic_array=traffic_array, response_type=response_type, points=points, )

And responses to temperature.

weather = temperature.load("holly-springs-19") weather["temp"] = temperature.resize(weather["temp"], tmin=-5, tmax=31) temp_responses = sim.responses.to_temperature( config=config, points=points, responses_array=responses_to_traffic, response_type=response_type, weather=weather, start_date="01/05/2019 00:00", end_date="02/05/2019 00:00", )

plt.plot((responses_to_traffic + temp_responses).T) plt.show()

+END_SRC