Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 38 additions & 129 deletions .github/workflows/build_cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,138 +2,21 @@ name: CMake Build

on:
push:
branches: [master]
branches: [constraint]

pull_request:
branches: [master]
branches: [constraint]

workflow_dispatch:

jobs:
build-win:
name: Build Windows10
runs-on: windows-2019
steps:
- name: 2.1. Obtaining OpenSees Source Code
uses: actions/checkout@v4
with:
fetch-depth: 0
# - name: CMake is already installed
# - name: Git is already installed
- name: Microsoft Visual Studio
uses: ilammy/msvc-dev-cmd@v1
with:
vsversion: 2019
- name: Intel oneAPI Basic & HPC Toolkits
shell: pwsh
env:
WINDOWS_BASEKIT_URL: https://registrationcenter-download.intel.com/akdlm/IRC_NAS/7dff44ba-e3af-4448-841c-0d616c8da6e7/w_BaseKit_p_2024.1.0.595_offline.exe
WINDOWS_BASEKIT_COMPONENTS: intel.oneapi.win.mkl.devel
WINDOWS_HPCKIT_URL: https://registrationcenter-download.intel.com/akdlm/IRC_NAS/c95a3b26-fc45-496c-833b-df08b10297b9/w_HPCKit_p_2024.1.0.561_offline.exe
WINDOWS_HPCKIT_COMPONENTS: "intel.oneapi.win.mpi.devel:intel.oneapi.win.ifort-compiler"
working-directory: D:\a\OpenSees\OpenSees\.github\workflows
run: |
./install_fortran.bat $env:WINDOWS_BASEKIT_URL $env:WINDOWS_BASEKIT_COMPONENTS
./install_fortran.bat $env:WINDOWS_HPCKIT_URL $env:WINDOWS_HPCKIT_COMPONENTS
- name: Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Conan 1.x
run: pip install conan<2.0
- name: MUMPS
shell: cmd
run: |
git clone https://github.com/OpenSees/mumps.git
cd mumps
mkdir build
cd build
call "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" intel64 mod
cmake .. -Darith=d -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" -G Ninja
cmake --build . --config Release --parallel 4
- name: 2.2.2. Building the OpenSees Applications and Python module
shell: cmd
run: |
mkdir build
cd build
conan install .. --build missing --settings compiler="Visual Studio" --settings compiler.runtime="MT" --settings compiler.version=16
call "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" intel64 mod
cmake .. -DBLA_STATIC=ON -DMKL_LINK=static -DMKL_INTERFACE_FULL=intel_lp64 -DMUMPS_DIR="..\..\mumps\build"
cmake --build . --config Release --target OpenSees -j8
cmake --build . --config Release --target OpenSeesPy -j8
- name: Verification OpenSeesPySP
shell: pwsh
run: |
mv ./build/bin/OpenSeesPy.dll ./build/bin/opensees.pyd
cp "C:\Program Files (x86)\Intel\oneAPI\compiler\2024.1\bin\libiomp5md.dll" ./build/bin/
$env:PYTHONPATH = "./build/bin/"
python -c "import sys; print(sys.path)"
python ./EXAMPLES/ExamplePython/example_variable_analysis.py
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: OpenSees_Windows
path: |
./build/bin/OpenSees.exe
./build/bin/opensees.pyd
./build/bin/libiomp5md.dll

build-mac:
name: Build Mac OS
runs-on: macos-latest
timeout-minutes: 30
steps:
- name: 2.1. Obtaining OpenSees Source Code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
# - name: XCode Command Line Tools is already installed.
- name: Install other dependencies via Homebrew
run: |
ln -s /opt/homebrew/bin/gcc-13 /usr/local/bin/gcc
ln -s /opt/homebrew/bin/gfortran-13 /usr/local/bin/gfortran
brew install eigen
brew install hdf5
brew install open-mpi
brew install scalapack
sudo ln -sf /opt/homebrew/include/eigen3/Eigen /opt/homebrew/include/Eigen
- name: MUMPS
run: |
git clone https://github.com/OpenSees/mumps.git
cd mumps
mkdir build
cd build
cmake .. -Darith=d
cmake --build . --config Release --parallel 4
- name: 2.3.2. Building the OpenSees Applications and Python module
run: |
mkdir build
cd build
cmake .. -DMUMPS_DIR=$PWD/../../mumps/build
cmake --build . --target OpenSees -j8
cmake --build . --target OpenSeesPy -j8
mv ./OpenSeesPy.dylib ./opensees.so
- name: Verification OpenSeesPySP
run: |
export PYTHONPATH="./build/"
python3 -c "import sys; print(sys.path)"
python3 ./EXAMPLES/ExamplePython/example_variable_analysis.py
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: OpenSees_Mac
path: |
./build/OpenSees
./build/opensees.so
env:
PYTHONPATH: "./build/lib/:./mylib/"

