diff --git a/examples/SpaceTruss/space_truss.py b/examples/SpaceTruss/space_truss.py new file mode 100644 index 0000000..fd0ec8a --- /dev/null +++ b/examples/SpaceTruss/space_truss.py @@ -0,0 +1,52 @@ +import numpy as np +import opensees.openseespy as ops + +def space_truss(ns, Ro, Ri, H): + """Generate a 3D truss""" + + model = ops.Model(3,3) + m1 = model.material('default', 1.0) + s1 = model.xsection('default', 1.0, 1.0) + + # Specify node coordinates for support points + # angle for supports + phi = np.arange(ns)/ns*2*np.pi + + # Coordinates for support points + X = np.cos(phi)*Ro + Y = np.sin(phi)*Ro + # Generate support points with height Z of 0 + for i in range(ns): + model.node(i+1, X[i], Y[i], 0.0) + + # Angles for upper ring (offset by pi/ns degrees from supports) + phi = phi+np.pi/ns + + # Coordinates for upper ring + X = np.append(X, np.cos(phi)*Ri) + Y = np.append(Y, np.sin(phi)*Ri) + + # Generate coordinates for upper ring with height H + for i in np.arange(ns, 2*ns): + model.node(i+1, X[i], Y[i], H) + + for i, j, k in zip(np.arange(ns), np.arange(0, ns), np.arange(ns, 2*ns)): + model.element("Truss", i+1, j, k, m1, s1) + + model.element("Truss", alpha[ns+1], 0, 2*ns-1, m1, s1) + + for i, j, k in zip(np.arange(ns+1, 2*ns), np.arange(1, ns), np.arange(ns, 2*ns-1)): + model.element("Truss", i+1, j, k, m1, s1) + + for i, j, k in zip(np.arange(2*ns, 3*ns-1), np.arange(ns, 2*ns-1), np.arange(ns+1, 2*ns)): + model.element("Truss", i+1, j, k, m1, s1) + + model.element("Truss", 3*ns, ns, 2*ns-1, m1, s1) + + + # boundary conditions + for node in range(ns): + model.fix(node, (1, 1, 1)) + + + return model diff --git a/examples/chopra-10.4/index.html b/examples/chopra-10.4/index.html index cb011b9..31b1c20 100644 --- a/examples/chopra-10.4/index.html +++ b/examples/chopra-10.4/index.html @@ -389,13 +389,13 @@

Instructions on how to run this Python Tcl @@ -411,7 +411,7 @@

Instructions on how to run this -
+
python EigenAnal_twoStoryShearFrame8.py
 
@@ -423,7 +423,7 @@

Instructions on how to run this -
+
python -m opensees EigenAnal_twoStoryShearFrame8.tcl
 
@@ -451,13 +451,13 @@

Create the model

Python Tcl @@ -473,7 +473,7 @@

Create the model

-
+
import opensees.openseespy as ops
 
@@ -487,7 +487,7 @@ 

Create the model

-
+
model BasicBuilder -ndm 2 -ndf 3
 
@@ -515,13 +515,13 @@

Create the model

Python Tcl @@ -537,7 +537,7 @@

Create the model

-
+
model.node(1, 0.,   0.)
 model.node(2, L ,   0.)
@@ -554,7 +554,7 @@ 

Create the model

-
+
node 1 0. 0. ;
 node 2 $L 0. ;
@@ -584,13 +584,13 @@ 

Create the model

Python Tcl @@ -606,7 +606,7 @@

Create the model

-
+
model.fix(1, 1, 1, 1)
 model.fix(2, 1, 1, 1)
@@ -619,7 +619,7 @@ 

Create the model

-
+
fix 1 1 1 1; 
 fix 2 1 1 1; 
@@ -647,13 +647,13 @@ 

Create the model

Python Tcl @@ -669,7 +669,7 @@

Create the model

-
+
model.mass(3,  m  , 0., 0. ) 
 model.mass(4,  m  , 0., 0. ) 
@@ -684,7 +684,7 @@ 

Create the model

-
+
mass 3 $m 0. 0. ; 
 mass 4 $m 0. 0. ; 
@@ -717,13 +717,13 @@ 

Create the model

Python Tcl @@ -739,7 +739,7 @@

Create the model

-
+
model.element("ElasticBeamColumn", 1, 1, 3, Ac, Ec, 2.*Ic, TransfTag)
 model.element("ElasticBeamColumn", 2, 3, 5, Ac, Ec,    Ic, TransfTag)
@@ -756,7 +756,7 @@ 

Create the model

