Substepping method for LoadControl and Displacement Control Analysis

# OpenSeesPy Sub-Stepping Methods

## Project and Purpose

There are 4 sequential divisions(/2, /4, /8, /16). From v0.1.2.0 user can define the substepping factors.

```DispControlSubStep(Nsteps:int , IDctrlNode:int, IDctrlDOF:int, Dmax:float, fac1=2, fac2=4, fac3=8, fac4=16, LoadConstandTimeZero=False)
```

## How to use

```pip install OpenSeesPySubStepping
```

Find the project release @Pypi.org

## Versions

### v0.1.2.0

• Substepping factors can be modified be the user.
Note: Default substepping factors are 1/2, 1/4, 1/8, 1/16

### v0.1.1.2

• Update REAME.md with example
• Example folder
• Add github workflow in order to publish library to pypi.org

## Example

```import openseespy.opensees as ops
from OpenSeesPySubStepping import DispControlSubStep

def main():
"""
Create a Cantilever Problem
"""

ops.wipe()
ops.model('basic', '-ndm', 2, '-ndf', 3)
height = 5.0
nElem = 20

ElemLength = height / nElem
nodeID = []
Ycoord = 0
for i in range(nElem + 1):
nodeID.append(i)
ops.node(i, 0.0, Ycoord)
Ycoord += ElemLength
IDctrlNode = i

ops.fix(0, 1, 1, 1)
ops.geomTransf('Linear', 1)

concrete = 'Concrete04'
steel = 'Steel02'

matTAGConc = 319
matTAGSteel = 312
fcc = -20000
ec2c = -0.002
ecu2c = -0.0035
Ec = 30000000
fct = 2200
et = 0.001
fy = 500000
E0 = 200000000
b = 0.01
ops.uniaxialMaterial(concrete, matTAGConc, fcc, ec2c, ecu2c, Ec, fct, et)
ops.uniaxialMaterial(steel, matTAGSteel, fy, E0, b, 20, 0.925, 0.15, 0, 1, 0, 1, 0)

# Core Fibers
ops.section('Fiber', 105)
ops.patch('rect', 319, 11, 11, -0.20, -0.20, 0.20, 0.20)
# Cover Fibers
ops.patch('rect', 319, 15, 2, 0.250000, 0.200000, -0.250000, 0.250000)
ops.patch('rect', 319, 15, 2, 0.250000, -0.250000, -0.250000, -0.200000)
ops.patch('rect', 319, 2, 11, -0.250000, -0.200000, -0.200000, 0.200000)
ops.patch('rect', 319, 2, 11, 0.200000, -0.200000, 0.250000, 0.200000)
# create corner bars
ops.layer('straight', 312, 4, 0.00025450, 0.200000, 0.200000, -0.200000, 0.200000)
ops.layer('straight', 312, 4, 0.00025450, 0.200000, -0.200000, -0.200000, -0.200000)
ops.beamIntegration('Lobatto', 100, 105, 3)

for i in range(len(nodeID) - 1):
ops.element('forceBeamColumn', i, nodeID[i], nodeID[i + 1], 1, 100, '-iter', 10, 1e-6)

ops.timeSeries('Linear', 101)
ops.pattern('Plain', 100, 101)

# Solve Gravity First
ops.system('UmfPack')
ops.numberer('Plain')
ops.constraints('Transformation')
ops.test('RelativeTotalNormDispIncr', 0.001, 100, 2)
ops.algorithm('Newton')
ops.analysis('Static')

# Displacement Control Analysis(Pushover)
ops.pattern('Plain', 200, 101)
ops.system('UmfPack')
ops.numberer('Plain')
ops.constraints('Transformation')
ops.test('RelativeTotalNormDispIncr', 1e-2, 500, 2)
ops.algorithm('Newton')
ops.analysis('Static')
DispControlSubStep(100, IDctrlNode, 1, 1.0)

if __name__ == '__main__':
main()
```

## Project details

Uploaded `source`
Uploaded `py3`