jobs:
build-ubuntu:
name: Build Ubuntu
runs-on: ubuntu-latest
timeout-minutes: 30
timeout-minutes: 10
steps:
- name: 2.1. Obtaining OpenSees Source Code
uses: actions/checkout@v4
Expand All @@ -146,6 +29,16 @@ jobs:
# - name: Needed Applications and Libraries are already satisfied.
- name: Conan 1.x
run: pip install "conan<2.0"
- name: matplotlib
run: pip install matplotlib
- name: numpy
run: pip install numpy
# - name: scipy
# run: pip install scipy
# - name: vfo
# run: pip install vfo
# - name: xvfb
# run: sudo apt-get install xvfb
- name: 2.4.2. Building the OpenSees Applications and Python module
run: |
mkdir build
Expand All @@ -154,19 +47,35 @@ jobs:
cmake ..
cmake --build . --target OpenSees -j8
cmake --build . --target OpenSeesPy -j8
mv lib/OpenSeesPy.so lib/opensees.so
cd lib
mkdir openseespy
mv OpenSeesPy.so openseespy/opensees.so
# - name: Verification OpenSeesPySP # Simple Sanity Test
# run: |
# export PYTHONPATH="./build/lib/"
# python3 ./EXAMPLES/ExamplePython/example_ground_motion.py
- name: Verification OpenSeesPySP # Simple Sanity Test
run: |
export PYTHONPATH="./build/lib/"
python3 -c "import sys; print(sys.path)"
python3 ./EXAMPLES/ExamplePython/example_variable_analysis.py
xvfb-run python3 ./EXAMPLES/ExamplePython/example_ground_motion.py
# - name: Run headless test
# uses: coactions/setup-xvfb@v1
# with:
# run: python3 ./EXAMPLES/ExamplePython/example_ground_motion.py
# - name: Verification OpenSeesPySP # Simple Sanity Test
# run: |
# export PYTHONPATH="./build/lib/:./mylib/"
# export PYVISTA_OFF_SCREEN=true
# xvfb-run python3 ./EXAMPLES/ExamplePython/example_ground_motion.py
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: OpenSees_Ubuntu
path: |
./build/bin/OpenSees
./build/lib/opensees.so
ground_motion.png
model.png
disp.out
force1.out
force2.out
# # Simple MP sanity test
# - name: Verification OpenSeesPyMP
# run: |
Expand Down
63 changes: 63 additions & 0 deletions EXAMPLES/ExamplePython/example_ground_motion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import openseespy.opensees as ops
import numpy as np

ops.model('basic', '-ndm', 2, '-ndf', 3)
ops.node( 1,-1.0, 0.0); ops.fix(1, 0, 1, 1)
ops.node(11, 0.0, 0.0); ops.fix(11, 1, 1, 1)
ops.node(12, 4.0, 0.0); ops.fix(12, 1, 1, 1)
ops.node(21, 0.0, 2.0)
ops.node(22, 4.0, 2.0)
ops.node(31, 0.0, 4.0)
ops.node(32, 4.0, 4.0)

ops.geomTransf('Linear', 1)
ops.uniaxialMaterial('Steel01', 1, 3e2, 2e5, 0.2)
ops.section('WFSection2d', 1, 1, 0.6, 0.05, 0.3, 0.1, 5, 1)
ops.beamIntegration('Lobatto', 1, 1, 5)
ops.uniaxialMaterial('Steel01', 2, 5e2, 2e5, 0.01)
ops.section('WFSection2d', 2, 2, 0.6, 0.05, 0.3, 0.1, 5, 1)
ops.beamIntegration('Lobatto', 2, 2, 5)

ops.element('forceBeamColumn', 11, 11, 21, 1, 1)
ops.element('forceBeamColumn', 12, 12, 22, 1, 1)
ops.element('elasticBeamColumn', 13, 21, 22, 0.1, 2e5, 0.05, 1)
ops.element('forceBeamColumn', 21, 21, 31, 1, 2)
ops.element('forceBeamColumn', 22, 22, 32, 1, 2)
ops.element('elasticBeamColumn', 23, 31, 32, 0.1, 2e5, 0.05, 1)

ops.equationConstraint(31, 1, 2.0, 21, 1, 1.0, 1, 1, -3.0)