-
+
element elasticBeamColumn 1 1 3 $Ac $Ec [expr 2.*$Ic] $TransfTag; 
 element elasticBeamColumn 2 3 5 $Ac $Ec $Ic $TransfTag; 
@@ -794,13 +794,13 @@ 

Create the model

Python Tcl @@ -816,7 +816,7 @@

Create the model

-
+
for k in range(numModes):
     model.recorder("Node", f"eigen {k}", file=f"modes/mode{k}.out", nodeRange=[1, 6], dof=[1, 2, 3])
@@ -829,7 +829,7 @@ 

Create the model

-
+
foreach k [range $numModes] {
   recorder Node -file [format "modes/mode%i.out" $k] -nodeRange 1 6 -dof 1 2 3 "eigen $k" 
diff --git a/examples/example1/index.html b/examples/example1/index.html
index c1dab1f..9b6e29a 100644
--- a/examples/example1/index.html
+++ b/examples/example1/index.html
@@ -373,13 +373,13 @@ 

Model

Python Tcl @@ -395,7 +395,7 @@

Model

-
+
import opensees.openseespy as ops
 
@@ -409,7 +409,7 @@ 

Model

-
+
model -ndm 2 -ndf 2
 
@@ -436,13 +436,13 @@

Model

Python Tcl @@ -458,7 +458,7 @@

Model

-
+
# Create nodes
 #         tag   X     Y
@@ -475,7 +475,7 @@ 

Model

-
+
# Create nodes & add to domain
 #   tag  X    Y
@@ -504,13 +504,13 @@ 

Model

Python Tcl @@ -526,7 +526,7 @@

Model

-
+
# set the boundary conditions
 #    nodeID xRestrnt? yRestrnt?
@@ -542,7 +542,7 @@ 

Model

-
+
# Set the boundary conditions
 #  tag  X  Y
@@ -572,13 +572,13 @@ 

Model

Python Tcl @@ -594,7 +594,7 @@

Model

-
+
# Create Elastic material prototype
 model.uniaxialMaterial("Elastic", 1, 3000)
@@ -607,7 +607,7 @@ 

Model

-
+
# Create Elastic material prototype
 uniaxialMaterial Elastic 1 3000;
@@ -639,13 +639,13 @@ 

Model

Python Tcl @@ -661,7 +661,7 @@

Model

-
+
#              Type   tag  nodes  Area  material
 model.element("Truss", 1, (1, 4), 10.0,    1   )
@@ -676,7 +676,7 @@ 

Model

-
+
element Truss 1 1 4 10.0 1;
 element Truss 2 2 4  5.0 1;
@@ -710,13 +710,13 @@ 

Loads

Python Tcl @@ -732,7 +732,7 @@

Loads

-
+
loads = {4: [100, -50]}
 
@@ -744,7 +744,7 @@

Loads

-
+
set loads {4 100 -50}
 
@@ -769,13 +769,13 @@

Loads

Python Tcl @@ -791,7 +791,7 @@

Loads

-
+
model.pattern("Plain", 1, "Linear", load=loads)
 
@@ -803,7 +803,7 @@

Loads

-
+
pattern Plain 1 "Linear" "load $loads"
 
@@ -828,13 +828,13 @@

Loads

Python Tcl @@ -850,7 +850,7 @@

Loads

-
+
model.pattern("Plain", 1, "Linear", load={
   4: [100, -50]
@@ -864,7 +864,7 @@ 

Loads

-
+
pattern Plain 1 "Linear" {
   load 4 100 -50
@@ -892,13 +892,13 @@ 

Analysis

Python Tcl @@ -914,7 +914,7 @@

Analysis

-
+
model.algorithm("Linear")
 
@@ -926,7 +926,7 @@

Analysis

-
+
algorithm Linear;
 
@@ -953,13 +953,13 @@

Analysis

Python Tcl @@ -975,7 +975,7 @@

Analysis

-
+
model.integrator("LoadControl", 1.0)
 
@@ -987,7 +987,7 @@

Analysis

-
+
integrator LoadControl 1.0;
 
@@ -1017,13 +1017,13 @@

Analysis

Python Tcl @@ -1039,7 +1039,7 @@

Analysis

-
+
model.analysis("Static")
 
@@ -1051,7 +1051,7 @@

Analysis

-
+
analysis Static;
 
@@ -1074,13 +1074,13 @@

Analysis

Python Tcl @@ -1096,7 +1096,7 @@

Analysis

-
+
model.analyze(1)
 
@@ -1108,7 +1108,7 @@

Analysis

-
+
analyze 1
 
@@ -1132,13 +1132,13 @@

Analysis

Python Tcl @@ -1154,7 +1154,7 @@

Analysis

-
+
model.print(node=4)
 model.print("ele")
@@ -1167,7 +1167,7 @@ 

Analysis

-
+
print node 4
 print ele
diff --git a/examples/example2/index.html b/examples/example2/index.html
index 143201c..daa676b 100644
--- a/examples/example2/index.html
+++ b/examples/example2/index.html
@@ -370,13 +370,13 @@ 

Modeling

Python Tcl @@ -392,7 +392,7 @@

Modeling

-
+
  1. Example2.py
  2. @@ -406,7 +406,7 @@

    Modeling

    -
    +
    1. Example2.tcl
    2. @@ -445,13 +445,13 @@

      Modeling

      Python Tcl @@ -467,7 +467,7 @@

      Modeling

      -
      +
      model.section("Fiber", 1)
       # Create the concrete core fibers
      @@ -490,7 +490,7 @@ 

      Modeling

      -
      +
      section Fiber 1 {
       
      diff --git a/examples/example3/index.html b/examples/example3/index.html
      index 6da27ef..a91af75 100644
      --- a/examples/example3/index.html
      +++ b/examples/example3/index.html
      @@ -368,13 +368,13 @@ 

      Python Tcl @@ -390,7 +390,7 @@

      -
      +
      1. portal.py
      2. @@ -404,7 +404,7 @@

        -
        +
        1. portal.tcl
        2. @@ -466,13 +466,13 @@

          create_portal

          Python Tcl @@ -488,7 +488,7 @@

          create_portal

          -
          +
          # create ModelBuilder (with two-dimensions and 3 DOF/node)
           model = ops.Model(ndm=2, ndf=3)
          @@ -513,7 +513,7 @@ 

          create_portal

          -
          +
          set width    360
           set height   144
          @@ -553,13 +553,13 @@ 

          create_portal

          Python Tcl @@ -575,7 +575,7 @@

          create_portal

          -
          +
          # Define materials for nonlinear columns
           # ------------------------------------------
          @@ -600,7 +600,7 @@ 

          create_portal

          -
          +
          
           # Define materials for nonlinear columns
          @@ -640,13 +640,13 @@ 

          create_portal

          Python Tcl @@ -662,7 +662,7 @@

          create_portal

          -
          +
           # Define cross-section for nonlinear columns
            # ------------------------------------------
          @@ -697,7 +697,7 @@ 

          create_portal

          -
          +
          # Define cross-section for nonlinear columns
           # ------------------------------------------
          @@ -754,13 +754,13 @@ 

          gravity_analysis

          Python Tcl @@ -776,7 +776,7 @@

          gravity_analysis

          -
          +
          # Create the model
           model = create_portal()
          @@ -792,7 +792,7 @@ 

          gravity_analysis

          -
          +
          create_portal;
           gravity_analysis;
          @@ -817,13 +817,13 @@ 

          gravity_analysis

          Python Tcl @@ -839,7 +839,7 @@

          gravity_analysis

          -
          +
          model.pattern("Plain", 1, "Linear", loads={
           # nodeID  xForce yForce zMoment
          @@ -855,7 +855,7 @@ 

          gravity_analysis

          -
          +
          @@ -935,13 +935,13 @@

          transient_analysis

          Python Tcl @@ -957,7 +957,7 @@

          transient_analysis

          -
          +
          model.loadConst(time=0.0)
           
          @@ -969,7 +969,7 @@

          transient_analysis

          -
          +
          loadConst -time 0.0
           
          diff --git a/examples/example4/index.html b/examples/example4/index.html index d38a82c..011f2ac 100644 --- a/examples/example4/index.html +++ b/examples/example4/index.html @@ -352,13 +352,13 @@

          Example 4.1

          Python Tcl @@ -374,7 +374,7 @@

          Example 4.1

          -
          +
          1. Example4.py
          2. @@ -388,7 +388,7 @@

            Example 4.1

            -
            +
            1. Example4.tcl
            2. diff --git a/examples/example7/gravity.glb b/examples/example7/gravity.glb index 9e90dea..115bd4e 100644 Binary files a/examples/example7/gravity.glb and b/examples/example7/gravity.glb differ diff --git a/examples/example7/model.glb b/examples/example7/model.glb index 6f9143f..422257f 100644 Binary files a/examples/example7/model.glb and b/examples/example7/model.glb differ diff --git a/examples/example7/render.py b/examples/example7/render.py index f61ca71..63f892a 100644 --- a/examples/example7/render.py +++ b/examples/example7/render.py @@ -32,5 +32,5 @@ ) # sees.serve(artist) -# artist.save("gravity.glb") + artist.save("gravity.glb") diff --git a/examples/framebuckling/buckling.py b/examples/framebuckling/buckling.py index 86c1bbd..b497dc3 100644 --- a/examples/framebuckling/buckling.py +++ b/examples/framebuckling/buckling.py @@ -39,7 +39,7 @@ def buckle_factor(boundary, phi=0): return 2*np.pi if boundary == "fix-pin": - f = lambda x: np.tan(x) - x/(1+x**2*phi/12) + f = lambda x: np.tan(x) - x/(1 + x**2*phi/12) sol = scipy.optimize.root_scalar(f, x0=0.7, bracket=(np.pi, 1.45*np.pi)) if sol.converged: return sol.root @@ -93,7 +93,7 @@ def fix_node(model, node, type): model.fix(node, *reactions) -def create_column(boundary="pin-pin", elem_data=None): +def create_column(boundary="pin-pin", elem_data=None, ndm=3): E = 29000.0 G = 11200.0 # A = 9.12e3 @@ -102,10 +102,8 @@ def create_column(boundary="pin-pin", elem_data=None): Ay = 3/6*A Az = 3/6*A L = 60.0 - ne = 4 # Number of elements discretizing the column - - ndm = 3 + ne = 10 # 4 if elem_data is None: elem_data = {} @@ -117,15 +115,6 @@ def create_column(boundary="pin-pin", elem_data=None): nIP = 5 # number of integration points along each element nn = ne + 1 - if use_shear: - phi = 12*E*I/(Ay*G*L**2) - lam = buckle_factor(boundary, phi) - kL = L/lam - euler_load = E*I/kL**2 / (1 + lam**2*phi/12) - else: -# kL = FACTORS[boundary]*L - kL = L/buckle_factor(boundary) - euler_load = E*I/kL**2 model = ops.Model(ndm=ndm) @@ -154,7 +143,7 @@ def create_column(boundary="pin-pin", elem_data=None): properties = [E, A, I] if ndm == 3: # Iy G, J - properties.extend([100*I, G, 100*I]) + properties.extend([ 2*I, G, 100*I]) if use_shear: properties.extend(["-Ay", Ay]) @@ -180,6 +169,15 @@ def create_column(boundary="pin-pin", elem_data=None): # Define loads + if use_shear: + phi = 12*E*I/(Ay*G*L**2) + lam = buckle_factor(boundary, phi) + kL = L/lam + euler_load = E*I/kL**2 / (1 + lam**2*phi/12) + else: +# kL = FACTORS[boundary]*L + kL = L/buckle_factor(boundary) + euler_load = E*I/kL**2 model.pattern('Plain', 1, "Linear") if ndm == 2: load = (0.0, -euler_load, 0.0) @@ -190,37 +188,53 @@ def create_column(boundary="pin-pin", elem_data=None): return model, euler_load +def linearized_buckling(model, peak_load): + # Analysis Options +# model.system('UmfPack') +# model.test('NormUnbalance', 1.0e-6, 20, 0) + model.algorithm('Newton') + model.integrator('LoadControl', load_step) + model.analysis('Static') + pass def buckling_analysis(model, peak_load): # Apply a load from zero to peak_load until # the stiffness becomes singular (first eigenvalue is zero) load_step = 0.01 - PeakLoadRatio = 2.00 + PeakLoadRatio = 1.50 # Analysis Options - model.system('UmfPack') - model.constraints('Transformation') - model.test('NormUnbalance', 1.0e-6, 20, 0) +# model.system('UmfPack') +# model.constraints('Transformation') +# model.test('NormUnbalance', 1.0e-6, 20, 0) + model.test("EnergyIncr", 1e-8, 20, 9) model.algorithm('Newton') - model.numberer('Plain') model.integrator('LoadControl', load_step) model.analysis('Static') +# print(pd.DataFrame(model.getTangent())) + lam_0 = model.getTime() eig_0 = model.eigen(1) limit_load = None + failed = False for i in range(1, int(PeakLoadRatio/load_step)+1): if model.analyze(1) != 0: - break + print(f" Analysis failed at step {i} with load at {model.getTime()}") + failed = True +# break lam = model.getTime() eig = model.eigen(1)[0] - if eig <= 0.0: - # linear interpolation - lam_i = lam_0 + (lam - lam_0)*eig_0/(eig_0-eig) + if eig <= 0.0 or failed: + if eig_0 != eig: + # linear interpolation + lam_i = lam_0 + (lam - lam_0)*eig_0/(eig_0-eig) + else: + lam_i = lam limit_load = lam_i * peak_load break @@ -233,11 +247,11 @@ def buckling_analysis(model, peak_load): if __name__ == "__main__": - for elem in "PrismFrame", "ForceFrame", "ForceDeltaFrame": + for elem in "PrismFrame", "ForceFrame", "ForceDeltaFrame", "ExactFrame": # "forceBeamColumn", "forceBeamColumnCBDI": - for shear in False,True: + for shear in True,: # , False print(elem, f"({shear = })") elem_data = { "type": elem, diff --git a/examples/frameshear/Case_1.py b/examples/frameshear/Case_1.py index 1eed144..a90c6e3 100644 --- a/examples/frameshear/Case_1.py +++ b/examples/frameshear/Case_1.py @@ -63,7 +63,10 @@ def analyze(element="ForceBeamColumn", use_shear = False): else: model.section("Elastic", 1, E, A, I) - model.geomTransf("Corotational", 1) + if "Exact" in element: + model.geomTransf("Linear", 1) + else: + model.geomTransf("Corotational", 1) # model.geomTransf("PDelta", 1) # Elements @@ -116,7 +119,7 @@ def analyze(element="ForceBeamColumn", use_shear = False): # "DispBeamColumn" # "PrismFrame" - for element in "ForceFrame", "forceBeamColumnCBDI", "PrismFrame": + for element in "ForceFrame", "forceBeamColumnCBDI", "PrismFrame", "ExactFrame": for shear in True, False: print(element, f"({shear = })") model = analyze(element, use_shear=shear) diff --git a/examples/frameshear/Case_2.py b/examples/frameshear/Case_2.py index 3558df3..a6e8fbb 100644 --- a/examples/frameshear/Case_2.py +++ b/examples/frameshear/Case_2.py @@ -32,7 +32,7 @@ def check(model, Mbench, Dbench): print(f"Base moment (kip-in) {Mbase:8.0f} {Mbench:8.0f} %8.2f %%" % (100*(Mbench-Mbase)/Mbench)) print(f"Tip displacement (in) {Dtip:8.4f} {Dbench:8.3f} %8.2f %%\n" % (100*(Dbench-Dtip)/Dbench)) -def create_column(element, use_shear=False): +def create_column(element, use_shear=False, ndm=2): L = 28*ft # Material E = 29000.0*ksi @@ -47,7 +47,6 @@ def create_column(element, use_shear=False): k = (d*tw)/A ne = 4 - ndm = 2 if ndm == 2: vecxz = () @@ -62,13 +61,24 @@ def create_column(element, use_shear=False): model.node(tag, 0.0, y) - model.fix(1, 1, 1, 1) + boundary = [1, 1, 1] + if ndm == 3: + boundary = boundary + [1, 1, 1] + model.fix(1, *boundary) # Cross-Section - if use_shear : - model.section("Elastic", 1, E, A, I, G, k) + if ndm == 2: + if use_shear : + model.section("Elastic", 1, E, A, I, G, k) + else: + model.section("Elastic", 1, E, A, I) else: - model.section("Elastic", 1, E, A, I) + # Iy G J + properties = [E, A, I, I, G, 100*I] + if use_shear: + properties.extend(["-Ay", k*A, "-Az", k*A]) + model.section("FrameElastic", 1, *properties) + model.geomTransf("Corotational", 1, *vecxz) @@ -125,5 +135,6 @@ def analyze(model, Mbench, Dbench): if __name__ == "__main__": analyze(create_column("forceBeamColumn"), Mbench, Dbench) analyze(create_column("forceBeamColumnCBDI"), Mbench, Dbench) + analyze(create_column("ExactFrame", True, ndm=3), Mbench, Dbench) diff --git a/examples/index.xml b/examples/index.xml index 1b51e63..68e00ea 100644 --- a/examples/index.xml +++ b/examples/index.xml @@ -175,6 +175,13 @@ https://stairlab.github.io/opensees-gallery/examples/shallowdome/ Double-Layer Shallow Dome March 2020, Amir Hossein Namadchi This is an OpenSeesPy simulation of one of the numerical examples in our previously published paper. + + Shell Diaphragms + https://stairlab.github.io/opensees-gallery/examples/shellframe/ + Mon, 01 Jan 0001 00:00:00 +0000 + https://stairlab.github.io/opensees-gallery/examples/shellframe/ + + Simple Pendulum https://stairlab.github.io/opensees-gallery/examples/pendulum/ diff --git a/examples/page/3/index.html b/examples/page/3/index.html index 1e3b780..ff248dd 100644 --- a/examples/page/3/index.html +++ b/examples/page/3/index.html @@ -580,10 +580,10 @@