# ops.timeSeries('Linear', 1)
ops.timeSeries('Path', 1, '-time', 0, 10, 30, 50, '-values', 0, 10, -10, 10)
ops.pattern('Plain', 1, 1)
ops.sp(1, 1, 0.01)
ops.constraints('Penalty', 1.0e6, 1.0e6)
ops.integrator('LoadControl', 1.0)
ops.analysis('Static')
ops.recorder('Node', '-file', 'disp.out', '-time', '-node', 21, 31, '-dof', 1, 'disp')
ops.recorder('Element', '-file', 'force1.out', '-time', '-ele', 11, 12, 'force')
ops.recorder('Element', '-file', 'force2.out', '-time', '-ele', 21, 22, 'force')
ops.analyze(50)
ops.wipe()

disp = np.loadtxt('disp.out')
force1 = np.loadtxt('force1.out')
force2 = np.loadtxt('force2.out')
plt.figure()
# plt.plot(disp[:, 1], force1[:, 4] + force1[:, 10], 'o-', label = "Story 1")
# plt.plot(disp[:, 2] - disp[:, 1], force2[:, 4] + force2[:, 10], 'o-', label = "Story 2")
plt.plot(force1[:, 0], force1[:, 4] + force1[:, 10], label = "Story 1")
plt.plot(force2[:, 0], force2[:, 4] + force2[:, 10], label = "Story 2")
plt.xlim(0, 50)
plt.ylim(-40, 40)
plt.xlabel('Time')
plt.ylabel('Shear')
plt.legend()
plt.grid()
# plt.show()

#######
plt.savefig('ground_motion.png')
59 changes: 59 additions & 0 deletions EXAMPLES/example_ground_motion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import openseespy.opensees as ops
import numpy as np

ops.model('basic', '-ndm', 2, '-ndf', 3)
ops.node( 1,-1.0, 0.0); ops.fix(1, 0, 1, 1)
ops.node(11, 0.0, 0.0); ops.fix(11, 1, 1, 1)
ops.node(12, 4.0, 0.0); ops.fix(12, 1, 1, 1)
ops.node(21, 0.0, 2.0)
ops.node(22, 4.0, 2.0)
ops.node(31, 0.0, 4.0)
ops.node(32, 4.0, 4.0)

ops.geomTransf('Linear', 1)
ops.uniaxialMaterial('Steel01', 1, 3e2, 2e5, 0.2)
ops.section('WFSection2d', 1, 1, 0.6, 0.05, 0.3, 0.1, 5, 1)
ops.beamIntegration('Lobatto', 1, 1, 5)
ops.uniaxialMaterial('Steel01', 2, 5e2, 2e5, 0.01)
ops.section('WFSection2d', 2, 2, 0.6, 0.05, 0.3, 0.1, 5, 1)
ops.beamIntegration('Lobatto', 2, 2, 5)

ops.element('forceBeamColumn', 11, 11, 21, 1, 1)
ops.element('forceBeamColumn', 12, 12, 22, 1, 1)
ops.element('elasticBeamColumn', 13, 21, 22, 0.1, 2e5, 0.05, 1)
ops.element('forceBeamColumn', 21, 21, 31, 1, 2)
ops.element('forceBeamColumn', 22, 22, 32, 1, 2)
ops.element('elasticBeamColumn', 23, 31, 32, 0.1, 2e5, 0.05, 1)

ops.equationConstraint(31, 1, 2.0, 21, 1, 1.0, 1, 1, -3.0)

# ops.timeSeries('Linear', 1)
ops.timeSeries('Path', 1, '-time', 0, 10, 30, '-values', 0, 10, -10)
ops.pattern('Plain', 1, 1)
ops.sp(1,1,0.01)
ops.constraints('Penalty', 1.0e6, 1.0e6)
ops.integrator('LoadControl',1.0)
ops.analysis('Static')
ops.recorder('Element', '-file', 'force1.out', '-time', '-ele', 11, 12, 'force')
ops.recorder('Element', '-file', 'force2.out', '-time', '-ele', 21, 22, 'force')
ops.analyze(30)
ops.wipe()

force1 = np.loadtxt('force1.out')
force2 = np.loadtxt('force2.out')
plt.figure()
plt.plot(force1[:, 0], force1[:, 4] + force1[:, 10], label = "Story 1")
plt.plot(force2[:, 0], force2[:, 4] + force2[:, 10], label = "Story 2")
plt.xlim(0, 20)
# plt.ylim(0, 30)
plt.xlabel('Time')
plt.ylabel('Shear')
plt.legend()
plt.grid()
# plt.show()

#######
plt.savefig('ground_motion.png')
Loading