diff --git a/.gitignore b/.gitignore index 9d64752e05..8417b16749 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,4 @@ SRC/interpreter/pythonInterpreter SRC/interpreter/tclInterpreter SRC/interpreter/openseespy SRC/interpreter/openseestcl +bin \ No newline at end of file diff --git a/DEVELOPER/core/classTags.h b/DEVELOPER/core/classTags.h index 45c2e8f762..3127735b5b 100644 --- a/DEVELOPER/core/classTags.h +++ b/DEVELOPER/core/classTags.h @@ -718,6 +718,9 @@ #define ELE_TAG_PFEMElement2DQuasi 187 #define ELE_TAG_MINI 188 #define ELE_TAG_PFEMElement3DBubble 189 +#define ELE_TAG_NineNodeQuad 207 +#define ELE_TAG_EightNodeQuad 208 +#define ELE_TAG_SixNodeTri 209 #define FRN_TAG_Coulomb 1 #define FRN_TAG_VelDependent 2 diff --git a/EXAMPLES/DeveloperTestScripts/ZeroLengthImpact3D_test.tcl b/EXAMPLES/DeveloperTestScripts/ZeroLengthImpact3D_test.tcl index 2a4c5aabc9..7894fb379e 100755 --- a/EXAMPLES/DeveloperTestScripts/ZeroLengthImpact3D_test.tcl +++ b/EXAMPLES/DeveloperTestScripts/ZeroLengthImpact3D_test.tcl @@ -20,7 +20,7 @@ # x (y=0.0) x (y=10.0) x (y=10.0) x (y=20.0) # | | | | # 02--------05 12--------15 22--------25 32--------35 -# | master1 | | master1 | | slave1 | | slave1 | +# | primary1 | | primary1 | | secondary1 | | secondary1 | # 01--------04---> z 11--------14---> z 21--------24---> z 31--------34---> z @@ -66,8 +66,8 @@ fix 05 1 1 1; nDMaterial ElasticIsotropic 1 29000.0 0.3; #steel #element stdBrick $eleTag $node1 $node2 $node3 $node4 $node5 $node6 $node7 $node8 $matTag -element stdBrick 1 12 11 01 02 15 14 04 05 1;#master1 -element stdBrick 2 32 31 21 22 35 34 24 25 1;#slave1 +element stdBrick 1 12 11 01 02 15 14 04 05 1;#primary1 +element stdBrick 2 32 31 21 22 35 34 24 25 1;#secondary1 @@ -184,4 +184,4 @@ if {$ok != 0} { if {$success == 1.0} { puts "SUCCESS: enjoy!" } - \ No newline at end of file + diff --git a/EXAMPLES/ExamplePython/Example5.1.py b/EXAMPLES/ExamplePython/Example5.1.py index 07735909dc..101919d8cf 100644 --- a/EXAMPLES/ExamplePython/Example5.1.py +++ b/EXAMPLES/ExamplePython/Example5.1.py @@ -66,7 +66,7 @@ node(17, bx/2.0, -by/2.0, 3.0*h) node(18, -bx/2.0, -by/2.0, 3.0*h) -# Master nodes for rigid diaphragm +# Retained nodes for rigid diaphragm # tag X Y Z node( 9, 0.0, 0.0, h) node(14, 0.0, 0.0, 2.0*h) @@ -80,12 +80,12 @@ fix(4, 1, 1, 1, 1, 1, 1) # Define rigid diaphragm multi-point constraints -# normalDir master slaves +# normalDir retained constrained rigidDiaphragm(3, 9, 5, 6, 7, 8) rigidDiaphragm(3, 14, 10, 11, 12, 13) rigidDiaphragm(3, 19, 15, 16, 17, 18) -# Constraints for rigid diaphragm master nodes +# Constraints for rigid diaphragm retained nodes # tag DX DY DZ RX RY RZ fix( 9, 0, 0, 1, 1, 1, 0) fix(14, 0, 0, 1, 1, 1, 0) @@ -199,13 +199,13 @@ # 10% of column capacity p = 0.1*fc*h*h -# Mass lumped at master nodes +# Mass lumped at retained nodes m = (4.0*p)/g -# Rotary inertia of floor about master node +# Rotary inertia of floor about retained node i = m*(bx*bx + by*by)/12.0 -# Set mass at the master nodes +# Set mass at the retained nodes # tag MX MY MZ RX RY RZ mass( 9, m, m, 0.0, 0.0, 0.0, i) mass(14, m, m, 0.0, 0.0, 0.0, i) diff --git a/EXAMPLES/ExamplePython/bending_quad9n.py b/EXAMPLES/ExamplePython/bending_quad9n.py new file mode 100644 index 0000000000..b884446118 --- /dev/null +++ b/EXAMPLES/ExamplePython/bending_quad9n.py @@ -0,0 +1,52 @@ +import openseespy.opensees as ops +# import opensees as ops + +ops.wipe() + +ops.model('basic', '-ndm', 2, '-ndf', 2) + +L = 5. +H = 1. + +thk = 0.01 + +P = 100. +E = 200.e6 +nu = 0.3 + +ops.nDMaterial('ElasticIsotropic', 1, E, nu) + +ops.node(1, 0., 0.) +ops.node(2, 5., 0.) +ops.node(3, 5., 1.) +ops.node(4, 0., 1.) +ops.node(5, 2.5, 0.) +ops.node(6, 5., .5) +ops.node(7, 2.5, 1.) +ops.node(8, 0., .5) +ops.node(9, 2.5, .5) # comment for quad8n element + +ops.element('quad9n', 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, thk, 'PlaneStress', 1) +# ops.element('quad8n', 1, 1, 2, 3, 4, 5, 6, 7, 8, thk, 'PlaneStress', 1) + +ops.fix(1, 1, 1) +ops.fix(4, 1, 0) +ops.fix(8, 1, 0) + +ops.timeSeries('Linear', 1) +ops.pattern('Plain', 1, 1) +ops.load(2, P, 0.) +ops.load(3, -P, 0.) + +ops.analysis('Static') + +ops.analyze(1) + +ops.printModel() + +# verification: +# tip vertical displacement (node 2 and 3) = 0.0075 +# bottom Gauss Point stress_xx = 46475.8 +# bottom extrem stress_xx (extrapolated) = 60000.0 + +exit() diff --git a/EXAMPLES/ExamplePython/bending_tri6n.py b/EXAMPLES/ExamplePython/bending_tri6n.py new file mode 100644 index 0000000000..f270b5ed62 --- /dev/null +++ b/EXAMPLES/ExamplePython/bending_tri6n.py @@ -0,0 +1,56 @@ +import openseespy.opensees as ops +# import opensees as ops + +ops.wipe() + +ops.model('basic', '-ndm', 2, '-ndf', 2) + +L = 5. +H = 1. + +thk = 0.01 + +P = 100. +E = 200.e6 +nu = 0.3 + +ops.nDMaterial('ElasticIsotropic', 1, E, nu) + +ops.node(1, 0., 0.) +ops.node(2, 5., 0.) +ops.node(3, 5., 1.) +ops.node(4, 0., 1.) +ops.node(5, 2.5, 0.) +ops.node(6, 5., .5) +ops.node(7, 2.5, 1.) +ops.node(8, 0., .5) +ops.node(9, 2.5, .5) # comment for quad8n element + +ops.element('tri6n', 1, 1, 2, 3, 5, 6, 9, thk, 'PlaneStress', 1) +ops.element('tri6n', 2, 1, 3, 4, 9, 7, 8, thk, 'PlaneStress', 1) + +ops.fix(1, 1, 1) +ops.fix(4, 1, 0) +ops.fix(8, 1, 0) + +ops.timeSeries('Linear', 1) +ops.pattern('Plain', 1, 1) +ops.load(2, P, 0.) +ops.load(3, -P, 0.) + +ops.analysis('Static') + +ops.analyze(1) + +ops.printModel() + +stressAtNodes_ele1 = ops.eleResponse(1, 'stressAtNodes') + +print(f'\nTip vertical displacement (node 2) is {ops.nodeDisp(2, 2):.4f}') +print(f'Stress sigma_xx at node 1 is {stressAtNodes_ele1[0]:.1f}') + +# verification: +# tip vertical displacement (node 2 and 3) = 0.0075 +# bottom extreme stress_xx (extrapolated) = 60000.0 + +exit() diff --git a/EXAMPLES/ExampleScripts/Example5.1.tcl b/EXAMPLES/ExampleScripts/Example5.1.tcl index 537fc5814c..08485f50b7 100644 --- a/EXAMPLES/ExampleScripts/Example5.1.tcl +++ b/EXAMPLES/ExampleScripts/Example5.1.tcl @@ -37,7 +37,7 @@ node 16 [expr $bx/2] [expr $by/2] [expr 3*$h] node 17 [expr $bx/2] [expr -$by/2] [expr 3*$h] node 18 [expr -$bx/2] [expr -$by/2] [expr 3*$h] -# Master nodes for rigid diaphragm +# Retained nodes for rigid diaphragm # tag X Y Z node 9 0 0 $h node 14 0 0 [expr 2*$h] @@ -51,12 +51,12 @@ fix 3 1 1 1 1 1 1 fix 4 1 1 1 1 1 1 # Define rigid diaphragm multi-point constraints -# normalDir master slaves +# normalDir retained constrained rigidDiaphragm 3 9 5 6 7 8 rigidDiaphragm 3 14 10 11 12 13 rigidDiaphragm 3 19 15 16 17 18 -# Constraints for rigid diaphragm master nodes +# Constraints for rigid diaphragm retained nodes # tag DX DY DZ RX RY RZ fix 9 0 0 1 1 1 0 fix 14 0 0 1 1 1 0 @@ -174,14 +174,14 @@ element nonlinearBeamColumn 24 18 15 $np $beamSec 2 # 10% of column capacity set p [expr 0.1*$fc*$h*$h] -# Mass lumped at master nodes +# Mass lumped at retained nodes set g 386.4; # Gravitational constant set m [expr (4.0*$p)/$g] -# Rotary inertia of floor about master node +# Rotary inertia of floor about retained node set i [expr $m*($bx*$bx+$by*$by)/12.0] -# Set mass at the master nodes +# Set mass at the retained nodes # tag MX MY MZ RX RY RZ mass 9 $m $m 0 0 0 $i mass 14 $m $m 0 0 0 $i diff --git a/EXAMPLES/ExampleScripts/RigidFrame3D.tcl b/EXAMPLES/ExampleScripts/RigidFrame3D.tcl index 5fd70c666a..fed8af471a 100644 --- a/EXAMPLES/ExampleScripts/RigidFrame3D.tcl +++ b/EXAMPLES/ExampleScripts/RigidFrame3D.tcl @@ -64,24 +64,24 @@ fix 2 1 1 1 1 1 1 fix 3 1 1 1 1 1 1 fix 4 1 1 1 1 1 1 -# Mass lumped at master node +# Mass lumped at retained node set m [expr ($dl+$ll)*$bx*$by/$g] -# Rotary inertia of floor about master node +# Rotary inertia of floor about retained node set i [expr $m*($bx^2+$by^2)/12.0] -# Master nodes for rigid diaphragm +# Retained nodes for rigid diaphragm node 9 0 0 $h -mass $m $m 0 0 0 $i node 14 0 0 [expr 2*$h] -mass $m $m 0 0 0 $i node 19 0 0 [expr 3*$h] -mass $m $m 0 0 0 $i # Define rigid diaphragm constraints -# normalDir master slaves +# normalDir retained constrained rigidDiaphragm 3 9 5 6 7 8 rigidDiaphragm 3 14 10 11 12 13 rigidDiaphragm 3 19 15 16 17 18 -# Constraints for rigid diaphragm master nodes +# Constraints for rigid diaphragm retained nodes fix 9 0 0 1 1 1 0 fix 14 0 0 1 1 1 0 fix 19 0 0 1 1 1 0 diff --git a/EXAMPLES/ExampleScripts/bending_quad9n.tcl b/EXAMPLES/ExampleScripts/bending_quad9n.tcl new file mode 100644 index 0000000000..b20eb462b9 --- /dev/null +++ b/EXAMPLES/ExampleScripts/bending_quad9n.tcl @@ -0,0 +1,48 @@ +model Basic -ndm 2 -ndf 2 + +set thk 0.01 +set L 5.0 +set H 1.0 + +set P 100. +set E 200.e6 +set nu 0.3 + +node 1 0. 0. +node 2 5. 0. +node 3 5. 1. +node 4 0. 1. +node 5 2.5 0. +node 6 5. .5 +node 7 2.5 1. +node 8 0. .5 +# node 9 2.5 .5; # comment for quad8n element + +nDMaterial ElasticIsotropic 1 $E $nu + +# element quad9n 1 1 2 3 4 5 6 7 8 9 $thk "PlaneStress" 1 +element quad8n 1 1 2 3 4 5 6 7 8 $thk "PlaneStress" 1 + +fix 1 1 1 +fix 4 1 0 +fix 8 1 0 + +timeSeries Linear 1 + +pattern Plain 1 1 { + load 2 $P 0. + load 3 -$P 0. +} + +analysis Static + +analyze 1 + +print + +# verification: +# tip vertical displacement (node 2 and 3) = 0.0075 +# bottom Gauss Point stress_xx = 46475.8 +# bottom extrem stress_xx (extrapolated) = 60000.0 + +exit diff --git a/EXAMPLES/ExamplesForTesting/PyTzSimple1GenForTesting.ops b/EXAMPLES/ExamplesForTesting/PyTzSimple1GenForTesting.ops index 7192d30886..f15b988335 100644 --- a/EXAMPLES/ExamplesForTesting/PyTzSimple1GenForTesting.ops +++ b/EXAMPLES/ExamplesForTesting/PyTzSimple1GenForTesting.ops @@ -1,5 +1,5 @@ ###################################################################### -# Master file for py pushover analysis to illustrate PySimple1Gen +# Main file for py pushover analysis to illustrate PySimple1Gen # command # # Created by Scott Brandenberg, April 30, 2004. diff --git a/EXAMPLES/ExamplesForTesting/Test.Example5.1.ops b/EXAMPLES/ExamplesForTesting/Test.Example5.1.ops index 4ed17a8da6..3196f11ef0 100644 --- a/EXAMPLES/ExamplesForTesting/Test.Example5.1.ops +++ b/EXAMPLES/ExamplesForTesting/Test.Example5.1.ops @@ -37,7 +37,7 @@ node 16 [expr $bx/2] [expr $by/2] [expr 3*$h] node 17 [expr $bx/2] [expr -$by/2] [expr 3*$h] node 18 [expr -$bx/2] [expr -$by/2] [expr 3*$h] -# Master nodes for rigid diaphragm +# Retained nodes for rigid diaphragm # tag X Y Z node 9 0 0 $h node 14 0 0 [expr 2*$h] @@ -51,12 +51,12 @@ fix 3 1 1 1 1 1 1 fix 4 1 1 1 1 1 1 # Define rigid diaphragm multi-point constraints -# normalDir master slaves +# normalDir retained constrained rigidDiaphragm 3 9 5 6 7 8 rigidDiaphragm 3 14 10 11 12 13 rigidDiaphragm 3 19 15 16 17 18 -# Constraints for rigid diaphragm master nodes +# Constraints for rigid diaphragm retained nodes # tag DX DY DZ RX RY RZ fix 9 0 0 1 1 1 0 fix 14 0 0 1 1 1 0 @@ -182,14 +182,14 @@ element nonlinearBeamColumn 24 18 15 $np $beamSec 2 # 10% of column capacity set p [expr 0.1*$fc*$h*$h] -# Mass lumped at master nodes +# Mass lumped at retained nodes set g 386.4; # Gravitational constant set m [expr (4*$p)/$g] -# Rotary inertia of floor about master node +# Rotary inertia of floor about retained node set i [expr $m*($bx*$bx+$by*$by)/12.0] -# Set mass at the master nodes +# Set mass at the retained nodes # tag MX MY MZ RX RY RZ mass 9 $m $m 0 0 0 $i mass 14 $m $m 0 0 0 $i diff --git a/EXAMPLES/ExamplesForTesting/Test.RigidFrame3D.ops b/EXAMPLES/ExamplesForTesting/Test.RigidFrame3D.ops index 65a88f7662..8811acf8c2 100644 --- a/EXAMPLES/ExamplesForTesting/Test.RigidFrame3D.ops +++ b/EXAMPLES/ExamplesForTesting/Test.RigidFrame3D.ops @@ -64,24 +64,24 @@ fix 2 1 1 1 1 1 1 fix 3 1 1 1 1 1 1 fix 4 1 1 1 1 1 1 -# Mass lumped at master node +# Mass lumped at retained node set m [expr ($dl+$ll)*$bx*$by/$g] -# Rotary inertia of floor about master node +# Rotary inertia of floor about retained node set i [expr $m*($bx^2+$by^2)/12.0] -# Master nodes for rigid diaphragm +# Retained nodes for rigid diaphragm node 9 0 0 $h -mass $m $m 0 0 0 $i node 14 0 0 [expr 2*$h] -mass $m $m 0 0 0 $i node 19 0 0 [expr 3*$h] -mass $m $m 0 0 0 $i # Define rigid diaphragm constraints -# normalDir master slaves +# normalDir retained constrained rigidDiaphragm 3 9 5 6 7 8 rigidDiaphragm 3 14 10 11 12 13 rigidDiaphragm 3 19 15 16 17 18 -# Constraints for rigid diaphragm master nodes +# Constraints for rigid diaphragm retained nodes fix 9 0 0 1 1 1 0 fix 14 0 0 1 1 1 0 fix 19 0 0 1 1 1 0 diff --git a/EXAMPLES/SmallSP/RigidFrame3D.tcl b/EXAMPLES/SmallSP/RigidFrame3D.tcl index 96f5fc0b69..3fdcb0794a 100644 --- a/EXAMPLES/SmallSP/RigidFrame3D.tcl +++ b/EXAMPLES/SmallSP/RigidFrame3D.tcl @@ -64,24 +64,24 @@ fix 2 1 1 1 1 1 1 fix 3 1 1 1 1 1 1 fix 4 1 1 1 1 1 1 -# Mass lumped at master node +# Mass lumped at retained node set m [expr ($dl+$ll)*$bx*$by/$g] -# Rotary inertia of floor about master node +# Rotary inertia of floor about retained node set i [expr $m*($bx^2+$by^2)/12.0] -# Master nodes for rigid diaphragm +# Retained nodes for rigid diaphragm node 9 0 0 $h -mass $m $m 0 0 0 $i node 14 0 0 [expr 2*$h] -mass $m $m 0 0 0 $i node 19 0 0 [expr 3*$h] -mass $m $m 0 0 0 $i # Define rigid diaphragm constraints -# normalDir master slaves +# normalDir retained constrained rigidDiaphragm 3 9 5 6 7 8 rigidDiaphragm 3 14 10 11 12 13 rigidDiaphragm 3 19 15 16 17 18 -# Constraints for rigid diaphragm master nodes +# Constraints for rigid diaphragm retained nodes fix 9 0 0 1 1 1 0 fix 14 0 0 1 1 1 0 fix 19 0 0 1 1 1 0 diff --git a/EXAMPLES/verification/mdofModal.tcl b/EXAMPLES/verification/mdofModal.tcl new file mode 100644 index 0000000000..4a1829a12f --- /dev/null +++ b/EXAMPLES/verification/mdofModal.tcl @@ -0,0 +1,182 @@ + +# +# file to compare modal & rayleigh for 2 dof problem +# NOTE: to get eigenvalue to work for 2 dof problem +# we had to add a dummy dof (so problem really 3 dof, +# though that last mode should have small contribution) +# + +# idea to test model with 2 different loadings +# case 1: harmonic +# case 2: earthquake (elCentro) +# + +# +# some parameters +# + +set zeta 0.05 +set periodForce 1. +set P 100. +set g 386.1 +set myTol 1.0e-8 +# +# function to build a model +# + +proc buildModel {} { + + global PI + set m1 2. + set m2 4. + set k1 5. + set k2 3. + + wipe + model Basic -ndm 1 -ndf 1 + node 1 0. + node 2 0. -mass $m1 + node 3 0. -mass $m2 + node 4 0. -mass [expr $m2/1e8] + + uniaxialMaterial Elastic 1 $k1 + uniaxialMaterial Elastic 2 $k2 + uniaxialMaterial Elastic 3 [expr $k2*1e8] + + element zeroLength 1 1 2 -mat 1 -dir 1 -doRayleigh 1 + element zeroLength 2 2 3 -mat 1 -dir 1 -doRayleigh 1 + element zeroLength 3 3 4 -mat 1 -dir 1 + + fix 1 1 +} + + +# +# trig motio +# + +buildModel + +# add load pattern +timeSeries Trig 1 0.0 [expr 100.0*$periodForce] $periodForce -factor $P +pattern Plain 1 1 { + load 2 1.0 +} + +constraints Plain +system FullGeneral +numberer Plain +algorithm Newton +integrator Newmark 0.5 0.25 +analysis Transient + +set lambda [eigen -fullGenLapack 2] +set w1 [expr sqrt([lindex $lambda 0])] +set w2 [expr sqrt([lindex $lambda 1])] + +set a0 [expr $zeta*2.0*$w1*$w2/($w1 + $w2)]; +set a1 [expr $zeta*2.0/($w1 + $w2)] +rayleigh $a0 $a1 0. 0. + +recorder Node -file nodeR1.out -time -node 2 3 -dof 1 disp +analyze 1000 .01 + +set rayleighRES1 [nodeDisp 3 1] + +buildModel + +# add load pattern +timeSeries Trig 1 0.0 [expr 100.0*$periodForce] $periodForce -factor $P +pattern Plain 1 1 { + load 2 1.0 +} + +constraints Plain +system FullGeneral +numberer Plain +algorithm Newton +integrator Newmark 0.5 0.25 +analysis Transient + +set lambda [eigen 2] +modalDamping $zeta + +recorder Node -file m1.out -time -node 2 3 -dof 1 disp +analyze 1000 .01 + +set modalRES1 [nodeDisp 3 1] + +# +# elCentro motion +# + +source ReadRecord.tcl +ReadRecord elCentro.at2 elCentro.dat dt nPts + +buildModel + +# add load pattern +timeSeries Path 1 -filePath elCentro.dat -dt $dt -factor $g +pattern UniformExcitation 1 1 -accel 1 + +set lambda [eigen -fullGenLapack 2] +set w1 [expr sqrt([lindex $lambda 0])] +set w2 [expr sqrt([lindex $lambda 1])] + +set a0 [expr $zeta*2.0*$w1*$w2/($w1 + $w2)]; +set a1 [expr $zeta*2.0/($w1 + $w2)] +rayleigh $a0 $a1 0. 0. + +recorder Node -file r2.out -time -node 2 3 -dof 1 disp +analyze 1000 .01 + +set rayleighRES2 [nodeDisp 3 1] + + +buildModel + +timeSeries Path 1 -filePath elCentro.dat -dt $dt -factor $g +pattern UniformExcitation 1 1 -accel 1 + +constraints Plain +system FullGeneral +numberer Plain +algorithm Newton +integrator Newmark 0.5 0.25 +analysis Transient + +set lambda [eigen 2] +modalDamping $zeta + + +recorder Node -file m2.out -time -node 2 3 -dof 1 disp +analyze 1000 .01 +set modalRES2 [nodeDisp 3 1] + +# +# print results +# + + + +# +# check & output results +# + +set error1 [expr $modalRES1-$rayleighRES1] +set error2 [expr $modalRES2-$rayleighRES2] +puts "RESULTS Comparing Rayleigh & Modal" +set formatString {%20s%15.5f%15.5f%10s%15.5f} +puts [format $formatString Harmonic: $rayleighRES1 $modalRES1 Diff: $error1] +puts [format $formatString Earthquake: $rayleighRES2 $modalRES2 Diff: $error2] + +set results [open results.out a+] +if {[expr abs($rayleighRES1-$modalRES1)] > $myTol || [expr abs($rayleighRES2-$modalRES2)] > $myTol} { + puts $results "FAILED : mdofModal.tcl" + puts "FAILED : mdofModal.tcl" +} else { + puts $results "SUCCESS : mdofModal.tcl" + puts "SUCCESS : mdofModal.tcl" +} +close $results + diff --git a/MAKES/Makefile.def-XUBUNTU.20.04 b/MAKES/Makefile.def-XUBUNTU.20.04 new file mode 100644 index 0000000000..a599f88ff5 --- /dev/null +++ b/MAKES/Makefile.def-XUBUNTU.20.04 @@ -0,0 +1,382 @@ +############################################################################ +# +# Program: OpenSees +# +# Purpose: A Top-level Makefile to create the libraries needed +# to use the OpenSees framework. +# and below. +# +# Written: fmk +# Created: 10/99 +# +# Send bug reports, comments or suggestions to fmckenna@ce.berkeley.edu +# +############################################################################ + + +# FOR SEQUENTIAL +# i installed latest gcc to get gfortran (not included in xcode when put this together) +# unpacked the package and issued the following: +# cd gcc-4.6.1 +# ./configure --enable-languages=c++,fortran +# make +# make install + +# %---------------------------------% +# | SECTION 1: PROGRAM | +# %---------------------------------% +# +# Specify the location and name of the OpenSees interpreter program +# that will be created (if this all works!) + +PROGRAMMING_MODE = SEQUENTIAL + +######################################### +HOME = /Users/jia-weichen/OpenSeesFile/DEVELOPER +############Added, Jiawei################ + +OpenSees_PROGRAM = $(HOME)/bin/OpenSees + +OPERATING_SYSTEM = LINUX + +DEBUG_MODE = NO_DEBUG +#DEBUG_MODE = DEBUG +RELIABILITY = NO_RELIABILITY + +BASE = /usr/local +FE = $(HOME)/OpenSees/SRC + +GRAPHICS = NONE +GRAPHIC_FLAG = -D_NOGRAPHICS +GRAPHIC_LIBRARY = +AGL_OBJS = + +#HAVE_BLAS = YES + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) +HAVE_BLAS = NO +endif + +BLASdir = $(HOME)/OpenSees/OTHER/BLAS +CBLASdir = $(HOME)/OpenSees/OTHER/CBLAS + +BLAS_LIBRARY = $(HOME)/lib/libBlas.a +CBLAS_LIBRARY = $(HOME)/lib/libCBlas.a + + +ifeq ($(HAVE_BLAS), YES) + +BLASdir = +BLAS_LIBRARY = +CBLAS_LIBRARY = + +endif + +AMDdir = $(HOME)/OpenSees/OTHER/AMD +LAPACKdir = $(HOME)/OpenSees/OTHER/LAPACK +SUPERLUdir = $(HOME)/OpenSees/OTHER/SuperLU_4.1/SRC +SUPERLU_DISTdir = $(HOME)/OpenSees/OTHER/SuperLU_DIST_2.5/SRC +ARPACKdir = $(HOME)/OpenSees/OTHER/ARPACK +UMFPACKdir = $(HOME)/OpenSees/OTHER/UMFPACK +METISdir = $(HOME)/OpenSees/OTHER/METIS +METISdir = $(HOME)/OpenSees/OTHER/ITPACK +SRCdir = $(HOME)/OpenSees/SRC +CSPARSEdir = $(HOME)/OpenSees/OTHER/CSPARSE + + +DIRS = $(BLASdir) \ + $(CBLASdir) \ + $(CSPARSEdir) \ + $(LAPACKdir) \ + $(AMDdir) \ + $(SUPERLUdir) \ + $(ARPACKdir) \ + $(UMFPACKdir) \ + $(SRCdir) \ + $(METISdir) \ + $(SUPERLUdir) \ + $(ARPACKdir) \ + $(UMFPACKdir) \ + $(METISdir) \ + $(ITPACKdir) + +DISTRIBUTED_SUPERLU_LIBRARY = + + +# %-------------------------------------------------------% +# | SECTION 3: LIBRARIES | +# | | +# | The following section defines the libraries that will | +# | be created and/or linked with when the libraries are | +# | being created or linked with. | +# %-------------------------------------------------------% +# +# Note: if vendor supplied BLAS and LAPACK libraries leave the +# libraries blank. You have to get your own copy of the tcl/tk +# library!! +# +# Note: For libraries that will be created (any in DIRS above) +# make sure the directory exsists where you want the library to go! + +FE_LIBRARY = $(HOME)/lib/libOpenSees.a +NDARRAY_LIBRARY = $(HOME)/lib/libndarray.a # BJ_UCD jeremic@ucdavis.edu +MATMOD_LIBRARY = $(HOME)/lib/libmatmod.a # BJ_UCD jeremic@ucdavis.edu +BJMISC_LIBRARY = $(HOME)/lib/libBJmisc.a # BJ_UCD jeremic@ucdavis.edu +LAPACK_LIBRARY = $(HOME)/lib/libLapack.a +#CLAPACK_LIBRARY = $(HOME)/OpenSees/OTHER/CLAPACK-3.1.1/lapack_MAC.a +CLAPACK_LIBRARY = +#CLBLAS_LIBRARY = $(HOME)/OpenSees/OTHER/CLAPACK-3.1.1/blas_MAC.a +CLBLAS_LIBRARY = +#LIBF2C_LIBRARY = $(HOME)/OpenSees/OTHER/CLAPACK-3.1.1/blas_MAC.a +LIBF2C_LIBRARY = +SUPERLU_LIBRARY = $(HOME)/lib/libSuperLU.a +ARPACK_LIBRARY = $(HOME)/lib/libArpack.a +AMD_LIBRARY = $(HOME)/lib/libAMD.a +UMFPACK_LIBRARY = $(HOME)/lib/libUmfpack.a +METIS_LIBRARY = $(HOME)/lib/libMetis.a +ITPACK_LIBRARY = $(HOME)/lib/libItpack.a +CSPARSE_LIBRARY = $(HOME)/lib/libCSparse.a + +TCL_LIBRARY = -framework Tcl -framework Tk + +# WATCH OUT .. These libraries are removed when 'make wipe' is invoked. +WIPE_LIBS = $(FE_LIBRARY) \ + $(NDARRAY_LIBRARY) \ + $(MATMOD_LIBRARY) \ + $(LAPACK_LIBRARY) \ + $(AMD_LIBRARY) \ + $(CSPARSE_LIBRARY) \ + $(BLAS_LIBRARY) \ + $(CLBLAS_LIBRARY) \ + $(SUPERLU_LIBRARY) \ + $(ARPACK_LIBRARY) \ + $(UMFPACK_LIBRARY) \ + $(METIS_LIBRARY) \ + $(ITPACK_LIBRARY) + +# %---------------------------------------------------------% +# | SECTION 4: COMPILERS | +# | | +# | The following macros specify compilers, linker/loaders, | +# | the archiver, and their options. You need to make sure | +# | these are correct for your system. | +# %---------------------------------------------------------% + +# Compilers +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) +###################Changed the following. Jiawei################## +CC++ = /usr/bin/g++ +CC = /usr/bin/gcc +FC = /usr/local/bin/gfortran +################################################################## + +LINKER = $(CC++) +LINKFLAGS = -Wl +#LINKFLAGS = -Wl +else +CC++ = /usr/local/openmpi-1.2.6/bin/mpic++ +CC = /usr/local/openmpi-1.2.6/bin/mpicc +FC = /usr/local/openmpi-1.2.6/bin/mpif77 +LINKER = $(CC++) +LINKFLAGS = -L/usr/local/openmpi-1.2.6/lib /usr/local/openmpi-1.2.6/lib/libmpi.a +#LINKFLAGS = -Wl,-u,_munmap -Wl,-multiply_defined,suppress -Wl,-u,_mmap -Wl,-multiply_defined,suppress +endif + +AR = ar +ARFLAGS = cqls +RANLIB = ranlib +RANLIBFLAGS = + +# Compiler Flags +# +# NOTES: +# C++ FLAGS TAKE need _UNIX or _WIN32 for preprocessor dircetives +# - the _WIN32 for the Windows95/98 or NT operating system. +# C FLAGS used -DUSE_VENDOR_BLAS (needed in SuperLU) if UNIX in C++ FLAGS +# + +OS_FLAG = -D_MACOSX + +# modified as optimizaton currently causing problems with Steeln01 code +ifeq ($(DEBUG_MODE), DEBUG) + +C++FLAGS = -Wall -D_LINUX -D_UNIX -D_TCL85 -D_AMDn $(OS_FLAG) -D_HTTPS \ + $(GRAPHIC_FLAG) $(RELIABILITY_FLAG) $(DEBUG_FLAG) $(MUMPS_FLAG) \ + $(PROGRAMMING_FLAG) -g -O0 -ffloat-store +CFLAGS = -Wall -O0 -g +FFLAGS = -Wall -O -DCUBLAS -x f77-cpp-input --no-second-underscore + + +# Linker +LINKER = $(CC++) +LINKFLAGS = -g -pg + +else + +C++FLAGS = -Wall -D_LINUX -D_UNIX -D_TCL85 -D_AMDn -D_MACOSX -D_HTTPS \ + $(GRAPHIC_FLAG) $(RELIABILITY_FLAG) $(DEBUG_FLAG) $(MUMPS_FLAG) \ + $(PROGRAMMING_FLAG) -O3 -ffloat-store -D_NO_PARALLEL_FILESYSTEM +CFLAGS = -Wall -O2 +FFLAGS = -Wall -O -DCUBLAS -x f77-cpp-input --no-second-underscore + +# Linker + +endif + +# Misc +MAKE = make +CD = cd +ECHO = echo +RM = rm +RMFLAGS = -f +SHELL = /bin/sh + +# %---------------------------------------------------------% +# | SECTION 5: COMPILATION | +# | | +# | The following macros specify the macros used in | +# | to compile the source code into object code. | +# %---------------------------------------------------------% + +.SUFFIXES: +.SUFFIXES: .C .c .f .f90 .cpp .o .cpp + +# +# %------------------% +# | Default command. | +# %------------------% +# +.DEFAULT: + @$(ECHO) "Unknown target $@, try: make help" +# +# %-------------------------------------------% +# | Command to build .o files from .f files. | +# %-------------------------------------------% +# + +.cpp.o: + @$(ECHO) Making $@ from $< + $(CC++) $(C++FLAGS) $(INCLUDES) -c $< -o $@ + +.C.o: + @$(ECHO) Making $@ from $< + $(CC++) $(C++FLAGS) $(INCLUDES) -c $< -o $@ +.c.o: + @$(ECHO) Making $@ from $< + $(CC) $(CFLAGS) -c $< -o $@ +.f.o: + @$(ECHO) Making $@ from $< + $(FC) $(FFLAGS) -c $< -o $@ + +# %---------------------------------------------------------% +# | SECTION 6: OTHER LIBRARIES | +# | | +# | The following macros specify other libraries that must | +# | be linked with when creating executables. These are | +# | platform specific and typically order does matter!! | +# %---------------------------------------------------------% + +HAVE_SCALAPACK = NO +SCALAPACK_INCLUDE = +SCALAPACK_LIB = + + +HAVE_MUMPS = NO +MUMPS_INCLUDE = +MUMPS_LIB = + +MACHINE_LINKLIBS = -L$(BASE)/lib \ + -L$(HOME)/lib + +HAVE_CUDA = NO +CUDA_DIR = +CUDA_FLAG = +CUDA_LIB = + +ifeq ($(HAVE_CUDA),YES) +CUDA_DIR = /usr/local/cuda +CUDA_FLAG = -D_CUDA +#CUDA_LIB = -L$(CUDA_DIR)/lib -lcublas +CUDA_LIB = $(FE)/system_of_eqn/linearSOE/bandGEN/BandGenLinSOE_Single.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/BandGenLinLapackSolver_Single.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/sgbsv.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/sgbtrs.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/sgbtrf.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/sgbtf2.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/slaswp.o \ + -L$(CUDA_DIR)/lib -cublas -lcuda \ + -L/usr/local/scalapack_installer_0.91/lib \ + -lrefblas + +CUDA_INCLUDE = -I$(CUDA_DIR)/include +endif + + +#FORTO = $(LAPACKdir)/fortran.o +FORTO = + +MACHINE_NUMERICAL_LIBS = \ + $(ARPACK_LIBRARY) \ + $(SUPERLU_LIBRARY) \ + $(UMFPACK_LIBRARY) \ + $(AMD_LIBRARY) \ + $(ITPACK_LIBRARY) \ + $(LAPACK_LIBRARY) \ + $(CLAPACK_LIBRARY) \ + $(CSPARSE_LIBRARY) \ + $(CLBLAS_LIBRARY) \ + $(BLAS_LIBRARY) \ + $(CBLAS_LIBRARY) \ + $(GRAPHIC_LIBRARY)\ + $(FORTO) \ + $(CUDA_LIB) \ + -ldl -L/usr/local/gfortran/lib/libgfortran.a + + +MACHINE_SPECIFIC_LIBS = $(AGL_OBJS) -lssl + +PARALLEL_LIB = $(FE)/system_of_eqn/linearSOE/sparseGEN/DistributedSuperLU.o \ + $(FE)/system_of_eqn/linearSOE/sparseGEN/DistributedSparseGenColLinSOE.o \ + $(FE)/system_of_eqn/linearSOE/sparseGEN/SparseGenColLinSOE.o \ + $(LAPACK_LIB) $(DISTRIBUTED_SUPERLU_LIBRARY) $(MUMPS_LIB) $(SCALAP_LIB) $(METIS_LIBRARY) \ + -L/usr/local/openmpi-1.2.6/lib -lmpi_cxx -lmpi_f77 -lmpi -lopen-rte -lopen-pal + +ifeq ($(PROGRAMMING_MODE), PARALLEL_INTERPRETERS) + +PARALLEL_LIB = $(FE)/system_of_eqn/linearSOE/sparseGEN/DistributedSuperLU.o \ + $(FE)/system_of_eqn/linearSOE/sparseGEN/DistributedSparseGenColLinSOE.o \ + $(DISTRIBUTED_SUPERLU_LIBRARY) $(MUMPS_LIB) $(SCALAP_LIB) $(METIS_LIBRARY) \ + -L/usr/local/openmpi-1.2.6/lib -lmpi_cxx -lmpi_f77 -lmpi -lopen-rte -lopen-pal + +endif + + +# %---------------------------------------------------------% +# | SECTION 7: INCLUDE FILES | +# | | +# | The following macros specify include files needed for | +# | compilation. | +# %---------------------------------------------------------% + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) +MACHINE_INCLUDES = -I/usr/include \ + -I/usr/local/include \ + -I$(BASE)/include \ + -I/usr/include/cxx \ + -I$(HOME)/include -I$(HOME)/blitz \ + -I$(CUDA_DIR)/include +else +MACHINE_INCLUDES = -I/usr/include \ + -I/usr/local/include \ + -I$(BASE)/include \ + -I/usr/include/cxx \ + -I$(FE)/../OTHER/SuperLU_DIST_2.0/SRC \ + -I$(HOME)/include -I$(HOME)/blitz $(MUMPS_INCLUDE) -I$(CUDA_DIR)/include +endif + +# this file contains all the OpenSees/SRC includes +include $(FE)/Makefile.incl + +TCL_INCLUDES = -I/Library/Frameworks/Tcl.framework/Headers -I/Library/Frameworks/Tk.framework/Headers + +INCLUDES = $(TCL_INCLUDES) $(FE_INCLUDES) $(MACHINE_INCLUDES) diff --git a/MAKES/Makefile.def.MacOS10.15-python b/MAKES/Makefile.def.MacOS10.15-python new file mode 100644 index 0000000000..47577f772b --- /dev/null +++ b/MAKES/Makefile.def.MacOS10.15-python @@ -0,0 +1,461 @@ +############################################################################ +# +# Program: OpenSees +# +# Purpose: A Top-level Makefile to create the libraries needed +# to use the OpenSees framework. +# and below. +# +# Written: fmk +# Created: 10/99 +# +# Send bug reports, comments or suggestions to fmckenna@ce.berkeley.edu +# +# Modified by Seokho Jeong for Mac OS X 10.11 El Capitan with +# Accelerate framework and Homebrew +# Modified by Maxim Millen for Mac OSX 10.15 with Python 3.7 +# +############################################################################ +# Prerequisites +# - Install Active TCL 8.5 for mac OS X +# - Install Homebrew +# - brew install gcc +# - brew install openmpi (for parallel versions) +# - brew install mumps (for parallel versions) +# - brew install python + +# steps +# 1) set HOME as path to repo +# 2) change path to gcc if not gcc-10 +# -L/usr/local/opt/gcc/lib/gcc/10/ +# 3) set path to Python `PYTHON_INCLUDES` +# 4) set path to a python virtual environment PYTHON_VENV (not sure if this is necessary) +# e.g. PYTHON_VENV = /Users/maximmillen/git/packages/OpenSees/venv +# 5) run `make python` + +INTERPRETER_LANGUAGE = PYTHON +#INTERPRETER_LANGUAGE = TCL + +# TODO: Add to travis build - since it supports macOS + +# %---------------------------------% +# | SECTION 1: PROGRAM | +# %---------------------------------% +# +# Specify the location and name of the OpenSees interpreter program +# that will be created (if this all works!) + +PROGRAMMING_MODE = SEQUENTIAL +#PROGRAMMING_MODE = PARALLEL +#PROGRAMMING_MODE = PARALLEL_INTERPRETERS + +OpenSees_PROGRAM = $(HOME)/bin/OpenSees + +ifeq ($(PROGRAMMING_MODE), PARALLEL) +OpenSees_PROGRAM = $(HOME)/bin/OpenSeesSP +PROGRAMMING_FLAG = -D_PARALLEL_PROCESSING +endif + +ifeq ($(PROGRAMMING_MODE), PARALLEL_INTERPRETERS) +OpenSees_PROGRAM = $(HOME)/bin/OpenSeesMP +PROGRAMMING_FLAG = -D_PARALLEL_INTERPRETERS +endif + +OPERATING_SYSTEM = LINUX + +DEBUG_MODE = NO_DEBUG +RELIABILITY = NO_RELIABILITY + +GRAPHICS = NONE +GRAPHIC_FLAG = -D_NOGRAPHICS +GRAPHIC_LIBRARY = +AGL_OBJS = +RELIABILITY = YES_RELIABILITY +RELIABILITY_FLAG = -D_RELIABILITY + +# %---------------------------------% +# | SECTION 2: PATHS | +# %---------------------------------% +# +# Note: if vendor supplied BLAS and LAPACK libraries or if you have +# any of the libraries already leave the directory location blank AND +# remove the directory from DIRS. + +BASE = /usr + +HOME = +FE = $(HOME)/SRC + +# Use BLAS,CBLAS, and LAPACK from APPLE Accelerate Library +BLASdir = $(HOME)/OTHER/BLAS +CBLASdir = $(HOME)/OTHER/CBLAS +LAPACKdir = $(HOME)/OTHER/LAPACK +SUPERLUdir = $(HOME)/OTHER/SuperLU_5.1.1/SRC +SUPERLU_DISTdir = $(HOME)/OTHER/SuperLU_DIST_4.3/SRC +ARPACKdir = $(HOME)/OTHER/ARPACK +UMFPACKdir = $(HOME)/OTHER/UMFPACK +METISdir = $(HOME)/OTHER/METIS +AMDdir = $(HOME)/OTHER/AMD +CSPARSEdir = $(HOME)/OTHER/CSPARSE +ITPACKdir = $(HOME)/OTHER/ITPACK +SRCdir = $(HOME)/SRC +PYdir = $(HOME)/SRC/interpreter + + +DIRS = $(BLASdir) \ + $(CBLASdir) \ + $(LAPACKdir) \ + $(SUPERLUdir) \ + $(SUPERLU_DISTdir) \ + $(ARPACKdir) \ + $(UMFPACKdir) \ + $(METISdir) \ + $(AMDdir) \ + $(CSPARSEdir) \ + $(ITPACKdir) \ + $(SRCdir) + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) +DIRS = $(BLASdir) \ + $(CBLASdir) \ + $(LAPACKdir) \ + $(SUPERLUdir) \ + $(ARPACKdir) \ + $(UMFPACKdir) \ + $(METISdir) \ + $(AMDdir) \ + $(CSPARSEdir) \ + $(ITPACKdir) \ + $(SRCdir) +endif + +# %-------------------------------------------------------% +# | SECTION 3: LIBRARIES | +# | | +# | The following section defines the libraries that will | +# | be created and/or linked with when the libraries are | +# | being created or linked with. | +# %-------------------------------------------------------% +# +# Note: if vendor supplied BLAS and LAPACK libraries leave the +# libraries blank. You have to get your own copy of the tcl/tk +# library!! +# +# Note: For libraries that will be created (any in DIRS above) +# make sure the directory exsists where you want the library to go! + +FE_LIBRARY = $(HOME)/lib/libOpenSees.a +RELIABILITY_LIBRARY = $(HOME)/lib/libReliability.a +OPTIMIZATION_LIBRARY = $(HOME)/lib/libOptimization.a +NDARRAY_LIBRARY = $(HOME)/lib/libndarray.a # BJ_UCD jeremic@ucdavis.edu +MATMOD_LIBRARY = $(HOME)/lib/libmatmod.a # BJ_UCD jeremic@ucdavis.edu +BJMISC_LIBRARY = $(HOME)/lib/libBJmisc.a # BJ_UCD jeremic@ucdavis.edu +LAPACK_LIBRARY = +BLAS_LIBRARY = +CBLAS_LIBRARY = +SUPERLU_LIBRARY = $(HOME)/lib/libSuperLU.a +ARPACK_LIBRARY = $(HOME)/lib/libArpack.a +UMFPACK_LIBRARY = $(HOME)/lib/libUmfpack.a +METIS_LIBRARY = $(HOME)/lib/libMetis.a +AMD_LIBRARY = $(HOME)/lib/libAMD.a +ITPACK_LIBRARY = $(HOME)/lib/libItpack.a +CSPARSE_LIBRARY = $(HOME)/lib/libcsparse.a +TCL_LIBRARY = -framework Tcl -framework Tk +TCL_DIST_LIBRARY = $(HOME)/lib/libOpenSeesTclCommands.a +PYTHON_VENV = + +PYTHON_LIBRARY = -L/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/ -lpython3.7 + +DISTRIBUTED_SUPERLU_LIBRARY = $(HOME)/lib/libDistributedSuperLU.a + +BLITZ_LIBRARY = $(HOME)/blitz/lib/libblitz.a +GRAPHIC_LIBRARY = + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) +DISTRIBUTED_SUPERLU_LIBRARY = +endif + +# WATCH OUT .. These libraries are removed when 'make wipe' is invoked. +WIPE_LIBS = $(FE_LIBRARY) \ + $(NDARRAY_LIBRARY) \ + $(MATMOD_LIBRARY) \ + $(BJMISC_LIBRARY) \ + $(LAPACK_LIBRARY) \ + $(BLAS_LIBRARY) \ + $(CBLAS_LIBRARY) \ + $(SUPERLU_LIBRARY) \ + $(ARPACK_LIBRARY) \ + $(UMFPACK_LIBRARY) \ + $(AMD_LIBRARY) \ + $(METIS_LIBRARY) \ + $(ITPACK_LIBRARY) \ + $(CSPARSE_LIBRARY) \ + $(RELIABILITY_LIBRARY) \ + $(DISTRIBUTED_SUPERLU_LIBRARY) \ + $(TCL_DIST_LIBRARY) + +# %---------------------------------------------------------% +# | SECTION 4: COMPILERS | +# | | +# | The following macros specify compilers, linker/loaders, | +# | the archiver, and their options. You need to make sure | +# | these are correct for your system. | +# %---------------------------------------------------------% + +# Compilers +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) +CC++ = /usr/bin/clang++ -std=c++14 +CC = /usr/bin/clang +FC = /usr/local/bin/gfortran + +LINKER = $(CC++) +LINKFLAGS = -Wl + +else +CC++ = /usr/local/bin/mpic++ +CC = /usr/local/bin/mpicc +FC = /usr/local/bin/mpifort + +LINKER = $(CC++) +LINKFLAGS = +endif + +AR = ar +ARFLAGS = cqls +RANLIB = ranlib +RANLIBFLAGS = + +# Compiler Flags +# +# NOTES: +# C++ FLAGS TAKE need _UNIX or _WIN32 for preprocessor dircetives +# - the _WIN32 for the Windows95/98 or NT operating system. +# C FLAGS used -DUSE_VENDOR_BLAS (needed in SuperLU) if UNIX in C++ FLAGS +# +OS_FLAG = -D_MACOSX + +# modified as optimizaton currently causing problems with Steeln01 code +ifeq ($(DEBUG_MODE), DEBUG) +C++FLAGS = -Wall -D_LINUX -D_UNIX -D_TCL85 -D_AMDn $(OS_FLAG)\ + $(GRAPHIC_FLAG) $(RELIABILITY_FLAG) $(DEBUG_FLAG) $(MUMPS_FLAG) \ + $(PROGRAMMING_FLAG) -g -O0 +CFLAGS = -Wall -O0 -g +FFLAGS = -Wall -O -DCUBLAS -x f77-cpp-input --no-second-underscore +LINKFLAGS = -g -pg + +else +ifeq ($(INTERPRETER_LANGUAGE), PYTHON) +C++FLAGS = -D_LINUX -D_UNIX -D_TCL85 -D_AMDn -D_MACOSX \ + -DPYTHON_EXECUTABLE=$(PYTHON_VENV)/bin/python \ + $(GRAPHIC_FLAG) $(RELIABILITY_FLAG) $(DEBUG_FLAG) $(MUMPS_FLAG) \ + $(PROGRAMMING_FLAG) -g -O0 +CFLAGS = -Wall -g -O0 +FFLAGS = -Wall -g -O0 + +# Linker +LINKER = $(CC++) +LINKFLAGS = -g -fPIC +else +C++FLAGS = -Wall -D_LINUX -D_UNIX -D_TCL85 -D_AMDn -D_MACOSX \ + $(GRAPHIC_FLAG) $(RELIABILITY_FLAG) $(DEBUG_FLAG) $(MUMPS_FLAG) \ + $(PROGRAMMING_FLAG) -O3 -march=native -D_NO_PARALLEL_FILESYSTEM +CFLAGS = -Wall -O2 +FFLAGS = -Wall -O -DCUBLAS -x f77-cpp-input --no-second-underscore +endif +endif + +# Misc +MAKE = make +CD = cd +ECHO = echo +RM = rm +RMFLAGS = -f +SHELL = /bin/sh + +# %---------------------------------------------------------% +# | SECTION 5: COMPILATION | +# | | +# | The following macros specify the macros used in | +# | to compile the source code into object code. | +# %---------------------------------------------------------% + +.SUFFIXES: +.SUFFIXES: .C .c .f .f90 .cpp .o .cpp + +# +# %------------------% +# | Default command. | +# %------------------% +# +.DEFAULT: + @$(ECHO) "Unknown target $@, try: make help" +# +# %-------------------------------------------% +# | Command to build .o files from .f files. | +# %-------------------------------------------% +# + +.cpp.o: + @$(ECHO) Making $@ from $< + $(CC++) $(C++FLAGS) $(INCLUDES) -c $< -o $@ + +.C.o: + @$(ECHO) Making $@ from $< + $(CC++) $(C++FLAGS) $(INCLUDES) -c $< -o $@ +.c.o: + @$(ECHO) Making $@ from $< + $(CC) $(CFLAGS) -c $< -o $@ +.f.o: + @$(ECHO) Making $@ from $< + $(FC) $(FFLAGS) -c $< -o $@ + +# %---------------------------------------------------------% +# | SECTION 6: OTHER LIBRARIES | +# | | +# | The following macros specify other libraries that must | +# | be linked with when creating executables. These are | +# | platform specific and typically order does matter!! | +# %---------------------------------------------------------% + +# Use scalapack from Homebrew +SCALAPACK = YES +SCALAPACK_INCLUDE = +SCALAPACK_FLAG = -D_SCALAP +#SCALAPACK_DIR = /usr/local/Cellar/scalapack/2.0.2_6/ +#SCALAPACK_LIB = -L$(SCALAPACK_DIR)/lib \ +# -lscalapack -lreflapack -lrefblas +SCALAPACK_DIR = +SCALAPACK_LIB = -lscalapack -lveclibfort + +# Use Mumps from Homebrew +MUMPS = YES +MUMPS_DIR = +MUMPS_FLAG = -D_MUMPS -D_OPENMPI +MUMPS_INCLUDE = -I$(MUMPS_DIR)/include +MUMPS_LIB = $(FE)/system_of_eqn/linearSOE/mumps/MumpsSOE.o \ + $(FE)/system_of_eqn/linearSOE/mumps/MumpsSolver.o \ + $(FE)/system_of_eqn/linearSOE/mumps/MumpsParallelSOE.o \ + $(FE)/system_of_eqn/linearSOE/mumps/MumpsParallelSolver.o \ + -ldmumps -lmumps_common -lpord + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) +SCALAPACK = NO +SCALAPACK_DIR = +SCALAPACK_LIB = +SCALAPACK_FLAG = + +MUMPS = NO +MUMPS_DIR = +MUMPS_FLAG = +MUMPS_INCLUDE = +MUMPS_LIB = +endif + +# Add '-L/usr/local/lib' to link Homebrew-installed libraries +MACHINE_LINKLIBS = -L$(BASE)/lib -L/usr/local/lib -L$(HOME)/lib + +HAVE_CUDA = NO +CUDA_DIR = +CUDA_FLAG = +CUDA_LIB = + +ifeq ($(HAVE_CUDA),YES) +CUDA_DIR = /usr/local/cuda +CUDA_FLAG = -D_CUDA +CUDA_LIB = $(FE)/system_of_eqn/linearSOE/bandGEN/BandGenLinSOE_Single.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/BandGenLinLapackSolver_Single.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/sgbsv.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/sgbtrs.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/sgbtrf.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/sgbtf2.o \ + $(FE)/system_of_eqn/linearSOE/bandGEN/slaswp.o \ + -L$(CUDA_DIR)/lib -cublas -lcuda \ + -L/usr/local/scalapack_installer_0.91/lib \ + -lrefblas + +CUDA_INCLUDE = -I$(CUDA_DIR)/include +endif + + +#FORTO = $(LAPACKdir)/fortran.o +FORTO = + +# Link Homebrew gfortran library +# TODO: may need to add python lib dir +MACHINE_NUMERICAL_LIBS = \ + $(ARPACK_LIBRARY) \ + $(SUPERLU_LIBRARY) \ + $(UMFPACK_LIBRARY) \ + $(AMD_LIBRARY) \ + $(ITPACK_LIBRARY) \ + $(LAPACK_LIBRARY) \ + $(CSPARSE_LIBRARY) \ + $(BLAS_LIBRARY) \ + $(CBLAS_LIBRARY) \ + $(GRAPHIC_LIBRARY)\ + $(FORTO) \ + $(CUDA_LIB) \ + $(RELIABILITY_LIBRARY) \ + -ldl -L/usr/local/opt/gcc/lib/gcc/10/ -lgfortran + +# Use BLAS,CBLAS, and LAPACK from APPLE Accelerate Library +MACHINE_SPECIFIC_LIBS = $(AGL_OBJS) -L/usr/local/opt/openssl/lib -lssl -lcrypto \ + -framework Accelerate + +PARALLEL_LIB = $(FE)/system_of_eqn/linearSOE/sparseGEN/DistributedSuperLU.o \ + $(FE)/system_of_eqn/linearSOE/sparseGEN/DistributedSparseGenColLinSOE.o \ + $(FE)/system_of_eqn/linearSOE/sparseGEN/SparseGenColLinSOE.o \ + $(LAPACK_LIB) $(DISTRIBUTED_SUPERLU_LIBRARY) $(MUMPS_LIB) $(SCALAPACK_LIB) $(METIS_LIBRARY) \ + -lmpi_cxx -lmpi_mpifh -lmpi -lopen-rte -lopen-pal + + +ifeq ($(PROGRAMMING_MODE), PARALLEL_INTERPRETERS) +PARALLEL_LIB = $(FE)/system_of_eqn/linearSOE/sparseGEN/DistributedSuperLU.o \ + $(FE)/system_of_eqn/linearSOE/sparseGEN/DistributedSparseGenColLinSOE.o \ + $(DISTRIBUTED_SUPERLU_LIBRARY) $(MUMPS_LIB) $(SCALAPACK_LIB) $(METIS_LIBRARY) \ + -lmpi_cxx -lmpi_mpifh -lmpi -lopen-rte -lopen-pal +else +PARALLEL_LIB = +endif + + +# %---------------------------------------------------------% +# | SECTION 7: INCLUDE FILES | +# | | +# | The following macros specify include files needed for | +# | compilation. | +# %---------------------------------------------------------% + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) +MACHINE_INCLUDES = -I/usr/include \ + -I/usr/local/include \ + -I$(BASE)/include \ + -I/usr/include/cxx \ + -I$(HOME)/include -I$(HOME)/blitz \ + -I$(CUDA_DIR)/include \ + -I/usr/local/opt/openssl/include +else +MACHINE_INCLUDES = -I/usr/include \ + -I/usr/local/include \ + -I$(BASE)/include \ + -I/usr/include/cxx \ + -I/opt/local/include \ + -I$(FE)/../OTHER/SuperLU_DIST_4.3/SRC \ + -I$(HOME)/include -I$(HOME)/blitz \ + $(MUMPS_INCLUDE) -I$(CUDA_DIR)/include \ + -I/usr/local/opt/openssl/include + +endif + +# this file contains all the OpenSees/SRC includes +include $(FE)/Makefile.incl + + +TCL_INCLUDES = -I/Library/Frameworks/Tcl.framework/Headers -I/Library/Frameworks/Tk.framework/Headers +PYTHON_INCLUDES = -I/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/include/python3.7m \ + -I/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/include/python3.7m/internal + +INCLUDES = $(TCL_INCLUDES) $(FE_INCLUDES) $(MACHINE_INCLUDES) $(PYTHON_INCLUDES) + + + diff --git a/MAKES/Makefile.def.STAMPEDE2.EVERYBODYELSE b/MAKES/Makefile.def.STAMPEDE2.EVERYBODYELSE new file mode 100644 index 0000000000..f3491d080b --- /dev/null +++ b/MAKES/Makefile.def.STAMPEDE2.EVERYBODYELSE @@ -0,0 +1,517 @@ +############################################################################ +# +# Program: OpenSees +# +# Purpose: A Top-level Makefile to create the libraries needed +# to use the OpenSees framework. +# +# version created for TACC ranger & their Portland Group Compilers +# +# Written: fmk +# Created: 02/2008 +# +# +############################################################################ + + +# 1. you need load modules in your .bashrc or at commmand line every time you build +# in the .basrc_user, or .cshrc_user you need to add the following + +# module load hdf5 +# module load petsc + +# 2. in your home dir you need a lib and bin folder +# mkdir lib +# mkdir bin + + +# PUT YOUR HOME DIRECTOREY HERE IF NOT THE DEFAULT ONE IN +#HOME = /home1/00477/tg457427/ + +BASE = + +FE = $(HOME)/OpenSees/SRC + +#PROGRAMMING_MODE = SEQUENTIAL +PROGRAMMING_MODE = PARALLEL +#PROGRAMMING_MODE = PARALLEL_INTERPRETERS + +OpenSees_PROGRAM = $(HOME)/bin/OpenSees + +ifeq ($(PROGRAMMING_MODE), PARALLEL) +OpenSees_PROGRAM = $(HOME)/bin/OpenSeesSP +endif +ifeq ($(PROGRAMMING_MODE), PARALLEL_INTERPRETERS) +OpenSees_PROGRAM = $(HOME)/bin/OpenSeesMP +endif + +# %---------------------------------% +# | SECTION 2: MAKEFILE CONSTANTS | +# %---------------------------------% +# +# Specify the constants the are used as control structure variables in the Makefiles. + +OPERATING_SYSTEM = LINUX + +#DEBUG_MODE = DEBUG, NO_DEBUG +DEBUG_MODE = NO_DEBUG + +RELIABILITY = NO_RELIABILITY + +GRAPHICS = NONE + +BLASdir = $(HOME)/OpenSees/OTHER/BLAS +CBLASdir = $(HOME)/OpenSees/OTHER/CBLAS +AMDdir = $(HOME)/OpenSees/OTHER/AMD +LAPACKdir = $(HOME)/OpenSees/OTHER/LAPACK +ARPACKdir = $(HOME)/OpenSees/OTHER/ARPACK +UMFPACKdir = $(HOME)/OpenSees/OTHER/UMFPACK +METISdir = $(HOME)/OpenSees/OTHER/METIS +SRCdir = $(HOME)/OpenSees/SRC +SUPERLUdir = $(HOME)/OpenSees/OTHER/SuperLU_5.1.1/SRC +SUPERLU_DISTdir = $(HOME)/OpenSees/OTHER/SuperLU_DIST_4.3/SRC +CSPARSEdir = $(HOME)/OpenSees/OTHER/CSPARSE + + +DIRS = $(SUPERLUdir) \ + $(SUPERLU_DISTdir) \ + $(ARPACKdir) \ + $(CBLASdir) \ + $(UMFPACKdir) \ + $(AMDdir) \ + $(CSPARSEdir) \ + $(METISdir) \ + $(SRCdir) + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) + +DIRS = \ + $(BLASdir) \ + $(LAPACKdir) \ + $(SUPERLUdir) \ + $(ARPACKdir) \ + $(CBLASdir) \ + $(UMFPACKdir) \ + $(METISdir) \ + $(CSPARSEdir) \ + $(AMDdir) \ + $(SRCdir) +endif + +# %-------------------------------------------------------% +# | SECTION 4: LIBRARIES | +# | | +# | The following section defines the libraries that will | +# | be created and/or linked with when the libraries are | +# | being created or linked with. | +# %-------------------------------------------------------% +# +# Note: if vendor supplied BLAS and LAPACK libraries leave the +# libraries blank. You have to get your own copy of the tcl/tk +# library!! +# +# Note: For libraries that will be created (any in DIRS above) +# make sure the directory exsists where you want the library to go! + +FE_LIBRARY = $(HOME)/lib/libOpenSees.a +NDARRAY_LIBRARY = $(HOME)/lib/libndarray.a # BJ_UCD jeremic@@ucdavis.edu +MATMOD_LIBRARY = $(HOME)/lib/libmatmod.a # BJ_UCD jeremic@@ucdavis.edu +BJMISC_LIBRARY = $(HOME)/lib/libBJmisc.a # BJ_UCD jeremic@@ucdavis.edu +LAPACK_LIBRARY = +BLAS_LIBRARY = +SUPERLU_LIBRARY = $(HOME)/lib/libSuperLU.a +AMD_LIBRARY = $(HOME)/lib/libAMD.a +CBLAS_LIBRARY = $(HOME)/lib/libCBlas.a +ARPACK_LIBRARY = $(HOME)/lib/libArpack.a +UMFPACK_LIBRARY = $(HOME)/lib/libUmfpack.a +METIS_LIBRARY = $(HOME)/lib/libMetis.a +CSPARSE_LIBRARY = $(HOME)/lib/libCSparse.a +DISTRIBUTED_SUPERLU_LIBRARY = $(HOME)/lib/libDistributedSuperLU.a + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) + +DISTRIBUTED_SUPERLU_LIBRARY = +LAPACK_LIBRARY = $(HOME)/lib/libLapack.a +BLAS_LIBRARY = $(HOME)/lib/libBlas.a + +endif + +TCL_LIBRARY = /home1/00477/tg457427/tcl8.6/lib/libtcl8.6.a -lz +#TCL_LIBRARY = -ltcl8.6 +TCL_INCLUDES = + +GRAPHIC_LIBRARY = + +#RELIABILITY_LIBRARY = $(HOME)/lib/libReliability.a +RELIABILITY_LIBRARY = + +# WATCH OUT .. These libraries are removed when 'make wipe' is invoked. + +WIPE_LIBS = $(FE_LIBRARY) \ + $(NDARRAY_LIBRARY) \ + $(MATMOD_LIBRARY) \ + $(SUPERLU_LIBRARY) \ + $(ARPACK_LIBRARY) \ + $(AMD_LIBRARY) \ + $(UMFPACK_LIBRARY) \ + $(METIS_LIBRARY) \ + $(LAPACK_LIBRARY) \ + $(BLAS_LIBRARY) \ + $(CBLAS_LIBRARY) \ + +# %---------------------------------------------------------% +# | SECTION 5: COMPILERS | +# | | +# | The following macros specify compilers, linker/loaders, | +# | the archiver, and their options. You need to make sure | +# | these are correct for your system. | +# %---------------------------------------------------------% + +# ################################################### +# # Compilers +# ################################################### + + +MPI_DIR = $(MPICH_HOME)/intel64 +MPI_BIN = $(MPI_DIR)/bin + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) + +CC++ = $(ICC_BIN)/icpc +CC = $(ICC_BIN)/icc +FC = $(IFC_BIN)/ifort + +#CC++ = g++ +#CC = gcc +#FC = gfortran + +OPT_FLAG = -O2 + +COMP_FLAG = -DMPICH_IGNORE_CXX_SEEK + + +F90 = $(FC) +LINKER = $(CC++) + +else + +CC++ = $(MPI_BIN)/mpicxx +CC = $(MPI_BIN)/mpicc +FC = $(MPI_BIN)/mpif90 +F90 = $(MPI_BIN)/mpif90 +FORTRAN = $(FC) + +LINKER = $(CC++) -mkl + +#OPT_FLAG = -fPIC +#OPT_FLAG = -O2 -xCORE-AVX2 -axCORE-AVX512,MIC-AVX512 + +endif + +C++FLAGS = $(PLAINCONCRETE_FLAG) $(DAMAGE2P_FLAG) -D_LINUX -D_UNIX $(GRAPHIC_FLAG) $(RELIABILITY_FLAG) $(DEBUG_FLAG) $(OPT_FLAG) $(COMP_FLAG) $(H5DRM_FLAG) \ + $(PROGRAMMING_FLAG) $(PETSC_FLAG) $(MUMPS_FLAG) \ + -D_TCL85 -D_BLAS + +CFLAGS = $(RELIABILITY_FLAG) $(DEBUG_FLAG)$(PROGRAMMING_FLAG) $(OPT_FLAG) $(COMP_FLAG) -D_TCL85 -D_BLAS +FFLAGS = $(OPT_FLAG) $(COMP_FLAG) +LINKFLAGS = + + + +AR = ar +ARCH = ar + +ARFLAGS = -q +#ARCHFLAGS = cqls +ARCHFLAGS = -v -q + +RANLIB = ranlib + +RANLIBFLAGS = + + +GRAPHIC_FLAG = -D_NOGRAPHICS +PROGRAMMING_FLAG = + +ifeq ($(PROGRAMMING_MODE), PARALLEL) +PROGRAMMING_FLAG = -D_PARALLEL_PROCESSING +endif + +ifeq ($(PROGRAMMING_MODE), PARALLEL_INTERPRETERS) +PROGRAMMING_FLAG = -D_PARALLEL_INTERPRETERS +endif + +#RELIABILITY_FLAG = -D_RELIABILITY +RELIABILITY_FLAG = + +#DEBUG_FLAG = -D_G3DEBUG +#DEBUG_FLAG = -g -p -pg +#DEBUG_FLAG = -p -g +DEBUG_FLAG = + +H5DRM_FLAG = +DAMAGE2P_FLAG = +PLAINCONCRETE_FLAG = +MUMPS_FLAG = +PETSC_FLAG = + + +# Misc +MAKE = /usr/bin/gmake +CD = cd +ECHO = echo +RM = rm +RMFLAGS = -f +SHELL = /bin/sh + +# %---------------------------------------------------------% +# | SECTION 6: COMPILATION | +# | | +# | The following macros specify the macros used in | +# | to compile the source code into object code. | +# %---------------------------------------------------------% + +.SUFFIXES: +.SUFFIXES: .C .c .f .f90 .cpp .o .cpp + +# +# %------------------% +# | Default command. | +# %------------------% +# +.DEFAULT: + @@$(ECHO) "Unknown target $@@, try: make help" +# +# %-----------------------------------------------% +# | Command to build .o files from source files. | +# %-----------------------------------------------% +# + + +.cpp.o: + @@$(ECHO) Making $@@ from $< $@@ with $(CC++) $(C++FLAGS) $(INCLUDES) -c $< + @@$(CC++) $(C++FLAGS) $(INCLUDES) -c $< + + +.C.o: + @@$(ECHO) Making $@@ from $< + $(CC++) $(C++FLAGS) $(INCLUDES) -c $< + +.c.o: + @@$(ECHO) Making $@@ from $< + $(CC) $(CFLAGS) -c $< + +.f.o: + @@$(ECHO) Making $@@ from $< + $(FC) $(FFLAGS) -c $< + +.f77.o: + @@$(ECHO) Making $@@ from $< + $(FC) $(FFLAGS) -c $< + +.f90.o: + @@$(ECHO) Making $@@ from $< + $(FC90) $(FFLAGS) -c $< + +# %---------------------------------------------------------% +# | SECTION 7: OTHER LIBRARIES | +# | | +# | The following macros specify other libraries that must | +# | be linked with when creating executables. These are | +# | platform specific and typically order does matter!! | +# %---------------------------------------------------------% +MACHINE_LINKLIBS = -L$(BASE)/lib \ + -L$(HOME)/lib + + +# PETSC +HAVEPETSC = NO +PETSCINC = +PETSC_LIB = + +ifeq ($(PROGRAMMMING_MODE), SEQUENTIAL) +HAVEPETSC = NO +endif + + +ifeq ($(HAVEPETSC), YES) + +PETSC = YES +PETSC_FLAG = -D_PETSC +PETSC_DIR = $(TACC_PETSC_DIR) + +BOPT = O + +#PETSC_INC = -I$(PETSC_DIR)/include -I$(PETSC_DIR)/bmake/$(PETSC_ARCH) -D_PETSC +PETSC_INCLUDE = -I$(TACC_PETSC_INC) -I$(PETSC_DIR)/bmake/$(PETSC_ARCH) -D_PETSC + +#PETSC_LIB = -L$(PETSC_DIR)/lib/libO_c++/$(PETSC_ARCH) \ + +PETSC_LIBRARY = -L$(TACC_PETSC_LIB) \ + $(FE)/system_of_eqn/linearSOE/petsc/PetscSOE.o \ + $(FE)/system_of_eqn/linearSOE/petsc/PetscSolver.o \ + $(FE)/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.o \ + -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetsc \ + -L/usr/X11/lib -lX11 -lGL + +endif + +MUMPS_INCLUDE = +MUMPS_LIB = + + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) + +HAVEMUMPS = NO +MUMPS_FLAG = +MUMPS_LIB = + +else + + +MUMPS = YES +MUMPS_FLAG = -D_MUMPS +MUMPS_DIR = /home1/00477/tg457427/MUMPS_5.0.0 + +#MUMPS_DIR = $(TACC_PETSC_LIB)/.. + +PLAT = MPICHGM-INTEL80 + +ifeq ($(PROGRAMMING_MODE), PARALLEL) + +SCALAP = $(BLACSlib) $(SCALAPlib) $(BLACSlib) \ + +endif + +ifeq ($(PROGRAMMING_MODE), PARALLEL_INTERPRETERS) + +SCALAP = \ + $(FE)/system_of_eqn/linearSOE/mumps/MumpsParallelSolver.o \ + $(FE)/system_of_eqn/linearSOE/mumps/MumpsParallelSOE.o \ + $(FE)/system_of_eqn/linearSOE/mumps/MumpsSOE.o \ + $(FE)/system_of_eqn/linearSOE/mumps/MumpsSolver.o \ + $(BLACSlib) $(SCALAPlib) $(BLACSlib) + +# +# +# $(FE)/system_of_eqn/linearSOE/mumps/MumpsSOE.o \ +# $(FE)/system_of_eqn/linearSOE/mumps/MumpsSolver.o \ + +endif + + +MUMPS_LIB = -L$(MUMPS_DIR)/lib \ + -ldmumps -lmumps_common \ + -lpord \ + $(SCALAP) + +MUMPS_INCLUDE = -I$(MUMPS_DIR)/include + +endif + +MKL_LIB = $(MKLROOT)/lib/intel64 + + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) + +PARALLEL_LIB = + +endif + +ifeq ($(PROGRAMMING_MODE), PARALLEL) + +PARALLEL_LIB = \ + -Wl,-rpath,$(MKL_LIB) \ + -L$(MKL_LIB) \ + $(MKL_LIB)/libmkl_scalapack_lp64.a \ + $(MKL_LIB)/libmkl_core.a \ + $(MKL_LIB)/libmkl_blacs_intelmpi_lp64.a \ + $(MKL_LIB)/libmkl_intel_lp64.a \ + $(MKL_LIB)/libmkl_sequential.a \ + $(MKL_LIB)/libmkl_core.a \ + $(MKL_LIB)/libmkl_sequential.a \ + $(MKL_LIB)/libmkl_core.a + +endif + +ifeq ($(PROGRAMMING_MODE), PARALLEL_INTERPRETERS) + +PARALLEL_LIB = \ + -Wl,-rpath,$(MKL_LIB) \ + -L$(MKL_LIB) \ + $(MKL_LIB)/libmkl_scalapack_lp64.a \ + $(MKL_LIB)/libmkl_core.a \ + $(MKL_LIB)/libmkl_blacs_intelmpi_lp64.a \ + $(MKL_LIB)/libmkl_intel_lp64.a \ + $(MKL_LIB)/libmkl_sequential.a \ + $(MKL_LIB)/libmkl_core.a \ + $(MKL_LIB)/libmkl_sequential.a \ + $(MKL_LIB)/libmkl_core.a + + +# $(FE)/system_of_eqn/linearSOE/sparseGEN/SparseGenColLinSolver.o \ +# $(FE)/system_of_eqn/linearSOE/sparseGEN/DistributedSparseGenColLinSOE.o \ +# $(FE)/system_of_eqn/linearSOE/sparseGEN/DistributedSuperLU.o \ + +endif + + +HPM_LIB = + + +MACHINE_NUMERICAL_LIBS = -lm \ + $(ARPACK_LIBRARY) \ + $(SUPERLU_LIBRARY) \ + $(UMFPACK_LIBRARY) \ + $(AMD_LIBRARY) \ + $(GRAPHIC_LIBRARY)\ + $(RELIABILITY_LIBRARY) \ + $(DISTRIBUTED_SUPERLU_LIBRARY) $(CSPARSE_LIBRARY) \ + $(METIS_LIBRARY) $(PETSC_LIBRARY) $(CBLAS_LIBRARY) \ + $(LAPACK_LIBRARY) $(MUMPS_LIB) \ + $(TACC_HDF5_DIR)/lib/libhdf5.a \ + $(TACC_HDF5_DIR)/lib/libsz.a $(PARALLEL_LIB) + +# $(DISTRIBUTED_SUPERLU_LIBRARY) $(METIS_LIBRARY) \ + +ifeq ($(PROGRAMMING_MODE), SEQUENTIAL) + +#MACHINE_SPECIFIC_LIBS = -mkl=sequential -static-intel -lifcore +#MACHINE_SPECIFIC_LIBS = -lpthread -lgfortran -ldl +MACHINE_SPECIFIC_LIBS = -lpthread -static-intel -L$(IFC_LIB) -lifcore + +#MACHINE_SPECIFIC_LIBS = /usr/lib/x86_64-redhat-linux6E/lib64/libpthread.a -lgfortran \ +#/usr/lib/x86_64-redhat-linux6E/lib64/libdl.a \ +#/usr/lib/x86_64-redhat-linux6E/lib64/libc.a \ +#/usr/lib/x86_64-redhat-linux6E/lib64/libm.a -static-libgcc + +else + +MACHINE_SPECIFIC_LIBS = -static-intel -L$(IFC_LIB) -lifcore + +endif + +# %---------------------------------------------------------% +# | SECTION 8: INCLUDE FILES | +# | | +# | The following macros specify include files needed for | +# | compilation. | +# %---------------------------------------------------------% + +MACHINE_INCLUDES = -I$(MPICH_HOME)/include \ + -I/usr/local/BerkeleyDB.4.0/include \ + -I/usr/include/mysql \ + -I$(HOME)/include \ + -I$(UMFPACKdir) \ + -I$(SUPERLUdir) \ + -I$(SUPERLU_DISTdir) -I$(TACC_HDF5_DIR)/include \ + $(PETSC_INCLUDE) $(MUMPS_INCLUDE) + + +# this file contains all the OpenSees/SRC includes +include $(FE)/Makefile.incl + +#TCL_INCLUDES = -I$(HOME)/include +PYTHON_INCLUDES =-I/opt/apps/intel17/python3/3.6.3/include/python3.6m +INCLUDES = $(TCL_INCLUDES) $(PYTHON_INCLUDES) $(FE_INCLUDES) $(MACHINE_INCLUDES) + diff --git a/MAKES/Makefile.def.Ubuntu20.04 b/MAKES/Makefile.def.Ubuntu20.04 new file mode 100644 index 0000000000..73c21aa2b5 --- /dev/null +++ b/MAKES/Makefile.def.Ubuntu20.04 @@ -0,0 +1,282 @@ +############################################################################ +# +# Program: OpenSees +# +# Purpose: A Top-level Makefile to create the libraries needed +# to use the OpenSees framework. Works on Linux version 6.1 +# and belonw. +# +# Written: fmk +# Created: 10/99 +# +# Send bug reports, comments or suggestions to fmckenna@ce.berkeley.edu +# +############################################################################ + + +# Instructuction for building OpenSees on Ubuntu 20.04 +# NOTE: if you plan to contribue code, fork your own github reo in the browser +# and make change to git clone below to point to your own fork. We will +# never give anyone access to repo itself. + + +# mkdir $HOME/lib +# mkdir $HOME/bin +# sudo apt-get update +# sudo apt-get install git +# sudo apt-get install emacs +# sudo apt-get install build-essential +# sudo apt-get install gfortran +# wget https://prdownloads.sourceforge.net/tcl/tcl8.6.10-src.tar.gz +# tar zxBf tcl8.6.tar.gz +# cd tcl8.6.10/unix +# configure --prefx=$HOME/tcl8.6 --enable-static --disable-shared --enable-64bit +# make +# make install +# cd $HOME +# git clone https://github.com/OpenSees/OpenSees.git +# cd OpenSees +# cp ./MAKES/Makefile.def.Ubuntu20.04 ./Makefile.def +# make + + +#INTERPRETER_LANGUAGE = PYTHON +INTERPRETER_LANGUAGE = TCL + +# %---------------------------------% +# | SECTION 1: PROGRAM | +# %---------------------------------% +# +# Specify the location and name of the OpenSees interpreter program +# that will be created (if this all works!) + +OpenSees_PROGRAM = $(HOME)/bin/OpenSees + +OPERATING_SYSTEM = LINUX +GRAPHICS = NONE +GRAPHIC_FLAG = -D_NOGRAPHICS +PROGRAMMING_MODE = SEQUENTIAL +DEBUG_MODE = NO_DEBUG +RELIABILITY = NO_RELIABILITY + + +# %---------------------------------% +# | SECTION 2: PATHS | +# %---------------------------------% +# +# Note: if vendor supplied BLAS and LAPACK libraries or if you have +# any of the libraries already leave the directory location blank AND +# remove the directory from DIRS. + +BASE = ./usr/local +FE = $(HOME)/OpenSees/SRC + +AMDdir = $(HOME)/OpenSees/OTHER/AMD +BLASdir = $(HOME)/OpenSees/OTHER/BLAS +CBLASdir = $(HOME)/OpenSees/OTHER/CBLAS +LAPACKdir = $(HOME)/OpenSees/OTHER/LAPACK +SUPERLUdir = $(HOME)/OpenSees/OTHER/SuperLU_5.1.1/SRC +ARPACKdir = $(HOME)/OpenSees/OTHER/ARPACK +UMFPACKdir = $(HOME)/OpenSees/OTHER/UMFPACK +METISdir = $(HOME)/OpenSees/OTHER/METIS +CSPARSEdir = $(HOME)/OpenSees/OTHER/CSPARSE +SRCdir = $(HOME)/OpenSees/SRC + + +DIRS = $(BLASdir) $(CBLASdir) $(LAPACKdir) $(AMDdir) $(CSPARSEdir) \ + $(SUPERLUdir) $(ARPACKdir) $(UMFPACKdir) $(SRCdir) $(METISdir) + +# %-------------------------------------------------------% +# | SECTION 3: LIBRARIES | +# | | +# | The following section defines the libraries that will | +# | be created and/or linked with when the libraries are | +# | being created or linked with. | +# %-------------------------------------------------------% +# +# Note: if vendor supplied BLAS and LAPACK libraries leave the +# libraries blank. You have to get your own copy of the tcl/tk +# library!! +# +# Note: For libraries that will be created (any in DIRS above) +# make sure the directory exsists where you want the library to go! + +FE_LIBRARY = $(HOME)/lib/libOpenSees.a +NDARRAY_LIBRARY = $(HOME)/lib/libndarray.a # BJ_UCD jeremic@ucdavis.edu +MATMOD_LIBRARY = $(HOME)/lib/libmatmod.a # BJ_UCD jeremic@ucdavis.edu +BJMISC_LIBRARY = $(HOME)/lib/libBJmisc.a # BJ_UCD jeremic@ucdavis.edu +LAPACK_LIBRARY = $(HOME)/lib/libLapack.a +BLAS_LIBRARY = $(HOME)/lib/libBlas.a +SUPERLU_LIBRARY = $(HOME)/lib/libSuperLU.a +CBLAS_LIBRARY = $(HOME)/lib/libCBlas.a +ARPACK_LIBRARY = $(HOME)/lib/libArpack.a +AMD_LIBRARY = $(HOME)/lib/libAMD.a +UMFPACK_LIBRARY = $(HOME)/lib/libUmfpack.a +METIS_LIBRARY = $(HOME)/lib/libMetis.a +CSPARSE_LIBRARY = $(HOME)/lib/libCSparse.a + +TCL_LIBRARY = $(HOME)/tcl8.6/lib/libtcl8.6.a + +BLITZ_LIBRARY = $(HOME)/blitz/lib/libblitz.a +GRAPHIC_LIBRARY = + +# WATCH OUT .. These libraries are removed when 'make wipe' is invoked. +WIPE_LIBS = $(FE_LIBRARY) \ + $(LAPACK_LIBRARY) \ + $(BLAS_LIBRARY) \ + $(CBLAS_LIBRARY) \ + $(SUPERLU_LIBRARY) \ + $(ARPACK_LIBRARY) \ + $(UMFPACK_LIBRARY) \ + $(CSPARSE_LIBRARY) \ + $(METIS_LIBRARY) + +# %---------------------------------------------------------% +# | SECTION 4: COMPILERS | +# | | +# | The following macros specify compilers, linker/loaders, | +# | the archiver, and their options. You need to make sure | +# | these are correct for your system. | +# %---------------------------------------------------------% + +# Compilers +CC++ = /usr/bin/g++ +CC = /usr/bin/gcc +FC = /usr/bin/gfortran + +AR = ar +ARFLAGS = cqls +RANLIB = ranlib +RANLIBFLAGS = + +# Compiler Flags +# +# NOTES/lib/x86_64-linux-gnu/: +# C++ FLAGS TAKE need _UNIX or _WIN32 for preprocessor dircetives +# - the _WIN32 for the Windows95/98 or NT operating system. +# C FLAGS used -DUSE_VENDOR_BLAS (needed in SuperLU) if UNIX in C++ FLAGS +# + +# modified as optimizaton currently causing problems with Steeln01 code +ifeq ($(INTERPRETER_LANGUAGE), PYTHON) + + +C++FLAGS = -Wall -D_LINUX -D_UNIX -D_TCL85 \ + $(GRAPHIC_FLAG) $(RELIABILITY_FLAG) $(DEBUG_FLAG) \ + $(PROGRAMMING_FLAG) -fPIC -ffloat-store +CFLAGS = -Wall -fPIC +FFLAGS = -Wall -fPIC + +# Linker +LINKER = $(CC++) +LINKFLAGS = -g -pg + +else + +C++FLAGS = -Wall -D_LINUX -D_UNIX -D_TCL85 \ + $(GRAPHIC_FLAG) $(RELIABILITY_FLAG) $(DEBUG_FLAG) \ + $(PROGRAMMING_FLAG) -O3 -ffloat-store +CFLAGS = -Wall -O2 +FFLAGS = -Wall -O + +# Linker +LINKER = $(CC++) +LINKFLAGS = -rdynamic + +endif + + +# Misc +MAKE = make +CD = cd +ECHO = echo +RM = rm +RMFLAGS = -f +SHELL = /bin/sh + +# %---------------------------------------------------------% +# | SECTION 5: COMPILATION | +# | | +# | The following macros specify the macros used in | +# | to compile the source code into object code. | +# %---------------------------------------------------------% + +.SUFFIXES: +.SUFFIXES: .C .c .f .f90 .cpp .o .cpp + +# +# %------------------% +# | Default command. | +# %------------------% +# +.DEFAULT: + @$(ECHO) "Unknown target $@, try: make help" +# +# %-------------------------------------------% +# | Command to build .o files from .f files. | +# %-------------------------------------------% +# + +.cpp.o: + @$(ECHO) Making $@ from $< + $(CC++) $(C++FLAGS) $(INCLUDES) -c $< -o $@ + +.C.o: + @$(ECHO) Making $@ from $< + $(CC++) $(C++FLAGS) $(INCLUDES) -c $< -o $@ +.c.o: + @$(ECHO) Making $@ from $< + $(CC) $(CFLAGS) -c $< -o $@ +.f.o: + @$(ECHO) Making $@ from $< + $(FC) $(FFLAGS) -c $< -o $@ + +# %---------------------------------------------------------% +# | SECTION 6: OTHER LIBRARIES | +# | | +# | The following macros specify other libraries that must | +# | be linked with when creating executables. These are | +# | platform specific and typically order does matter!! | +# %---------------------------------------------------------% +MACHINE_LINKLIBS = -L$(BASE)/lib \ + -L$(HOME)/lib + +MACHINE_NUMERICAL_LIBS = -lm \ + $(ARPACK_LIBRARY) \ + $(SUPERLU_LIBRARY) \ + $(UMFPACK_LIBRARY) $(CSPARSE_LIBRARY) \ + $(LAPACK_LIBRARY) $(BLAS_LIBRARY) $(CBLAS_LIBRARY) \ + $(AMD_LIBRARY) $(GRAPHIC_LIBRARY)\ + -ldl -lgfortran + +MACHINE_SPECIFIC_LIBS = -lpthread + + + +# %---------------------------------------------------------% +# | SECTION 7: INCLUDE FILES | +# | | +# | The following macros specify include files needed for | +# | compilation. | +# %---------------------------------------------------------% +MACHINE_INCLUDES = -I/usr/include \ + -I$(BASE)/include \ + -I/usr/include/cxx \ + -I$(HOME)/include -I$(HOME)/blitz + +# this file contains all the OpenSees/SRC includes +include $(FE)/Makefile.incl + +#TCL_INCLUDES = -I/usr/includes/tcl-private/generic +TCL_INCLUDES = -I$(HOME)/tcl8.6/include +PYTHON_INCLUDES = -I/usr/include/python3.5 + +INCLUDES = $(TCL_INCLUDES) $(FE_INCLUDES) $(MACHINE_INCLUDES) $(PYTHON_INCLUDES) + + + + + + + + diff --git a/OTHER/AMD/Makefile b/OTHER/AMD/Makefile index 27e235f317..73c885a6dd 100644 --- a/OTHER/AMD/Makefile +++ b/OTHER/AMD/Makefile @@ -2,7 +2,7 @@ include ../../Makefile.def all: $(AMD_LIBRARY) -C = $(CC) -O3 -fexceptions -fPIC -I. +C = $(CC) $(OPT_FLAG) -fexceptions -fPIC -I. #------------------------------------------------------------------------------- # source files diff --git a/OTHER/UMFPACK/Makefile b/OTHER/UMFPACK/Makefile index 94dd4e7815..579753f000 100644 --- a/OTHER/UMFPACK/Makefile +++ b/OTHER/UMFPACK/Makefile @@ -1,7 +1,7 @@ include ../../Makefile.def I = -I. -I../AMD -C = $(CC) -O3 -fexceptions -fPIC -DNCHOLMOD $(I) +C = $(CC) $(OPT_FLAG) -fexceptions -fPIC -DNCHOLMOD $(I) #------------------------------------------------------------------------------- # source files diff --git a/SCRIPTS/toOpenSeesPy.py b/SCRIPTS/toOpenSeesPy.py index fbd79cd9f2..75bbf542a7 100644 --- a/SCRIPTS/toOpenSeesPy.py +++ b/SCRIPTS/toOpenSeesPy.py @@ -77,8 +77,10 @@ def toOpenSeesPy(infile, outfile): secTag = info[6] eleTag = info[2] Np = info[5] - Np = 3 - outfile.write('ops.beamIntegration(\'Legendre\',%s,%s,%s)\n' % (eleTag,secTag,Np)) + if info[1] == 'dispBeamColumn': + outfile.write('ops.beamIntegration(\'Legendre\',%s,%s,%s)\n' % (eleTag,secTag,Np)) + if info[1] == 'forceBeamColumn': + outfile.write('ops.beamIntegration(\'Lobatto\',%s,%s,%s)\n' % (eleTag,secTag,Np)) outfile.write('ops.element(\'%s\',%s,%s,%s,%s,%s)\n' % (info[1],eleTag,info[3],info[4],info[7],eleTag)) continue @@ -100,6 +102,11 @@ def toOpenSeesPy(infile, outfile): if info[i] == '}': writeClose = False break + if info[0] == 'recorder': + # If it's a recorder, make everything immediately after material, section, or fiber a string + if info[i-1] in ['material','section','fiber'] and isfloat(info[i]): + outfile.write(',str(%s)' % info[i]) + continue if isfloat(info[i]): outfile.write(',%s' % info[i]) else: diff --git a/SRC/Makefile b/SRC/Makefile index 0619214624..b31bd323ba 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -217,6 +217,7 @@ REMO_LIBS = $(FE)/element/nonlinearBeamColumn/matrixutil/MatrixUtil.o \ $(FE)/element/forceBeamColumn/ForceBeamColumnCBDI2d.o \ $(FE)/element/forceBeamColumn/ForceBeamColumnWarping2d.o \ $(FE)/element/forceBeamColumn/ForceBeamColumn3d.o \ + $(FE)/element/forceBeamColumn/ForceBeamColumnCBDI3d.o \ $(FE)/element/forceBeamColumn/ElasticForceBeamColumn2d.o \ $(FE)/element/forceBeamColumn/ElasticForceBeamColumnWarping2d.o \ $(FE)/element/forceBeamColumn/ElasticForceBeamColumn3d.o \ @@ -419,6 +420,8 @@ RECORDER_LIBS = $(FE)/recorder/Recorder.o \ $(FE)/recorder/PVDRecorder.o \ $(FE)/recorder/GmshRecorder.o \ $(FE)/recorder/MPCORecorder.o \ + $(FE)/recorder/ElementRecorderRMS.o \ + $(FE)/recorder/NodeRecorderRMS.o \ $(FE)/recorder/VTK_Recorder.o @@ -524,6 +527,7 @@ ELE_LIBS = $(FE)/element/Element.o \ $(FE)/element/elasticBeamColumn/WheelRail.o \ $(FE)/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn2d.o \ $(FE)/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn3d.o \ + $(FE)/element/gradientInelasticBeamColumn/TclGradientInelasticBeamColumnCommand.o \ $(FE)/element/mixedBeamColumn/MixedBeamColumn2d.o \ $(FE)/element/mixedBeamColumn/MixedBeamColumn3d.o \ $(FE)/element/fourNodeQuad/FourNodeQuad.o \ @@ -533,6 +537,9 @@ ELE_LIBS = $(FE)/element/Element.o \ $(FE)/element/fourNodeQuad/EnhancedQuad.o \ $(FE)/element/componentElement/ComponentElement2d.o \ $(FE)/element/fourNodeQuad/NineNodeMixedQuad.o \ + $(FE)/element/fourNodeQuad/NineNodeQuad.o \ + $(FE)/element/fourNodeQuad/EightNodeQuad.o \ + $(FE)/element/fourNodeQuad/SixNodeTri.o \ $(FE)/element/shell/ShellMITC4.o \ $(FE)/element/shell/ShellMITC4Thermal.o \ $(FE)/element/shell/ShellMITC9.o \ @@ -541,6 +548,7 @@ ELE_LIBS = $(FE)/element/Element.o \ $(FE)/element/shell/ShellDKGT.o \ $(FE)/element/shell/ShellNLDKGT.o \ $(FE)/element/shell/ShellNLDKGQThermal.o \ + $(FE)/element/shell/ASDShellQ4.o \ $(FE)/element/shell/R3vectors.o \ $(FE)/element/shell/ShellANDeS.o \ $(FE)/element/brick/Brick.o \ @@ -656,7 +664,11 @@ endif ifdef PLAINCONCRETE_FLAG - PLAINCONCRETE = $(FE)/material/nD/PlainConcrete.o $(FE)/material/nD/forumat.o + PLAINCONCRETE = $(FE)/material/nD/PlainConcrete.o $(FE)/material/nD/forumat.o \ + $(FE)/element/PML/PMLDynamicSymmDamp3D.o \ + $(FE)/element/PML/PML3D.o \ + $(FE)/element/PML/PMLDynamicSymmDamp2D.o \ + $(FE)/element/PML/PML2D.o else PLAINCONCRETE = endif @@ -696,6 +708,7 @@ MATERIAL_LIBS = $(FE)/material/Material.o \ $(FE)/material/uniaxial/ParallelMaterial.o \ $(FE)/material/uniaxial/SeriesMaterial.o \ $(FE)/material/uniaxial/Neoprene.o \ + $(FE)/material/uniaxial/ASD_SMA_3K.o \ $(FE)/material/uniaxial/Concrete01.o \ $(FE)/material/uniaxial/Concrete02.o \ $(FE)/material/uniaxial/Concrete02IS.o \ @@ -792,6 +805,7 @@ MATERIAL_LIBS = $(FE)/material/Material.o \ $(FE)/material/uniaxial/TDConcreteMC10NL.o \ $(FE)/material/uniaxial/TDConcreteMC10NL.o \ $(FE)/material/uniaxial/DegradingPinchedBW.o \ + $(FE)/material/uniaxial/SLModel.o \ $(FE)/material/uniaxial/MaterialState.o \ $(FE)/material/uniaxial/backbone/HystereticBackbone.o \ $(FE)/material/uniaxial/backbone/ArctangentBackbone.o \ @@ -887,6 +901,7 @@ MATERIAL_LIBS = $(FE)/material/Material.o \ $(FE)/material/nD/ElasticIsotropicPlateFiber.o \ $(FE)/material/nD/ElasticIsotropicBeamFiber.o \ $(FE)/material/nD/ElasticIsotropicBeamFiber2d.o \ + $(FE)/material/nD/IncrementalElasticIsotropicThreeDimensional.o \ $(FE)/material/nD/ElasticOrthotropicMaterial.o \ $(FE)/material/nD/ElasticOrthotropicThreeDimensional.o \ $(FE)/material/nD/PlaneStressMaterial.o \ @@ -1225,6 +1240,7 @@ ANALYSIS_LIBS = $(FE)/analysis/analysis/Analysis.o \ $(FE)/analysis/algorithm/equiSolnAlgo/BFGS.o \ $(FE)/analysis/algorithm/equiSolnAlgo/KrylovNewton.o \ $(FE)/analysis/algorithm/equiSolnAlgo/PeriodicNewton.o \ + $(FE)/analysis/algorithm/equiSolnAlgo/ExpressNewton.o \ $(FE)/analysis/algorithm/equiSolnAlgo/LineSearch.o \ $(FE)/analysis/algorithm/equiSolnAlgo/BisectionLineSearch.o \ $(FE)/analysis/algorithm/equiSolnAlgo/SecantLineSearch.o \ @@ -1255,6 +1271,8 @@ ANALYSIS_LIBS = $(FE)/analysis/analysis/Analysis.o \ $(FE)/analysis/integrator/IncrementalIntegrator.o \ $(FE)/analysis/integrator/StaticIntegrator.o \ $(FE)/analysis/integrator/LoadControl.o \ + $(FE)/analysis/integrator/StagedLoadControl.o \ + $(FE)/analysis/integrator/StagedNewmark.o \ $(FE)/analysis/integrator/EQPath.o \ $(FE)/analysis/integrator/LoadPath.o \ $(FE)/analysis/integrator/ArcLength.o \ diff --git a/SRC/OPS_Globals.h b/SRC/OPS_Globals.h index 357ad76c44..9d6d2330be 100644 --- a/SRC/OPS_Globals.h +++ b/SRC/OPS_Globals.h @@ -28,7 +28,7 @@ // if you change some of the variables, you must recompile ALL the code. -#define OPS_VERSION "3.2.1" +#define OPS_VERSION "3.2.2" #ifdef _WIN32 #ifndef _WIN64 diff --git a/SRC/actor/channel/TCP_Socket.cpp b/SRC/actor/channel/TCP_Socket.cpp index 31f6ebd552..c598b2276c 100644 --- a/SRC/actor/channel/TCP_Socket.cpp +++ b/SRC/actor/channel/TCP_Socket.cpp @@ -858,7 +858,7 @@ TCP_Socket::getBytesAvailable() char * TCP_Socket::addToProgram() { - char *tcp = " 1 "; + const char *tcp = " 1 "; char my_InetAddr[MAX_INET_ADDR]; char myPortNum[8]; diff --git a/SRC/actor/channel/UDP_Socket.cpp b/SRC/actor/channel/UDP_Socket.cpp index bfefb7a823..435180db7c 100644 --- a/SRC/actor/channel/UDP_Socket.cpp +++ b/SRC/actor/channel/UDP_Socket.cpp @@ -822,7 +822,7 @@ UDP_Socket::getBytesAvailable() char * UDP_Socket::addToProgram() { - char *tcp = " 2 "; + const char *tcp = " 2 "; char my_InetAddr[MAX_INET_ADDR]; char myPortNum[8]; diff --git a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp index 7d0dec6725..1332011203 100644 --- a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp +++ b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp @@ -37,489 +37,498 @@ #include // ActorTypes -#include +#include "domain/subdomain/ActorSubdomain.h" // Convergence tests -#include -#include -#include -#include -#include -#include -#include -#include +#include "convergenceTest/CTestNormUnbalance.h" +#include "convergenceTest/CTestRelativeNormUnbalance.h" +#include "convergenceTest/CTestNormDispIncr.h" +#include "convergenceTest/CTestRelativeNormDispIncr.h" +#include "convergenceTest/CTestRelativeTotalNormDispIncr.h" +#include "convergenceTest/CTestEnergyIncr.h" +#include "convergenceTest/CTestRelativeEnergyIncr.h" +#include "convergenceTest/CTestFixedNumIter.h" // graph numbering schemes -#include -#include -#include +#include "graph/numberer/RCM.h" +#include "graph/numberer/MyRCM.h" +#include "graph/numberer/SimpleNumberer.h" // uniaxial material model header files -#include //SAJalali -#include //SAJalali -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "BoucWenMaterial.h" //SAJalali +#include "SPSW02.h" //SAJalali +#include "ElasticMaterial.h" +#include "ElasticMultiLinear.h" +#include "ElasticPowerFunc.h" +#include "Elastic2Material.h" +#include "ElasticPPMaterial.h" +#include "ParallelMaterial.h" +#include "ASD_SMA_3K.h" +#include "Concrete01.h" +#include "Concrete02.h" +#include "Concrete04.h" +#include "Concrete06.h" +#include "Concrete07.h" +#include "ConcretewBeta.h" +#include "OriginCentered.h" +#include "Steel01.h" +#include "Steel02.h" +#include "Steel2.h" +#include "Steel4.h" +#include "FatigueMaterial.h" +#include "ReinforcingSteel.h" +#include "HardeningMaterial.h" +#include "HystereticMaterial.h" +#include "EPPGapMaterial.h" +#include "ViscousMaterial.h" +#include "ViscousDamper.h" +#include "PathIndependentMaterial.h" +#include "SeriesMaterial.h" +#include "CableMaterial.h" +#include "ENTMaterial.h" +#include "MinMaxMaterial.h" +#include "ModIMKPeakOriented.h" +#include "snap/Clough.h" +#include "limitState/LimitStateMaterial.h" +#include "InitStressMaterial.h" +#include "InitStrainMaterial.h" +#include "Bond_SP01.h" +#include "SimpleFractureMaterial.h" +#include "ConfinedConcrete01.h" //PY springs: RWBoulanger and BJeremic -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include +#include "PY/PySimple1.h" +#include "PY/TzSimple1.h" +#include "PY/QzSimple1.h" +#include "PY/PySimple2.h" +#include "PY/TzSimple2.h" +#include "PY/QzSimple2.h" +#include "PY/PyLiq1.h" +#include "PY/TzLiq1.h" + +#include "fedeas/FedeasBond1Material.h" +#include "fedeas/FedeasBond2Material.h" +#include "fedeas/FedeasConcr1Material.h" +#include "fedeas/FedeasConcr2Material.h" +#include "fedeas/FedeasConcr3Material.h" +#include "fedeas/FedeasHardeningMaterial.h" +#include "fedeas/FedeasHyster1Material.h" +#include "fedeas/FedeasHyster2Material.h" +#include "fedeas/FedeasSteel1Material.h" +#include "fedeas/FedeasSteel2Material.h" + +#include "Bilin.h" +#include "drain/DrainBilinearMaterial.h" +#include "drain/DrainClough1Material.h" +#include "drain/DrainClough2Material.h" +#include "drain/DrainPinch1Material.h" +#include "HyperbolicGapMaterial.h" +#include "ImpactMaterial.h" // Sections -#include -#include -#include -#include -#include -//#include -#include -//#include -#include -#include -#include -#include -#include -#include -#include // Yuli Huang & Xinzheng Lu +#include "ElasticSection2d.h" +#include "ElasticSection3d.h" +#include "ElasticShearSection2d.h" +#include "ElasticShearSection3d.h" +#include "GenericSection1d.h" +//#include "GenericSectionNd.h" +#include "SectionAggregator.h" +//#include "FiberSection.h" +#include "FiberSection2d.h" +#include "FiberSection3d.h" +#include "ElasticPlateSection.h" +#include "ElasticMembranePlateSection.h" +#include "MembranePlateFiberSection.h" +#include "Bidirectional.h" +#include "LayeredShellFiberSection.h" // Yuli Huang & Xinzheng Lu // NDMaterials -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "ElasticIsotropicPlaneStrain2D.h" +#include "ElasticIsotropicPlaneStress2D.h" +#include "ElasticIsotropicPlateFiber.h" +#include "ElasticIsotropicAxiSymm.h" +#include "ElasticIsotropicThreeDimensional.h" +#include "J2PlaneStrain.h" +#include "J2PlaneStress.h" +#include "J2PlateFiber.h" +#include "J2AxiSymm.h" +#include "J2ThreeDimensional.h" +#include "PlaneStressMaterial.h" +#include "PlateFiberMaterial.h" //start Yuli Huang & Xinzheng L -#include -#include -//#include -#include +#include "PlateRebarMaterial.h" +#include "PlateFromPlaneStressMaterial.h" +//#include "ConcreteS.h" +#include "PlaneStressUserMaterial.h" //end Yuli Huang & Xinzheng Lu -#include -#include -#include -#include -#include - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "feap/FeapMaterial03.h" +#include "CycLiqCP3D.h" +#include "CycLiqCPPlaneStrain.h" +#include "CycLiqCPSP3D.h" +#include "CycLiqCPSPPlaneStrain.h" + + +#include "soil/FluidSolidPorousMaterial.h" +#include "soil/PressureDependMultiYield.h" +#include "soil/PressureDependMultiYield02.h" +#include "soil/PressureIndependMultiYield.h" + +#include "UWmaterials/ContactMaterial2D.h" +#include "UWmaterials/ContactMaterial3D.h" +#include "UWmaterials/DruckerPrager3D.h" +#include "UWmaterials/DruckerPragerPlaneStrain.h" +#include "UWmaterials/BoundingCamClay.h" +#include "UWmaterials/BoundingCamClay3D.h" +#include "UWmaterials/BoundingCamClayPlaneStrain.h" +#include "UWmaterials/ManzariDafalias.h" +#include "UWmaterials/ManzariDafalias3D.h" +#include "UWmaterials/ManzariDafaliasPlaneStrain.h" +#include "UWmaterials/ManzariDafaliasRO.h" +#include "UWmaterials/ManzariDafalias3DRO.h" +#include "UWmaterials/ManzariDafaliasPlaneStrainRO.h" +#include "UWmaterials/PM4Sand.h" +#include "UWmaterials/PM4Silt.h" +#include "UWmaterials/InitialStateAnalysisWrapper.h" #if !_DLL -#include +#include "stressDensityModel/stressDensity.h" #endif -#include +#include "InitStressNDMaterial.h" // Fibers -#include -#include +#include "fiber/UniaxialFiber2d.h" +#include "fiber/UniaxialFiber3d.h" // friction models -#include -#include -#include -#include -#include +#include "frictionBearing/frictionModel/Coulomb.h" +#include "frictionBearing/frictionModel/VelDependent.h" +#include "frictionBearing/frictionModel/VelPressureDep.h" +#include "frictionBearing/frictionModel/VelDepMultiLinear.h" +#include "frictionBearing/frictionModel/VelNormalFrcDep.h" // element header files -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#include //SAJalali -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu -#include //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu -#include -#include -#include // Arash -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "Element.h" +#include "truss/Truss.h" +#include "truss/Truss2.h" +#include "truss/TrussSection.h" +#include "truss/CorotTruss.h" +#include "truss/CorotTrussSection.h" +#include "zeroLength/ZeroLength.h" +#include "zeroLength/ZeroLengthSection.h" +#include "zeroLength/ZeroLengthContact2D.h" +#include "zeroLength/ZeroLengthContact3D.h" +#include "zeroLength/ZeroLengthContactNTS2D.h" +#include "zeroLength/ZeroLengthInterface2D.h" +//#include "ZeroLengthND.h" + +#include "fourNodeQuad/FourNodeQuad.h" +#include "fourNodeQuad/EnhancedQuad.h" +#include "fourNodeQuad/NineNodeMixedQuad.h" +#include "fourNodeQuad/NineNodeQuad.h" +#include "fourNodeQuad/EightNodeQuad.h" +#include "fourNodeQuad/ConstantPressureVolumeQuad.h" +#include "elasticBeamColumn/ElasticBeam2d.h" +#include "elasticBeamColumn/ElasticBeam3d.h" +#include "elasticBeamColumn/ModElasticBeam2d.h" //SAJalali +#include "elasticBeamColumn/ElasticTimoshenkoBeam2d.h" +#include "elasticBeamColumn/ElasticTimoshenkoBeam3d.h" +#include "forceBeamColumn/ForceBeamColumn2d.h" +#include "forceBeamColumn/ForceBeamColumn3d.h" +#include "triangle/Tri31.h" + +#include "UWelements/SSPquad.h" +#include "UWelements/SSPquadUP.h" +#include "UWelements/SSPbrick.h" +#include "UWelements/SSPbrickUP.h" +#include "UWelements/BeamContact2D.h" +#include "UWelements/BeamContact2Dp.h" +#include "UWelements/BeamContact3D.h" +#include "UWelements/BeamContact3Dp.h" +#include "UWelements/BeamEndContact3D.h" +#include "UWelements/BeamEndContact3Dp.h" +#include "UWelements/QuadBeamEmbedContact.h" + +#include "UP-ucsd/Nine_Four_Node_QuadUP.h" +#include "UP-ucsd/BrickUP.h" +#include "UP-ucsd/BBarBrickUP.h" +#include "UP-ucsd/BBarFourNodeQuadUP.h" +#include "UP-ucsd/Twenty_Eight_Node_BrickUP.h" +#include "UP-ucsd/FourNodeQuadUP.h" + +#include "dispBeamColumn/DispBeamColumn2d.h" +#include "dispBeamColumn/DispBeamColumn3d.h" +#include "shell/ShellMITC4.h" +#include "shell/ShellMITC9.h" +#include "shell/ShellDKGQ.h" //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu +#include "shell/ShellNLDKGQ.h" //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu +#include "shell/ASDShellQ4.h" // Massimo Petracca +#include "brick/Brick.h" +#include "brick/BbarBrick.h" +#include "joint/Joint2D.h" // Arash +#include "twoNodeLink/TwoNodeLink.h" +#include "twoNodeLink/LinearElasticSpring.h" +#include "twoNodeLink/Inerter.h" + +#include "elastomericBearing/ElastomericBearingBoucWen2d.h" +#include "elastomericBearing/ElastomericBearingBoucWen3d.h" +#include "elastomericBearing/ElastomericBearingPlasticity2d.h" +#include "elastomericBearing/ElastomericBearingPlasticity3d.h" +#include "elastomericBearing/ElastomericBearingUFRP2d.h" +#include "elastomericBearing/ElastomericX.h" +#include "elastomericBearing/HDR.h" +#include "elastomericBearing/LeadRubberX.h" + +#include "frictionBearing/FlatSliderSimple2d.h" +#include "frictionBearing/FlatSliderSimple3d.h" +#include "frictionBearing/FPBearingPTV.h" +#include "frictionBearing/RJWatsonEQS2d.h" +#include "frictionBearing/RJWatsonEQS3d.h" +#include "frictionBearing/SingleFPSimple2d.h" +#include "frictionBearing/SingleFPSimple3d.h" +#include "frictionBearing/TripleFrictionPendulum.h" + +#include "PFEMElement/PFEMElement2D.h" + +#include "LinearCrdTransf2d.h" +#include "LinearCrdTransf3d.h" +#include "PDeltaCrdTransf2d.h" +#include "PDeltaCrdTransf3d.h" +#include "CorotCrdTransf2d.h" +#include "CorotCrdTransf3d.h" + +#include "HingeMidpointBeamIntegration.h" +#include "HingeEndpointBeamIntegration.h" +#include "HingeRadauBeamIntegration.h" +#include "HingeRadauTwoBeamIntegration.h" +#include "UserDefinedHingeIntegration.h" +#include "DistHingeIntegration.h" +#include "RegularizedHingeIntegration.h" + +#include "LobattoBeamIntegration.h" +#include "LegendreBeamIntegration.h" +#include "RadauBeamIntegration.h" +#include "NewtonCotesBeamIntegration.h" +#include "TrapezoidalBeamIntegration.h" +#include "UserDefinedBeamIntegration.h" +#include "FixedLocationBeamIntegration.h" +#include "LowOrderBeamIntegration.h" +#include "MidDistanceBeamIntegration.h" +#include "CompositeSimpsonBeamIntegration.h" // node header files -#include - - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include +#include "Node.h" + + +#include "FileStream.h" +#include "StandardStream.h" +#include "XmlFileStream.h" +#include "DataFileStream.h" +#include "DataFileStreamAdd.h" +#include "BinaryFileStream.h" +#include "DatabaseStream.h" +#include "DummyStream.h" + +#include "NodeRecorder.h" +#include "ElementRecorder.h" +#include "EnvelopeNodeRecorder.h" +#include "EnvelopeElementRecorder.h" +#include "DriftRecorder.h" +#include "MPCORecorder.h" +#include "VTK_Recorder.h" +#include "GmshRecorder.h" // mp_constraint header files -#include -#include +#include "MP_Constraint.h" +#include "joint/MP_Joint2D.h" // sp_constraint header files -#include -#include -#include -#include +#include "SP_Constraint.h" +#include "SP_Constraint.h" +#include "ImposedMotionSP.h" +#include "ImposedMotionSP1.h" // Pressure_Constraint header file -#include +#include "Pressure_Constraint.h" // nodal load header files -#include +#include "NodalLoad.h" // elemental load header files -#include -#include -#include -#include -#include -#include -#include +#include "ElementalLoad.h" +#include "Beam2dUniformLoad.h" +#include "Beam2dPointLoad.h" +#include "Beam3dUniformLoad.h" +#include "Beam3dPointLoad.h" +#include "BrickSelfWeight.h" +#include "SelfWeight.h" +#include "SurfaceLoader.h" // matrix, vector & id header files -#include -#include -#include +#include "Matrix.h" +#include "Vector.h" +#include "ID.h" // subdomain header files -#include +#include "Subdomain.h" // constraint handler header files -#include -#include -#include -#include -#include +#include "ConstraintHandler.h" +#include "PlainHandler.h" +#include "PenaltyConstraintHandler.h" +#include "LagrangeConstraintHandler.h" +#include "TransformationConstraintHandler.h" // dof numberer header files -#include -#include +#include "DOF_Numberer.h" +#include "PlainNumberer.h" // analysis model header files -#include +#include "AnalysisModel.h" // equi soln algo header files -#include -#include -#include -#include -#include -#include -#include -#include +#include "EquiSolnAlgo.h" +#include "Linear.h" +#include "NewtonRaphson.h" +#include "Broyden.h" +#include "NewtonLineSearch.h" +#include "KrylovNewton.h" +#include "AcceleratedNewton.h" +#include "ModifiedNewton.h" -#include -#include +#include "accelerator/KrylovAccelerator.h" +#include "accelerator/RaphsonAccelerator.h" -#include -#include -#include -#include +#include "BisectionLineSearch.h" +#include "InitialInterpolatedLineSearch.h" +#include "RegulaFalsiLineSearch.h" +#include "SecantLineSearch.h" // domain decomp soln algo header files -#include +#include "DomainDecompAlgo.h" // integrator header files -#include -#include +#include "ArcLength.h" +#include "DisplacementControl.h" #ifdef _PARALLEL_PROCESSING -#include +#include "DistributedDisplacementControl.h" #endif -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "LoadControl.h" +#include "StagedLoadControl.h" + +#include "TransientIntegrator.h" +#include "AlphaOS.h" +#include "AlphaOS_TP.h" +#include "AlphaOSGeneralized.h" +#include "AlphaOSGeneralized_TP.h" +#include "CentralDifference.h" +#include "CentralDifferenceAlternative.h" +#include "CentralDifferenceNoDamping.h" +#include "Collocation.h" +#include "CollocationHSFixedNumIter.h" +#include "CollocationHSIncrLimit.h" +#include "CollocationHSIncrReduct.h" +#include "HHT.h" +#include "HHT_TP.h" +#include "HHTExplicit.h" +#include "HHTExplicit_TP.h" +#include "HHTGeneralized.h" +#include "HHTGeneralized_TP.h" +#include "HHTGeneralizedExplicit.h" +#include "HHTGeneralizedExplicit_TP.h" +#include "HHTHSFixedNumIter.h" +#include "HHTHSFixedNumIter_TP.h" +#include "HHTHSIncrLimit.h" +#include "HHTHSIncrLimit_TP.h" +#include "HHTHSIncrReduct.h" +#include "HHTHSIncrReduct_TP.h" +#include "KRAlphaExplicit.h" +#include "KRAlphaExplicit_TP.h" +#include "Newmark.h" +#include "StagedNewmark.h" +#include "NewmarkExplicit.h" +#include "NewmarkHSFixedNumIter.h" +#include "NewmarkHSIncrLimit.h" +#include "NewmarkHSIncrReduct.h" +#include "PFEMIntegrator.h" +#include "TRBDF2.h" +#include "TRBDF3.h" +#include "WilsonTheta.h" // system of eqn header files -#include -#include -#include -#include -#include -#include -#include - -#include - -#include +#include "LinearSOE.h" +#include "DomainSolver.h" +#include "fullGEN/FullGenLinSOE.h" +#include "bandGEN/BandGenLinSOE.h" +#include "bandSPD/BandSPDLinSOE.h" +#include "profileSPD/ProfileSPDLinSOE.h" +#include "profileSPD/ProfileSPDLinSubstrSolver.h" +#include "sparseGEN/SparseGenColLinSOE.h" +#include "DomainDecompositionAnalysis.h" // load patterns -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include +#include "LoadPattern.h" +#include "UniformExcitation.h" +#include "MultiSupportPattern.h" +#include "GroundMotion.h" +#include "InterpolatedGroundMotion.h" +#include "drm/DRMLoadPatternWrapper.h" + +#ifdef _H5DRM +#include "drm/H5DRM.h" +#endif + +#include "Parameter.h" +#include "ElementParameter.h" +#include "MaterialStageParameter.h" +#include "MatParameter.h" +#include "InitialStateParameter.h" +#include "ElementStateParameter.h" // time series -#include -#include -#include -#include -#include -#include +#include "LinearSeries.h" +#include "PathSeries.h" +#include "PathTimeSeries.h" +#include "RectangularSeries.h" +#include "ConstantSeries.h" +#include "TrigSeries.h" +#include "TriangleSeries.h" // time series integrators -#include +#include "TrapezoidalTimeSeriesIntegrator.h" -#include +#include "eigenSOE/ArpackSOE.h" #ifdef _PETSC -#include -#include +#include "PetscSOE.h" +#include "PetscSolver.h" +#include "SparseGenColLinSOE.h" #endif #ifdef _MUMPS -#include +#include "MumpsSOE.h" #ifdef _PARALLEL_PROCESSING -#include +#include "MumpsParallelSOE.h" #endif #endif #ifdef _PARALLEL_PROCESSING -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "DistributedBandSPDLinSOE.h" +#include "DistributedProfileSPDLinSOE.h" +#include "DistributedSparseGenColLinSOE.h" +#include "DistributedSparseGenRowLinSOE.h" +#include "DistributedBandGenLinSOE.h" +#include "DistributedSuperLU.h" +#include "ParallelNumberer.h" +#include "StaticDomainDecompositionAnalysis.h" +#include "TransientDomainDecompositionAnalysis.h" +#include "DistributedDiagonalSOE.h" #endif -#include +//#include "TclFeViewer.h" -#include +#include "packages.h" typedef struct uniaxialPackage { int classTag; @@ -703,6 +712,12 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_NineNodeMixedQuad: return new NineNodeMixedQuad(); + case ELE_TAG_NineNodeQuad: + return new NineNodeQuad(); + + case ELE_TAG_EightNodeQuad: + return new EightNodeQuad(); + case ELE_TAG_ConstantPressureVolumeQuad: return new ConstantPressureVolumeQuad(); @@ -753,7 +768,10 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_ShellNLDKGQ: //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu return new ShellNLDKGQ(); //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu - + + case ELE_TAG_ASDShellQ4: // Massimo Petracca + return new ASDShellQ4(); // Massimo Petracca + case ELE_TAG_BbarBrick: return new BbarBrick(); @@ -961,6 +979,9 @@ FEM_ObjectBrokerAllClasses::getNewElementalLoad(int classTag) case LOAD_TAG_SelfWeight: return new SelfWeight(); + case LOAD_TAG_SurfaceLoader: + return new SurfaceLoader(); + default: opserr << "FEM_ObjectBrokerAllClasses::getNewNodalLoad - "; opserr << " - no NodalLoad type exists for class tag "; @@ -1087,6 +1108,9 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_ParallelMaterial: return new ParallelMaterial(); + case MAT_TAG_ASD_SMA_3K: + return new ASD_SMA_3K(); + case MAT_TAG_Concrete01: return new Concrete01(); @@ -1114,6 +1138,9 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_Steel2: return new Steel2(); + case MAT_TAG_Steel4: + return new Steel4(); + case MAT_TAG_OriginCentered: return new OriginCentered(); @@ -1577,6 +1604,10 @@ FEM_ObjectBrokerAllClasses::getNewLoadPattern(int classTag) case PATTERN_TAG_DRMLoadPattern: return new DRMLoadPatternWrapper(); +#ifdef _H5DRM + case PATTERN_TAG_H5DRM: + return new H5DRM(); +#endif default: opserr << "FEM_ObjectBrokerAllClasses::getPtrLoadPattern - "; opserr << " - no Load type exists for class tag "; @@ -1626,6 +1657,9 @@ FEM_ObjectBrokerAllClasses::getNewTimeSeries(int classTag) case TSERIES_TAG_ConstantSeries: return new ConstantSeries; + case TSERIES_TAG_TriangleSeries: + return new TriangleSeries; + case TSERIES_TAG_TrigSeries: return new TrigSeries; @@ -1777,10 +1811,12 @@ FEM_ObjectBrokerAllClasses::getPtrNewRecorder(int classTag) case RECORDER_TAGS_TclFeViewer: return 0; - // return new TclFeViewer(); - case RECORDER_TAGS_MPCORecorder: - return new MPCORecorder(); + case RECORDER_TAGS_GmshRecorder: + return new GmshRecorder(); + + case RECORDER_TAGS_MPCORecorder: + return new MPCORecorder(); default: opserr << "FEM_ObjectBrokerAllClasses::getNewRecordr - "; @@ -1972,6 +2008,9 @@ FEM_ObjectBrokerAllClasses::getNewStaticIntegrator(int classTag) case INTEGRATOR_TAGS_LoadControl: return new LoadControl(1.0,1,1.0,.10); // must recvSelf + case INTEGRATOR_TAGS_StagedLoadControl: + return new StagedLoadControl(1.0, 1, 1.0, .10); // must recvSelf + #ifdef _PARALLEL_PROCESSING case INTEGRATOR_TAGS_DistributedDisplacementControl: return new DistributedDisplacementControl(); // must recvSelf @@ -2079,6 +2118,9 @@ FEM_ObjectBrokerAllClasses::getNewTransientIntegrator(int classTag) case INTEGRATOR_TAGS_Newmark: return new Newmark(); + case INTEGRATOR_TAGS_StagedNewmark: + return new StagedNewmark(); + case INTEGRATOR_TAGS_NewmarkExplicit: return new NewmarkExplicit(); @@ -2170,17 +2212,19 @@ FEM_ObjectBrokerAllClasses::getNewLinearSOE(int classTagSOE) theSOE = new SparseGenColLinSOE(); return theSOE; -#ifdef _PETSC - case LinSOE_TAGS_PetscSOE: - theSOE = new PetscSOE(); - return theSOE; -#endif #ifdef _PARALLEL_PROCESSING #ifdef _MUMPS case LinSOE_TAGS_MumpsParallelSOE: theSOE = new MumpsParallelSOE(); + return theSOE; +#endif + +#ifdef _PETSC + case LinSOE_TAGS_PetscSOE: + thePetscSolver = new PetscSolver(); + theSOE = new PetscSOE(*thePetscSolver); return theSOE; #endif diff --git a/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp b/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp new file mode 100644 index 0000000000..01cd27c6e7 --- /dev/null +++ b/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp @@ -0,0 +1,163 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.0 $ +// $Date: 2019-01-28 17:53:01 $ +// $Source: /usr/local/cvs/OpenSees/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp,v $ + +// Written: Yuli Huang (yulee@berkeley.edu) +// Created: 02/2020 +// Revision: A +// +// Description: This file contains the implementation for the ExpressNewton class. +// ExpressNewton is a class which performs a ExpressNewton solution algorithm +// to solve the equations. +// +// Reference: +// Junjie Xu, Yuli Huang, Zhe Qu, +// An efficient and unconditionally stable numerical algorithm for nonlinear structural dynamics +// International Journal for Numerical Methods in Engineering, +// https://doi.org/10.1002/nme.6456. +// (https://onlinelibrary.wiley.com/doi/abs/10.1002/nme.6456) + +// What: "@(#)ExpressNewton.h, revA" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// Constructor +ExpressNewton::ExpressNewton(int ni, double km, int tg, int fo) + :EquiSolnAlgo(EquiALGORITHM_TAGS_ExpressNewton), nIter(ni), factorOnce(fo) +{ + if (tg == INITIAL_TANGENT) { + kMultiplier1 = km; + kMultiplier2 = 0.0; + } + else { + kMultiplier1 = 0.0; + kMultiplier2 = km; + } +} + +// Destructor +ExpressNewton::~ExpressNewton() +{ + +} + +int +ExpressNewton::solveCurrentStep(void) +{ + // set up some pointers and check they are valid + // NOTE this could be taken away if we set Ptrs as protecetd in superclass + + AnalysisModel *theAnalysisModel = this->getAnalysisModelPtr(); + LinearSOE *theSOE = this->getLinearSOEptr(); + IncrementalIntegrator *theIntegrator = this->getIncrementalIntegratorPtr(); + + if ((theAnalysisModel == 0) || (theIntegrator ==0 ) || (theSOE == 0)){ + opserr << "WARNING ExpressNewton::solveCurrentStep() -"; + opserr << "setLinks() has not been called.\n"; + return -5; + } + + if (factorOnce != 2) { + if (theIntegrator->formTangent(HALL_TANGENT, kMultiplier1, kMultiplier2) < 0) { + opserr << "WARNING ExpressNewton::solveCurrentStep() -"; + opserr << "the Integrator failed in formTangent()\n"; + return -1; + } + if (factorOnce == 1) + factorOnce = 2; + } + + for (int iter = 0; iter formUnbalance() < 0) { + opserr << "WARNING ExpressNewton::solveCurrentStep() -"; + opserr << "the Integrator failed in formUnbalance()\n"; + return -2; + } + + if (theSOE->solve() < 0) { + opserr << "WARNING ExpressNewton::solveCurrentStep() -"; + opserr << "the LinearSOE failed in solve()\n"; + return -3; + } + + if (theIntegrator->update(theSOE->getX()) < 0) { + opserr << "WARNING ExpressNewton::solveCurrentStep() -"; + opserr << "the Integrator failed in update()\n"; + return -4; + } + } + + return 0; +} + +int +ExpressNewton::setConvergenceTest(ConvergenceTest *theNewTest) +{ + return 0; +} + +int +ExpressNewton::sendSelf(int cTag, Channel &theChannel) +{ + static Vector data(4); + data(0) = nIter; + data(1) = kMultiplier1; + data(1) = kMultiplier2; + data(2) = factorOnce; + return theChannel.sendVector(this->getDbTag(), cTag, data); + + +} + +int +ExpressNewton::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +{ + static Vector data(4); + theChannel.recvVector(this->getDbTag(), cTag, data); + nIter = int(data(0)); + kMultiplier1 = data(1); + kMultiplier2 = data(2); + factorOnce = int(data(3)); + return 0; +} + + +void +ExpressNewton::Print(OPS_Stream &s, int flag) +{ + s << "\t ExpressNewton algorithm"; +} diff --git a/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.h b/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.h new file mode 100644 index 0000000000..413f8a2930 --- /dev/null +++ b/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.h @@ -0,0 +1,72 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.0 $ +// $Date: 2019-01-28 17:53:01 $ +// $Source: /usr/local/cvs/OpenSees/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.h,v $ + +// Written: Yuli Huang (yulee@berkeley.edu) +// Created: 02/2020 +// Revision: A +// +// Description: This file contains the definition for the ExpressNewton class. +// ExpressNewton is a class which performs a ExpressNewton solution algorithm +// to solve the equations. +// +// Reference: +// Junjie Xu, Yuli Huang, Zhe Qu, +// An efficient and unconditionally stable numerical algorithm for nonlinear structural dynamics +// International Journal for Numerical Methods in Engineering, +// https://doi.org/10.1002/nme.6456. +// (https://onlinelibrary.wiley.com/doi/abs/10.1002/nme.6456) + +// What: "@(#)ExpressNewton.h, revA" + +#ifndef ExpressNewton_h +#define ExpressNewton_h + +#include + +class ExpressNewton: public EquiSolnAlgo +{ + public: + ExpressNewton(int nIter, double kMultiplier, int tagent, int factorOnce); + ~ExpressNewton(); + + int solveCurrentStep(void); + int setConvergenceTest(ConvergenceTest *theNewTest); + + virtual int sendSelf(int commitTag, Channel &theChannel); + virtual int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + + void Print(OPS_Stream &s, int flag =0); + + protected: + + private: + int factorOnce; + int nIter; + double kMultiplier1, kMultiplier2; +}; + +#endif + + diff --git a/SRC/analysis/algorithm/equiSolnAlgo/KrylovNewton.cpp b/SRC/analysis/algorithm/equiSolnAlgo/KrylovNewton.cpp index 6fed2326dd..abd7e64f68 100644 --- a/SRC/analysis/algorithm/equiSolnAlgo/KrylovNewton.cpp +++ b/SRC/analysis/algorithm/equiSolnAlgo/KrylovNewton.cpp @@ -313,7 +313,8 @@ KrylovNewton::leastSquares(int k) B = r; // No transpose - char *trans = "N"; + // char *trans = "N"; + char trans[] = "N"; // The number of right hand side vectors int nrhs = 1; diff --git a/SRC/analysis/algorithm/equiSolnAlgo/Linear.cpp b/SRC/analysis/algorithm/equiSolnAlgo/Linear.cpp index c8344a7715..e4df50a79c 100644 --- a/SRC/analysis/algorithm/equiSolnAlgo/Linear.cpp +++ b/SRC/analysis/algorithm/equiSolnAlgo/Linear.cpp @@ -48,7 +48,7 @@ #include #include -#include +//#include #include #include diff --git a/SRC/analysis/algorithm/equiSolnAlgo/Makefile b/SRC/analysis/algorithm/equiSolnAlgo/Makefile index dda99a8977..03082c31ca 100644 --- a/SRC/analysis/algorithm/equiSolnAlgo/Makefile +++ b/SRC/analysis/algorithm/equiSolnAlgo/Makefile @@ -4,7 +4,8 @@ OBJS = EquiSolnAlgo.o Linear.o NewtonRaphson.o \ ModifiedNewton.o NewtonLineSearch.o Broyden.o BFGS.o \ KrylovNewton.o PeriodicNewton.o AcceleratedNewton.o \ LineSearch.o InitialInterpolatedLineSearch.o NewtonHallM.o \ - SecantLineSearch.o RegulaFalsiLineSearch.o BisectionLineSearch.o + SecantLineSearch.o RegulaFalsiLineSearch.o BisectionLineSearch.o \ + ExpressNewton.o # Compilation control diff --git a/SRC/analysis/algorithm/equiSolnAlgo/ModifiedNewton.cpp b/SRC/analysis/algorithm/equiSolnAlgo/ModifiedNewton.cpp index 8be7de3328..986632108e 100644 --- a/SRC/analysis/algorithm/equiSolnAlgo/ModifiedNewton.cpp +++ b/SRC/analysis/algorithm/equiSolnAlgo/ModifiedNewton.cpp @@ -46,7 +46,7 @@ #include #include #include -#include +//#include #include void* OPS_ModifiedNewton() diff --git a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/DifferenceAccelerator.cpp b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/DifferenceAccelerator.cpp index 85e479f4d4..72c4f3fde3 100755 --- a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/DifferenceAccelerator.cpp +++ b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/DifferenceAccelerator.cpp @@ -189,7 +189,7 @@ DifferenceAccelerator::accelerate(Vector &vStar, LinearSOE &theSOE, B = r; // No transpose - char *trans = "N"; + char trans[] = "N"; // The number of right hand side vectors int nrhs = 1; diff --git a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/DifferenceAccelerator2.cpp b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/DifferenceAccelerator2.cpp index 9f6ab51c08..50f91da8a4 100755 --- a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/DifferenceAccelerator2.cpp +++ b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/DifferenceAccelerator2.cpp @@ -188,7 +188,7 @@ DifferenceAccelerator2::accelerate(Vector &vStar, LinearSOE &theSOE, B = R; // No transpose - char *trans = "N"; + char trans[] = "N"; // The number of right hand side vectors int nrhs = 1; diff --git a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator.cpp b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator.cpp index 25e14bd8cc..d5655813db 100755 --- a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator.cpp +++ b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator.cpp @@ -223,7 +223,7 @@ KrylovAccelerator::accelerate(Vector &vStar, LinearSOE &theSOE, B = r; // No transpose - char *trans = "N"; + char trans[] = "N"; // The number of right hand side vectors int nrhs = 1; diff --git a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator.h b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator.h index ac1ddb1326..42fca5c4ec 100644 --- a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator.h +++ b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator.h @@ -31,7 +31,7 @@ #ifndef KrylovAccelerator_h #define KrylovAccelerator_h -#include +#include "Accelerator.h" #include class KrylovAccelerator : public Accelerator diff --git a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator2.cpp b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator2.cpp index afb6720af2..06c04ce55c 100755 --- a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator2.cpp +++ b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/KrylovAccelerator2.cpp @@ -212,7 +212,7 @@ KrylovAccelerator2::accelerate(Vector &vStar, LinearSOE &theSOE, B = R; // No transpose - char *trans = "N"; + char trans[] = "N"; // The number of right hand side vectors int nrhs = 1; diff --git a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/RaphsonAccelerator.h b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/RaphsonAccelerator.h index 4e2e8dc547..f47ab0fc04 100644 --- a/SRC/analysis/algorithm/equiSolnAlgo/accelerator/RaphsonAccelerator.h +++ b/SRC/analysis/algorithm/equiSolnAlgo/accelerator/RaphsonAccelerator.h @@ -31,7 +31,7 @@ #ifndef RaphsonAccelerator_h #define RaphsonAccelerator_h -#include +#include "Accelerator.h" #include class RaphsonAccelerator: public Accelerator diff --git a/SRC/analysis/analysis/EigenAnalysis.cpp b/SRC/analysis/analysis/EigenAnalysis.cpp index 777527d9de..9891b2a812 100644 --- a/SRC/analysis/analysis/EigenAnalysis.cpp +++ b/SRC/analysis/analysis/EigenAnalysis.cpp @@ -45,7 +45,7 @@ #include #include #include -#include +//#include #include #include #include diff --git a/SRC/analysis/analysis/StaticAnalysis.cpp b/SRC/analysis/analysis/StaticAnalysis.cpp index 2d1fd5d6e0..4316a003aa 100644 --- a/SRC/analysis/analysis/StaticAnalysis.cpp +++ b/SRC/analysis/analysis/StaticAnalysis.cpp @@ -46,7 +46,7 @@ #include #include #include -#include +//#include #include //Abbas // Constructor diff --git a/SRC/analysis/analysis/StaticDomainDecompositionAnalysis.cpp b/SRC/analysis/analysis/StaticDomainDecompositionAnalysis.cpp index fb68cae6ce..81bf298121 100644 --- a/SRC/analysis/analysis/StaticDomainDecompositionAnalysis.cpp +++ b/SRC/analysis/analysis/StaticDomainDecompositionAnalysis.cpp @@ -40,7 +40,7 @@ #include #include #include -#include +//#include #include #include diff --git a/SRC/analysis/analysis/TransientDomainDecompositionAnalysis.cpp b/SRC/analysis/analysis/TransientDomainDecompositionAnalysis.cpp index 45ae728ccd..f7ce6ac5eb 100644 --- a/SRC/analysis/analysis/TransientDomainDecompositionAnalysis.cpp +++ b/SRC/analysis/analysis/TransientDomainDecompositionAnalysis.cpp @@ -40,7 +40,7 @@ #include #include #include -#include +//#include #include #include diff --git a/SRC/analysis/fe_ele/FE_Element.cpp b/SRC/analysis/fe_ele/FE_Element.cpp index fc2ec5d6db..94be63b34e 100644 --- a/SRC/analysis/fe_ele/FE_Element.cpp +++ b/SRC/analysis/fe_ele/FE_Element.cpp @@ -351,13 +351,16 @@ FE_Element::zeroTangent(void) void FE_Element::addKtToTang(double fact) { - if (myEle != 0) { + if (myEle != 0 && myEle->isActive()) { // check for a quick return if (fact == 0.0) return; else if (myEle->isSubdomain() == false) - theTangent->addMatrix(1.0, myEle->getTangentStiff(),fact); + { + const Matrix& Kt = myEle->getTangentStiff(); + theTangent->addMatrix(1.0, Kt,fact); + } else { opserr << "WARNING FE_Element::addKToTang() - "; opserr << "- this should not be called on a Subdomain!\n"; @@ -368,7 +371,7 @@ FE_Element::addKtToTang(double fact) void FE_Element::addCtoTang(double fact) { - if (myEle != 0) { + if (myEle != 0 && myEle->isActive()) { // check for a quick return if (fact == 0.0) @@ -385,7 +388,7 @@ FE_Element::addCtoTang(double fact) void FE_Element::addMtoTang(double fact) { - if (myEle != 0) { + if (myEle != 0 && myEle->isActive()) { // check for a quick return if (fact == 0.0) @@ -403,7 +406,7 @@ FE_Element::addMtoTang(double fact) void FE_Element::addKiToTang(double fact) { - if (myEle != 0) { + if (myEle != 0 && myEle->isActive()) { // check for a quick return if (fact == 0.0) return; @@ -419,7 +422,7 @@ FE_Element::addKiToTang(double fact) void FE_Element::addKgToTang(double fact) { - if (myEle != 0) { + if (myEle != 0 && myEle->isActive()) { // check for a quick return if (fact == 0.0) return; @@ -435,7 +438,7 @@ FE_Element::addKgToTang(double fact) void FE_Element::addKpToTang(double fact, int numP) { - if (myEle != 0) { + if (myEle != 0 && myEle->isActive()) { // check for a quick return if (fact == 0.0) return; @@ -484,7 +487,7 @@ FE_Element::addRtoResidual(double fact) { if (myEle != 0) { // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return; else if (myEle->isSubdomain() == false) { const Vector &eleResisting = myEle->getResistingForce(); @@ -507,7 +510,7 @@ FE_Element::addRIncInertiaToResidual(double fact) { if (myEle != 0) { // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return; else if (myEle->isSubdomain() == false) { const Vector &eleResisting = myEle->getResistingForceIncInertia(); @@ -534,7 +537,7 @@ FE_Element::getTangForce(const Vector &disp, double fact) theResidual->Zero(); // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return *theResidual; // get the components we need out of the vector @@ -583,7 +586,7 @@ FE_Element::getK_Force(const Vector &disp, double fact) theResidual->Zero(); // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return *theResidual; // get the components we need out of the vector @@ -621,7 +624,7 @@ FE_Element::getKi_Force(const Vector &disp, double fact) theResidual->Zero(); // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return *theResidual; // get the components we need out of the vector @@ -659,7 +662,7 @@ FE_Element::getM_Force(const Vector &disp, double fact) theResidual->Zero(); // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return *theResidual; // get the components we need out of the vector @@ -697,7 +700,7 @@ FE_Element::getC_Force(const Vector &disp, double fact) theResidual->Zero(); // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return *theResidual; // get the components we need out of the vector @@ -765,7 +768,7 @@ FE_Element::addM_Force(const Vector &accel, double fact) if (myEle != 0) { // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return; if (myEle->isSubdomain() == false) { // get the components we need out of the vector @@ -801,7 +804,7 @@ FE_Element::addD_Force(const Vector &accel, double fact) if (myEle != 0) { // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return; if (myEle->isSubdomain() == false) { // get the components we need out of the vector @@ -837,7 +840,7 @@ FE_Element::addK_Force(const Vector &disp, double fact) if (myEle != 0) { // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return; if (myEle->isSubdomain() == false) { // get the components we need out of the vector @@ -873,7 +876,7 @@ FE_Element::addKg_Force(const Vector &disp, double fact) if (myEle != 0) { // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return; if (myEle->isSubdomain() == false) { // get the components we need out of the vector @@ -910,7 +913,7 @@ FE_Element::addLocalM_Force(const Vector &accel, double fact) if (myEle != 0) { // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return; if (myEle->isSubdomain() == false) { if (theResidual->addMatrixVector(1.0, myEle->getMass(), @@ -937,7 +940,7 @@ FE_Element::addLocalD_Force(const Vector &accel, double fact) if (myEle != 0) { // check for a quick return - if (fact == 0.0) + if (fact == 0.0 || !myEle->isActive()) return; if (myEle->isSubdomain() == false) { if (theResidual->addMatrixVector(1.0, myEle->getDamp(), @@ -1101,7 +1104,7 @@ FE_Element::commitSensitivity(int gradNum, int numGrads) int FE_Element::updateElement(void) { - if (myEle != 0) { + if (myEle != 0 && myEle->isActive()) { return myEle->update(); opserr << "FE_Element::update()"; myEle->Print(opserr, 0); } @@ -1109,3 +1112,30 @@ FE_Element::updateElement(void) return 0; } + + +void FE_Element::activate() +{ + myEle->activate(); +} + + +void FE_Element::deactivate() +{ + myEle->deactivate(); +} + + +bool FE_Element::isActive() +{ + if (myEle->isActive()) + { + // opserr << "Element # " << myEle->getTag() << " is ACTIVE." << endln; + return true; + } + else + { + // opserr << "Element # " << myEle->getTag() << " is INACTIVE." << endln; + return false; + } +} diff --git a/SRC/analysis/fe_ele/FE_Element.h b/SRC/analysis/fe_ele/FE_Element.h index cdb877a726..056d439e41 100644 --- a/SRC/analysis/fe_ele/FE_Element.h +++ b/SRC/analysis/fe_ele/FE_Element.h @@ -102,6 +102,10 @@ class FE_Element: public TaggedObject virtual int commitSensitivity (int gradNum, int numGrads); // AddingSensitivity:END ////////////////////////////////////// + void activate(); + void deactivate(); + bool isActive(); + protected: void addLocalM_Force(const Vector &accel, double fact = 1.0); void addLocalD_Force(const Vector &vel, double fact = 1.0); @@ -121,7 +125,6 @@ class FE_Element: public TaggedObject Vector *theResidual; Matrix *theTangent; Integrator *theIntegrator; // need for Subdomain - // static variables - single copy for all objects of the class static Matrix errMatrix; diff --git a/SRC/analysis/handler/PlainHandler.cpp b/SRC/analysis/handler/PlainHandler.cpp index ed38370e56..3f3ffaf299 100644 --- a/SRC/analysis/handler/PlainHandler.cpp +++ b/SRC/analysis/handler/PlainHandler.cpp @@ -91,7 +91,7 @@ PlainHandler::handle(const ID *nodesLast) opserr << "WARNING PlainHandler::handle() - "; opserr << " non-homogeneos constraint"; opserr << " for node " << theSP->getNodeTag(); - opserr << " homo assumed\n"; + opserr << " homogeneous constraint assumed\n"; } allSPs.insert(std::make_pair(theSP->getNodeTag(),theSP)); } diff --git a/SRC/analysis/integrator/DisplacementControl.cpp b/SRC/analysis/integrator/DisplacementControl.cpp index 70828f5477..8e832980c4 100644 --- a/SRC/analysis/integrator/DisplacementControl.cpp +++ b/SRC/analysis/integrator/DisplacementControl.cpp @@ -86,6 +86,7 @@ void* OPS_DisplacementControlIntegrator() // numIter,dumin,dumax int numIter = 1; + int formTangent = 0; double data[2] = {incr,incr}; if(OPS_GetNumRemainingInputArgs() > 2) { numData = 1; @@ -100,6 +101,13 @@ void* OPS_DisplacementControlIntegrator() } } + if (OPS_GetNumRemainingInputArgs() == 1) { + std::string type = OPS_GetString(); + if(type=="-initial" || type=="-Initial") { + formTangent = 1; + } + } + // check node Domain* theDomain = OPS_GetDomain(); Node *theNode = theDomain->getNode(iData[0]); @@ -114,15 +122,18 @@ void* OPS_DisplacementControlIntegrator() return 0; } - return new DisplacementControl(iData[0],iData[1]-1,incr,theDomain,numIter,data[0],data[1]); + return new DisplacementControl(iData[0],iData[1]-1, + incr,theDomain, + numIter,data[0],data[1], + formTangent); } DisplacementControl::DisplacementControl(int node, int dof, - double increment, - Domain *domain, - int numIncr, - double min, double max) + double increment, + Domain *domain, + int numIncr, + double min, double max, int tang) :StaticIntegrator(INTEGRATOR_TAGS_DisplacementControl), theNode(node), theDof(dof), theIncrement(increment), theDomain(domain), theDofID(-1), @@ -132,6 +143,8 @@ DisplacementControl::DisplacementControl(int node, int dof, minIncrement(min), maxIncrement(max),sensitivityFlag(0),Residual(0),dlambdadh(0.0), dLambda(0.0), sensU(0),d_deltaU_dh(0),Residual2(0),gradNumber(0),dLAMBDAdh(0),dphatdh(0) { + tangFlag = tang; + // to avoid divide-by-zero error on first update() ensure numIncr != 0 if (numIncr == 0) { opserr << "WARNING DisplacementControl::DisplacementControl() -"; @@ -207,7 +220,7 @@ DisplacementControl::newStep(void) currentLambda = theModel->getCurrentDomainTime(); // determine dUhat - this->formTangent(); + this->formTangent(tangFlag); theLinSOE->setB(*phat); if (theLinSOE->solve() < 0) { opserr << "DisplacementControl::newStep(void) - failed in solver\n"; @@ -628,7 +641,7 @@ DisplacementControl::formTangDispSensitivity(Vector *dUhatdh,int gradNumber) //call the tangent (K) - this->formTangent(); + this->formTangent(tangFlag); theLinSOE->setB(*dphatdh); if(theLinSOE->solve()<0) { opserr<<"SOE failed to obtained dUhatdh "; @@ -1046,7 +1059,7 @@ DisplacementControl::computeSensitivities(void) // this->formTangDispSensitivity(dUhatdh,gradIndex); this->formSensitivityRHS(gradIndex); - this->formTangent(); + this->formTangent(tangFlag); theSOE->solve(); *dUIJdh=theSOE->getX();// sensitivity of the residual displacement diff --git a/SRC/analysis/integrator/DisplacementControl.h b/SRC/analysis/integrator/DisplacementControl.h index 28f62118f4..d7c9080246 100644 --- a/SRC/analysis/integrator/DisplacementControl.h +++ b/SRC/analysis/integrator/DisplacementControl.h @@ -55,7 +55,8 @@ class DisplacementControl : public StaticIntegrator { public: DisplacementControl(int node, int dof, double increment, Domain *theDomain, - int numIncrStep, double minIncrement, double maxIncrement ); + int numIncrStep, double minIncrement, double maxIncrement, + int tangFlag = 0); ~DisplacementControl(); @@ -104,7 +105,7 @@ class DisplacementControl : public StaticIntegrator Domain *theDomain; // the domain containing the node being followed int theDofID; // the system level id of the dof being followed Vector *deltaUhat, *deltaUbar, *deltaU,*phat,*deltaUstep,*dphatdh; - // Vector *deltaUhat_newStep ; + // Vector *deltaUhat_newStep ; Vector *dLAMBDAdh; ///////////////////////////////////////Abbas///////////////////////////////////////// // Pointers used for sensitivity analysis @@ -117,18 +118,18 @@ class DisplacementControl : public StaticIntegrator // *Residual : the residual forces that are required to obtain the dLambdadh // *Residual2 : the residual forces required to obtain dUdh - // the reference load vector double deltaLambdaStep, currentLambda; // dLambda(i) & current value of lambda double dLambdaStepDh ;//Abbas double specNumIncrStep, numIncrLastStep; // Jd & J(i-1) double minIncrement, maxIncrement; // min/max values of deltaU at (i) + int tangFlag; + // adding sensitivity int gradNumber; int sensitivityFlag; FE_Element *theEle; - }; #endif diff --git a/SRC/analysis/integrator/IncrementalIntegrator.cpp b/SRC/analysis/integrator/IncrementalIntegrator.cpp index 2f4fbdf5c9..d73fb18142 100644 --- a/SRC/analysis/integrator/IncrementalIntegrator.cpp +++ b/SRC/analysis/integrator/IncrementalIntegrator.cpp @@ -300,9 +300,9 @@ IncrementalIntegrator::setModalDampingFactors(const Vector &factors) } */ -/* slow code + /* int -IncrementalIntegrator::addModalDampingForce(void) +IncrementalIntegrator::addModalDampingForce(const Vector *modalDampingValues) { int res = 0; @@ -344,9 +344,9 @@ IncrementalIntegrator::addModalDampingForce(void) return res; } -*/ + */ - /*int +/*int IncrementalIntegrator::addModalDampingForce(void) { int res = 0; @@ -518,8 +518,8 @@ IncrementalIntegrator::addModalDampingForce(const Vector *modalDampingValues) this->setupModal(modalDampingValues); } - const Vector &vel = this->getVel(); + dampingForces->Zero(); for (int i=0; i 0) { double wn = sqrt(eigenvalue); + double *eigenVectorI = &eigenVectors[numDOF*i]; double beta = 0.0; for (int j=0; j #include #include -#include -#include +#include "fullGEN/FullGenLinSOE.h" +#include "fullGEN/FullGenLinLapackSolver.h" #include #include #include diff --git a/SRC/analysis/integrator/KRAlphaExplicit_TP.cpp b/SRC/analysis/integrator/KRAlphaExplicit_TP.cpp index 97bd14e014..a998c6f0c2 100644 --- a/SRC/analysis/integrator/KRAlphaExplicit_TP.cpp +++ b/SRC/analysis/integrator/KRAlphaExplicit_TP.cpp @@ -22,8 +22,8 @@ #include #include #include -#include -#include +#include "fullGEN/FullGenLinSOE.h" +#include "fullGEN/FullGenLinLapackSolver.h" #include #include #include diff --git a/SRC/analysis/integrator/LoadControl.cpp b/SRC/analysis/integrator/LoadControl.cpp index a21758f1b7..9420f6b006 100644 --- a/SRC/analysis/integrator/LoadControl.cpp +++ b/SRC/analysis/integrator/LoadControl.cpp @@ -86,8 +86,8 @@ void* OPS_LoadControlIntegrator() return new LoadControl(lambda,numIter,mLambda[0],mLambda[1]); } -LoadControl::LoadControl(double dLambda, int numIncr, double min, double max) -:StaticIntegrator(INTEGRATOR_TAGS_LoadControl), +LoadControl::LoadControl(double dLambda, int numIncr, double min, double max, int classtag) + : StaticIntegrator(classtag), deltaLambda(dLambda), specNumIncrStep(numIncr), numIncrLastStep(numIncr), dLambdaMin(min), dLambdaMax(max), gradNumber(0), sensitivityFlag(0) diff --git a/SRC/analysis/integrator/LoadControl.h b/SRC/analysis/integrator/LoadControl.h index 6b304af811..42ed14ce64 100644 --- a/SRC/analysis/integrator/LoadControl.h +++ b/SRC/analysis/integrator/LoadControl.h @@ -39,6 +39,7 @@ // What: "@(#) LoadControl.h, revA" #include +#include class LinearSOE; class AnalysisModel; @@ -51,7 +52,7 @@ class LoadControl : public StaticIntegrator { public: LoadControl(double deltaLambda, int numIncr, - double minLambda, double maxlambda); + double minLambda, double maxlambda, int classtag=INTEGRATOR_TAGS_LoadControl); ~LoadControl(); diff --git a/SRC/analysis/integrator/Makefile b/SRC/analysis/integrator/Makefile index 0d25ad7234..38eaf096cb 100644 --- a/SRC/analysis/integrator/Makefile +++ b/SRC/analysis/integrator/Makefile @@ -43,6 +43,8 @@ OBJS = AlphaOS.o \ KRAlphaExplicit.o \ KRAlphaExplicit_TP.o \ LoadControl.o \ + StagedLoadControl.o \ + StagedNewmark.o \ LoadPath.o \ MinUnbalDispNorm.o \ Newmark.o \ diff --git a/SRC/analysis/integrator/Newmark.cpp b/SRC/analysis/integrator/Newmark.cpp index 2607094a56..873188b895 100644 --- a/SRC/analysis/integrator/Newmark.cpp +++ b/SRC/analysis/integrator/Newmark.cpp @@ -50,7 +50,7 @@ #include #include #include -#include//Abbas +//#include//Abbas #include #include//Abbas static bool converged = false; @@ -102,9 +102,9 @@ OPS_Newmark(void) } -Newmark::Newmark() - : TransientIntegrator(INTEGRATOR_TAGS_Newmark), - displ(1), gamma(0), beta(0), +Newmark::Newmark(int classTag) + : TransientIntegrator(classTag), + displ(true), gamma(0), beta(0), c1(0.0), c2(0.0), c3(0.0), Ut(0), Utdot(0), Utdotdot(0), U(0), Udot(0), Udotdot(0), determiningMass(false), @@ -116,8 +116,8 @@ Newmark::Newmark() } -Newmark::Newmark(double _gamma, double _beta, int dispFlag, bool aflag) - : TransientIntegrator(INTEGRATOR_TAGS_Newmark), +Newmark::Newmark(double _gamma, double _beta, bool dispFlag, bool aflag, int classTag_) + : TransientIntegrator(classTag_), displ(dispFlag), gamma(_gamma), beta(_beta), c1(0.0), c2(0.0), c3(0.0), Ut(0), Utdot(0), Utdotdot(0), U(0), Udot(0), Udotdot(0), @@ -479,7 +479,7 @@ int Newmark::update(const Vector &deltaU) (*Udotdot) += deltaU; } - + // update the response at the DOFs theModel->setResponse(*U,*Udot,*Udotdot); if (theModel->updateDomain() < 0) { diff --git a/SRC/analysis/integrator/Newmark.h b/SRC/analysis/integrator/Newmark.h index 5e898d51c1..c5766ecdd7 100644 --- a/SRC/analysis/integrator/Newmark.h +++ b/SRC/analysis/integrator/Newmark.h @@ -47,8 +47,8 @@ class Newmark : public TransientIntegrator { public: // constructors - Newmark(); - Newmark(double gamma, double beta, int disp = 1, bool aflag=false); + Newmark(int classTag=INTEGRATOR_TAGS_Newmark); + Newmark(double gamma, double beta, bool disp = true, bool aflag=false, int classTag=INTEGRATOR_TAGS_Newmark); // destructor ~Newmark(); diff --git a/SRC/analysis/integrator/PFEMIntegrator.cpp b/SRC/analysis/integrator/PFEMIntegrator.cpp index 21e6e5c079..cac69ebf98 100644 --- a/SRC/analysis/integrator/PFEMIntegrator.cpp +++ b/SRC/analysis/integrator/PFEMIntegrator.cpp @@ -52,7 +52,7 @@ #include #include #include -#include +#include "sparseGEN/PFEMLinSOE.h" void * OPS_PFEMIntegrator(void) diff --git a/SRC/analysis/integrator/StagedLoadControl.cpp b/SRC/analysis/integrator/StagedLoadControl.cpp new file mode 100644 index 0000000000..e888b03d34 --- /dev/null +++ b/SRC/analysis/integrator/StagedLoadControl.cpp @@ -0,0 +1,214 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.6 $ +// $Date: 2007-04-02 23:42:26 $ +// $Source: /usr/local/cvs/OpenSees/SRC/analysis/integrator/StagedLoadControl.cpp,v $ + + +// +// Written: fmk +// Created: 07/98 +// Revision: A +// +// Description: This file contains the class definition for StagedLoadControl. +// StagedLoadControl is an algorithmic class for performing a static analysis +// using a load control integration scheme. +// +// What: "@(#) StagedLoadControl.h, revA" + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _PARALLEL_PROCESSING +#include +#endif + +// static double doubleone = 1.0; +// static Matrix one(&doubleone,1,1); +// static ID dofid(1); + +#define SEQUENTIAL_SECTION_BEGIN for (int proc = 0; proc < nproc; ++proc){ if (rank == proc) { +#define SEQUENTIAL_SECTION_END } MPI_Barrier(MPI_COMM_WORLD);} + + +void* OPS_StagedLoadControlIntegrator() +{ + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "insufficient arguments\n"; + return 0; + } + + double lambda; + int numData = 1; + if (OPS_GetDoubleInput(&numData, &lambda) < 0) { + opserr << "WARNING failed to read double lambda\n"; + return 0; + } + + int numIter = 1; + double mLambda[2] = {lambda, lambda}; + if (OPS_GetNumRemainingInputArgs() > 2) { + if (OPS_GetIntInput(&numData, &numIter) < 0) { + opserr << "WARNING failed to read int numIter\n"; + return 0; + } + numData = 2; + if (OPS_GetDoubleInput(&numData, &mLambda[0]) < 0) { + opserr << "WARNING failed to read double min and max\n"; + return 0; + } + } + + return new StagedLoadControl(lambda, numIter, mLambda[0], mLambda[1]); +} + + +StagedLoadControl::StagedLoadControl() + : LoadControl(0, 0, 0, 0, INTEGRATOR_TAGS_StagedLoadControl) +{ +} + + + +StagedLoadControl::StagedLoadControl(double dLambda, int numIncr, double min, double max) + : LoadControl(dLambda, numIncr, min, max, INTEGRATOR_TAGS_StagedLoadControl) +{ +} + + +int StagedLoadControl::formTangent(int statFlag) +{ + int rank = 0; + int nproc = 1; + + #ifdef _PARALLEL_PROCESSING + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + #endif + + // Run a typocal LoadControl formTangent call + int errflag = this->IncrementalIntegrator::formTangent(statFlag); + + if (errflag < 0) + { + return errflag; + } + + // Now detect inactive nodes and add 1 to the tangent diagonal there + + AnalysisModel *theAnalysisModel = this->getAnalysisModel(); + Domain *theDomain = theAnalysisModel->getDomainPtr(); + LinearSOE *theSOE = this->getLinearSOE(); + int numEqn = theSOE->getNumEqn(); + + int * nodedofs = new int[numEqn + 1]; + #ifdef _PARALLEL_PROCESSING + int * allnodedofs = new int[numEqn + 1]; + #endif + + for (int i = 0; i < numEqn; ++i) + { + nodedofs[i] = 0; + #ifdef _PARALLEL_PROCESSING + allnodedofs[i] = 0; + #endif + } + + FE_Element *elePtr = 0; + + FE_EleIter &theEles = theAnalysisModel->getFEs(); + + while ((elePtr = theEles()) != 0) { + const ID& elenodedofs = elePtr->getID(); + + for (int i = 0; i < elenodedofs.Size(); ++i) + { + int dof = elenodedofs(i); + if (dof > numEqn) + { + std::cout << "i = " << i << std::endl; + std::cout << "numEqn = " << numEqn << std::endl; + std::cout << "elenodedofs(i) = " << dof << std::endl; + exit(-1); + } + // std::cout << "i = " << i << " numEqn = " << numEqn << " dof = " << dof << std::endl; + if (dof >= 0 && elePtr->isActive()) + { + + nodedofs[dof] = (int) 1; + } + + } + } + + + #ifdef _PARALLEL_PROCESSING + MPI_Allreduce(nodedofs, allnodedofs, numEqn, MPI_INT, MPI_MAX, MPI_COMM_WORLD); + #endif + + + for (int i = 0; i < numEqn; ++i) + { + #ifdef _PARALLEL_PROCESSING + bool is_lonely_dof = allnodedofs[i] == 0; + #else + bool is_lonely_dof = nodedofs[i] == 0; + #endif + + if (is_lonely_dof) + { + // opserr << "i = " << i << " nodedofs(i) = " << nodedofs[i] << endln; + double uno = 1.0; + static ID dofid(1); + static Matrix one(1, 1); + one(0, 0) = uno; + dofid(0) = i; + theSOE->addA(one, dofid); + } + } + + delete [] nodedofs; + + #ifdef _PARALLEL_PROCESSING + delete [] allnodedofs; + #endif + + return errflag; +} diff --git a/SRC/analysis/integrator/StagedLoadControl.h b/SRC/analysis/integrator/StagedLoadControl.h new file mode 100644 index 0000000000..14116db119 --- /dev/null +++ b/SRC/analysis/integrator/StagedLoadControl.h @@ -0,0 +1,66 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.2 $ +// $Date: 2003-02-14 23:00:48 $ +// $Source: /usr/local/cvs/OpenSees/SRC/analysis/integrator/StagedLoadControl.h,v $ + + +#ifndef StagedLoadControl_h +#define StagedLoadControl_h + +// File: ~/analysis/integrator/StagedLoadControl.h +// +// Written: fmk +// Created: 07/98 +// Revision: A +// +// Description: This file contains the class definition for StagedLoadControl. +// StagedLoadControl is an algorithmic class for performing a static analysis +// using a load control integration scheme. +// +// What: "@(#) StagedLoadControl.h, revA" + +#include +#include + +class LinearSOE; +class AnalysisModel; +class FE_Element; +class Vector; +class EquiSolnAlgo; +class ReliabilityDomain; + +class StagedLoadControl : public LoadControl +{ +public: + StagedLoadControl(); + + StagedLoadControl(double deltaLambda, int numIncr, + double minLambda, double maxlambda); + + + int formTangent(int statusFlag = CURRENT_TANGENT); + + +}; + +#endif + diff --git a/SRC/analysis/integrator/StagedNewmark.cpp b/SRC/analysis/integrator/StagedNewmark.cpp new file mode 100644 index 0000000000..40c3367911 --- /dev/null +++ b/SRC/analysis/integrator/StagedNewmark.cpp @@ -0,0 +1,215 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +static bool converged = false; +static int count = 0; + + +#ifdef _PARALLEL_PROCESSING +#include +#endif + + + + +void * +OPS_StagedNewmark(void) +{ + // Pointer to a uniaxial material that will be returned + TransientIntegrator *theIntegrator = 0; + + int argc = OPS_GetNumRemainingInputArgs(); + if (argc != 2 && argc != 4) { + opserr << "WARNING - incorrect number of args want StagedNewmark $gamma $beta <-form $typeUnknown>\n"; + return 0; + } + + bool dispFlag = true; + double dData[2]; + int numData = 2; + if (OPS_GetDouble(&numData, dData) != 0) { + opserr << "WARNING - invalid args want StagedNewmark $gamma $beta <-form $typeUnknown>\n"; + return 0; + } + + if (argc == 2) + theIntegrator = new StagedNewmark(dData[0], dData[1]); + else { + // char nextString[10]; + const char *nextString = OPS_GetString(); + // OPS_GetString(nextString, 10); + if (strcmp(nextString,"-form") == 0) { + // OPS_GetString(nextString, 10); + nextString = OPS_GetString(); + if ((nextString[0] == 'D') || (nextString[0] == 'd')) + dispFlag = true; + else if ((nextString[0] == 'A') || (nextString[0] == 'a')) + dispFlag = false; + } + theIntegrator = new StagedNewmark(dData[0], dData[1], dispFlag); + } + + if (theIntegrator == 0) + opserr << "WARNING - out of memory creating StagedNewmark integrator\n"; + + return theIntegrator; +} + + + +StagedNewmark::StagedNewmark() + : Newmark( 0, 0, 0, 0, INTEGRATOR_TAGS_StagedNewmark) +{ + +} + + + +StagedNewmark::StagedNewmark(double _gamma, double _beta, bool dispFlag, bool aflag) + : Newmark( _gamma, _beta, dispFlag, aflag, INTEGRATOR_TAGS_StagedNewmark) +{ + +} + + + + +int StagedNewmark::formTangent(int statFlag) +{ + int rank = 0; + int nproc = 1; + + #ifdef _PARALLEL_PROCESSING + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + #endif + + // Run a typocal LoadControl formTangent call + int errflag = this->IncrementalIntegrator::formTangent(statFlag); + + if (errflag < 0) + { + return errflag; + } + + // Now detect inactive nodes and add 1 to the tangent diagonal there + + AnalysisModel *theAnalysisModel = this->getAnalysisModel(); + Domain *theDomain = theAnalysisModel->getDomainPtr(); + LinearSOE *theSOE = this->getLinearSOE(); + int numEqn = theSOE->getNumEqn(); + + int * nodedofs = new int[numEqn + 1]; + #ifdef _PARALLEL_PROCESSING + int * allnodedofs = new int[numEqn + 1]; + #endif + + for (int i = 0; i < numEqn; ++i) + { + nodedofs[i] = 0; + #ifdef _PARALLEL_PROCESSING + allnodedofs[i] = 0; + #endif + } + + FE_Element *elePtr = 0; + + FE_EleIter &theEles = theAnalysisModel->getFEs(); + + while ((elePtr = theEles()) != 0) { + const ID& elenodedofs = elePtr->getID(); + + for (int i = 0; i < elenodedofs.Size(); ++i) + { + int dof = elenodedofs(i); + if (dof > numEqn) + { + std::cout << "i = " << i << std::endl; + std::cout << "numEqn = " << numEqn << std::endl; + std::cout << "elenodedofs(i) = " << dof << std::endl; + exit(-1); + } + // std::cout << "i = " << i << " numEqn = " << numEqn << " dof = " << dof << std::endl; + if (dof >= 0 && elePtr->isActive()) + { + + nodedofs[dof] = (int) 1; + } + + } + } + + + #ifdef _PARALLEL_PROCESSING + MPI_Allreduce(nodedofs, allnodedofs, numEqn, MPI_INT, MPI_MAX, MPI_COMM_WORLD); + #endif + + + for (int i = 0; i < numEqn; ++i) + { + #ifdef _PARALLEL_PROCESSING + bool is_lonely_dof = allnodedofs[i] == 0; + #else + bool is_lonely_dof = nodedofs[i] == 0; + #endif + + if (is_lonely_dof) + { + // opserr << "i = " << i << " nodedofs(i) = " << nodedofs[i] << endln; + double uno = 1.0; + static ID dofid(1); + static Matrix one(1, 1); + one(0, 0) = uno; + dofid(0) = i; + theSOE->addA(one, dofid); + } + } + + delete [] nodedofs; + + #ifdef _PARALLEL_PROCESSING + delete [] allnodedofs; + #endif + + return errflag; +} diff --git a/SRC/analysis/integrator/StagedNewmark.h b/SRC/analysis/integrator/StagedNewmark.h new file mode 100644 index 0000000000..f5c9106082 --- /dev/null +++ b/SRC/analysis/integrator/StagedNewmark.h @@ -0,0 +1,42 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + + +#ifndef StagedNewmark_h +#define StagedNewmark_h + + +#include + + +class StagedNewmark : public Newmark +{ +public: + + StagedNewmark(); + StagedNewmark(double gamma, double beta, bool disp = true, bool aflag=false); + + int formTangent(int statusFlag = CURRENT_TANGENT); + + +private: +}; + +#endif diff --git a/SRC/analysis/integrator/TransientIntegrator.cpp b/SRC/analysis/integrator/TransientIntegrator.cpp index a119038c03..b87c2a7a3b 100644 --- a/SRC/analysis/integrator/TransientIntegrator.cpp +++ b/SRC/analysis/integrator/TransientIntegrator.cpp @@ -136,13 +136,13 @@ TransientIntegrator::formUnbalance(void) { if (modalValues != 0) { this->addModalDampingForce(modalValues); } - + if (this->formElementResidual() < 0) { opserr << "WARNING IncrementalIntegrator::formUnbalance "; opserr << " - this->formElementResidual failed\n"; return -1; } - + if (this->formNodalUnbalance() < 0) { opserr << "WARNING IncrementalIntegrator::formUnbalance "; opserr << " - this->formNodalUnbalance failed\n"; diff --git a/SRC/api/elementAPI.h b/SRC/api/elementAPI.h index ee7e603309..2fdc4c6274 100644 --- a/SRC/api/elementAPI.h +++ b/SRC/api/elementAPI.h @@ -18,12 +18,12 @@ ** ** ** ****************************************************************** */ -/* +/* ** $Revision: 1.9 $ ** $Date: 2010-03-05 22:32:36 $ ** $Source: /usr/local/cvs/OpenSees/SRC/api/elementAPI.h,v $ - -** Written: fmk + +** Written: fmk */ #ifndef _eleAPI @@ -49,61 +49,58 @@ #define OPS_SECTION_TYPE 7 struct modState { - double time; - double dt; + double time; + double dt; }; typedef struct modState modelState; -typedef void (*matFunct)(struct matObject *, modelState *,double *strain, double *tang, double *stress, int *isw, int *error); +typedef void (*matFunct)(struct matObject*, modelState*, double* strain, double* tang, double* stress, int* isw, int* error); struct matObject { - int tag; - int matType; - int nParam; - int nState; - double *theParam; - double *cState; - double *tState; - matFunct matFunctPtr; - void *matObjectPtr; + int tag; + int matType; + int nParam; + int nState; + double* theParam; + double* cState; + double* tState; + matFunct matFunctPtr; + void* matObjectPtr; }; typedef struct matObject matObj; -//start **MRL -typedef void (*limCrvFunct)(struct limCrvObject *, modelState *,double *strain, double *tang, double *stress, int *isw, int *error); +typedef void (*limCrvFunct)(struct limCrvObject*, modelState*, double* strain, double* tang, double* stress, int* isw, int* error); struct limCrvObject { - int tag; - int nParam; - int nState; - double *theParam; - double *cState; - double *tState; - limCrvFunct limCrvFunctPtr; - void *limCrvObjectPtr; + int tag; + int nParam; + int nState; + double* theParam; + double* cState; + double* tState; + limCrvFunct limCrvFunctPtr; + void* limCrvObjectPtr; }; typedef struct limCrvObject limCrvObj; -//end **MRL - -typedef void (*eleFunct)(struct eleObject *, modelState *, double *tang, double *resid, int *isw, int *error); +typedef void (*eleFunct)(struct eleObject*, modelState*, double* tang, double* resid, int* isw, int* error); struct eleObject { - int tag; - int nNode; - int nDOF; - int nParam; - int nState; - int nMat; - int *node; - double *param; - double *cState; - double *tState; - matObj **mats; - eleFunct eleFunctPtr; + int tag; + int nNode; + int nDOF; + int nParam; + int nState; + int nMat; + int* node; + double* param; + double* cState; + double* tState; + matObj** mats; + eleFunct eleFunctPtr; }; typedef struct eleObject eleObj; @@ -114,7 +111,7 @@ class ConstraintHandler; class DOF_Numberer; class LinearSOE; class EigenSOE; -class StaticAnalysis ; +class StaticAnalysis; class DirectIntegrationAnalysis; class VariableTimeStepDirectIntegrationAnalysis; class StaticIntegrator; @@ -149,8 +146,8 @@ class ConvergenceTest; #define OPS_GetNDF ops_getndf_ #define OPS_GetFEDatastore ops_getfedatastore_ #define OPS_GetInterpPWD ops_getinterppwd_ -#define OPS_AllocateLimitCurve ops_allocatelimitcurve_//**MRL -#define OPS_GetLimitCurveType ops_getlimitcurvetype_//**MRL +#define OPS_AllocateLimitCurve ops_allocatelimitcurve_ +#define OPS_GetLimitCurveType ops_getlimitcurvetype_ #define OPS_GetAnalysisModel ops_getanalysismodel_ #define OPS_GetAlgorithm ops_getalgorithm_ @@ -168,78 +165,81 @@ class ConvergenceTest; #define OPS_builtModel ops_builtmodel_ #define OPS_GetDomain ops_getdomain_ - +#include +#include +//#include "TclModelBuilder.h" #ifdef __cplusplus -extern "C" int OPS_GetNDM(); -extern "C" int OPS_GetNDF(); -extern "C" int OPS_Error(char *, int length); -extern "C" int OPS_GetNumRemainingInputArgs(); -extern "C" int OPS_ResetCurrentInputArg(int cArg); -extern "C" int OPS_GetIntInput(int *numData, int*data); -extern "C" int OPS_SetIntOutput(int *numData, int*data, bool scalar); -extern "C" int OPS_GetDoubleInput(int *numData, double *data); -extern "C" int OPS_SetDoubleOutput(int *numData, double *data, bool scalar); -extern "C" const char *OPS_GetString(void); // does a strcpy -extern "C" int OPS_SetString(const char*); -//extern "C" int OPS_GetString(char *cArray, int sizeArray); // does a strcpy -extern "C" int OPS_GetStringCopy(char **cArray); // returns a new copy -extern "C" matObj *OPS_GetMaterial(int *matTag, int *matType); -extern "C" void OPS_GetMaterialPtr(int *, matObj *); -extern "C" eleObj *OPS_GetElement(int *); -extern "C" matObj *OPS_GetMaterialType(char *type, int sizeType); -extern "C" eleObj *OPS_GetElementType(char *, int); -extern "C" int OPS_AllocateElement(eleObj *, int *matTags, int *maType); -extern "C" int OPS_AllocateMaterial(matObj *); -extern "C" limCrvObj *OPS_GetLimitCurveType(char *type, int sizeType);//**MRL -extern "C" int OPS_AllocateLimitCurve(limCrvObj *);//**MRL - -extern "C" int OPS_InvokeMaterial(eleObject *, int *,modelState *, double *, double *, double *, int *); -extern "C" int OPS_InvokeMaterialDirectly(matObject **, modelState *, double *, double *, double *, int *); -extern "C" int OPS_InvokeMaterialDirectly2(matObject *, modelState *, double *, double *, double *, int *); - -extern "C" int OPS_GetNodeCrd(int *nodeTag, int *sizeData, double *data); -extern "C" int OPS_GetNodeDisp(int *nodeTag, int *sizeData, double *data); -extern "C" int OPS_GetNodeVel(int *nodeTag, int *sizeData, double *data); -extern "C" int OPS_GetNodeAccel(int *nodeTag, int *sizeData, double *data); -extern "C" int OPS_GetNodeIncrDisp(int *nodeTag, int *sizeData, double *data); -extern "C" int OPS_GetNodeIncrDeltaDisp(int *nodeTag, int *sizeData, double *data); +extern "C" int OPS_GetNDM(); +extern "C" int OPS_GetNDF(); +extern "C" int OPS_Error(char* errorMessage, int length); +extern "C" int OPS_GetNumRemainingInputArgs(); +extern "C" int OPS_ResetCurrentInputArg(int cArg); +//extern "C" int OPS_ResetInput(ClientData clientData, Tcl_Interp * interp, int cArg, int mArg, TCL_Char * *argv, Domain * domain, TclModelBuilder * builder); +extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp * interp, int cArg, int mArg, TCL_Char * *argv, Domain * domain); +extern "C" int OPS_GetIntInput(int* numData, int* data); +extern "C" int OPS_SetIntOutput(int* numData, int* data, bool scalar); +extern "C" int OPS_GetDoubleInput(int* numData, double* data); +extern "C" int OPS_SetDoubleOutput(int* numData, double* data, bool scalar); +extern "C" const char* OPS_GetString(); // does a strcpy +extern "C" int OPS_SetString(const char* str); +//extern "C" int OPS_GetString(char *cArray, int sizeArray); // does a strcpy +extern "C" int OPS_GetStringCopy(char** cArray); // returns a new copy +extern "C" matObj* OPS_GetMaterial(int* matTag, int* matType); +//extern "C" void OPS_GetMaterialPtr(int *matTag, matObj *theRes); +extern "C" eleObj* OPS_GetElement(int* eleTag); +extern "C" matObj* OPS_GetMaterialType(char* type, int sizeType); +extern "C" eleObj* OPS_GetElementType(char* type, int sizeType); +extern "C" int OPS_AllocateElement(eleObject * theEle, int* matTags, int* matType); +extern "C" int OPS_AllocateMaterial(matObject * theMat); +extern "C" limCrvObj* OPS_GetLimitCurveType(char* type, int sizeType); +extern "C" int OPS_AllocateLimitCurve(limCrvObject * theLimCrv); + +extern "C" int OPS_InvokeMaterial(eleObject*, int*, modelState*, double*, double*, double*, int*); +extern "C" int OPS_InvokeMaterialDirectly(matObject**, modelState*, double*, double*, double*, int*); +extern "C" int OPS_InvokeMaterialDirectly2(matObject*, modelState*, double*, double*, double*, int*); + +extern "C" int OPS_GetNodeCrd(int* nodeTag, int* sizeData, double* data); +extern "C" int OPS_GetNodeDisp(int* nodeTag, int* sizeData, double* data); +extern "C" int OPS_GetNodeVel(int* nodeTag, int* sizeData, double* data); +extern "C" int OPS_GetNodeAccel(int* nodeTag, int* sizeData, double* data); +extern "C" int OPS_GetNodeIncrDisp(int* nodeTag, int* sizeData, double* data); +extern "C" int OPS_GetNodeIncrDeltaDisp(int* nodeTag, int* sizeData, double* data); class UniaxialMaterial; class NDMaterial; class SectionForceDeformation; class CrdTransf; class FrictionModel; -class LimitCurve; //MRL +class LimitCurve; class Domain; class FE_Datastore; -extern UniaxialMaterial *OPS_GetUniaxialMaterial(int matTag); -extern NDMaterial *OPS_GetNDMaterial(int matTag); -extern SectionForceDeformation *OPS_GetSectionForceDeformation(int secTag); -extern CrdTransf *OPS_GetCrdTransf(int crdTag); -extern FrictionModel *OPS_GetFrictionModel(int frnTag); -extern LimitCurve *OPS_GetLimitCurve(int LimCrvTag);//MRL -extern Domain *OPS_GetDomain(void); - - -extern FE_Datastore *OPS_GetFEDatastore(); -extern "C" const char *OPS_GetInterpPWD(); - -extern "C" AnalysisModel **OPS_GetAnalysisModel(void); -extern "C" EquiSolnAlgo **OPS_GetAlgorithm(void); -extern "C" ConstraintHandler **OPS_GetHandler(void); -extern "C" DOF_Numberer **OPS_GetNumberer(void); -extern "C" LinearSOE **OPS_GetSOE(void); -extern "C" EigenSOE **OPS_GetEigenSOE(void); -extern "C" StaticAnalysis **OPS_GetStaticAnalysis(void); -extern "C" DirectIntegrationAnalysis **OPS_GetTransientAnalysis(void); -extern "C" VariableTimeStepDirectIntegrationAnalysis **OPS_GetVariableTimeStepTransientAnalysis(void); -extern "C" int *OPS_GetNumEigen(void); -extern "C" StaticIntegrator **OPS_GetStaticIntegrator(void); -extern "C" TransientIntegrator **OPS_GetTransientIntegrator(void); -extern "C" ConvergenceTest **OPS_GetTest(void); -extern "C" bool *OPS_builtModel(void); +extern UniaxialMaterial* OPS_GetUniaxialMaterial(int matTag); +extern NDMaterial* OPS_GetNDMaterial(int matTag); +extern SectionForceDeformation* OPS_GetSectionForceDeformation(int secTag); +extern CrdTransf* OPS_GetCrdTransf(int crdTag); +extern FrictionModel* OPS_GetFrictionModel(int frnTag); +extern LimitCurve* OPS_GetLimitCurve(int LimCrvTag); +extern Domain* OPS_GetDomain(void); + +extern FE_Datastore* OPS_GetFEDatastore(); +extern "C" const char* OPS_GetInterpPWD(); + +extern "C" AnalysisModel * *OPS_GetAnalysisModel(void); +extern "C" EquiSolnAlgo * *OPS_GetAlgorithm(void); +extern "C" ConstraintHandler * *OPS_GetHandler(void); +extern "C" DOF_Numberer * *OPS_GetNumberer(void); +extern "C" LinearSOE * *OPS_GetSOE(void); +extern "C" EigenSOE * *OPS_GetEigenSOE(void); +extern "C" StaticAnalysis * *OPS_GetStaticAnalysis(void); +extern "C" DirectIntegrationAnalysis * *OPS_GetTransientAnalysis(void); +extern "C" VariableTimeStepDirectIntegrationAnalysis * *OPS_GetVariableTimeStepTransientAnalysis(void); +extern "C" int* OPS_GetNumEigen(void); +extern "C" StaticIntegrator * *OPS_GetStaticIntegrator(void); +extern "C" TransientIntegrator * *OPS_GetTransientIntegrator(void); +extern "C" ConvergenceTest * *OPS_GetTest(void); +extern "C" bool* OPS_builtModel(void); int OPS_numIter(); @@ -248,48 +248,48 @@ int OPS_numIter(); int OPS_GetNDF(); int OPS_GetNDM(); -int OPS_Error(char *, int length); -int OPS_GetIntInput(int *numData, int*data); -int OPS_GetDoubleInput(int *numData, double *data); -int OPS_GetString(char *cArray, int sizeArray); - - -matObj *OPS_GetMaterial(int *matTag, int *matType); -void OPS_GetMaterialPtr(int *, matObj *); -eleObj *OPS_GetElement(int *); -matObj *OPS_GetMaterialType(char *type, int sizeType); -eleObj *OPS_GetElementType(char *, int); -int OPS_AllocateElement(eleObj *, int *matTags, int *maType); -int OPS_AllocateMaterial(matObj *); - -limCrv *OPS_GetLimitCurveType(char *type, int sizeType);//**MRL -int OPS_AllocateLimitCurve(limCrvObj *);//**MRL - -int OPS_InvokeMaterial(struct eleObj *, int *,modelState *, double *, double *, double *, int *); -int OPS_InvokeMaterialDirectly(matObj **, modelState *, double *, double *, double *, int *); -int OPS_InvokeMaterialDirectly2(matObj *, modelState *, double *, double *, double *, int *); - -int OPS_GetNodeCrd(int *nodeTag, int *sizeData, double *data); -int OPS_GetNodeDisp(int *nodeTag, int *sizeData, double *data); -int OPS_GetNodeVel(int *nodeTag, int *sizeData, double *data); -int OPS_GetNodeAcc(int *nodeTag, int *sizeData, double *data); -int OPS_GetNodeIncrDisp(int *nodeTag, int *sizeData, double *data); -int OPS_GetNodeIncrDeltaDisp(int *nodeTag, int *sizeData, double *data); - -AnalysisModel **OPS_GetAnalysisModel(void); -EquiSolnAlgo **OPS_GetAlgorithm(void); -ConstraintHandler **OPS_GetHandler(void); -DOF_Numberer **OPS_GetNumberer(void); -LinearSOE **OPS_GetSOE(void); -EigenSOE **OPS_GetEigenSOE(void); -StaticAnalysis **OPS_GetStaticAnalysis(void); -DirectIntegrationAnalysis **OPS_GetTransientAnalysis(void); -VariableTimeStepDirectIntegrationAnalysis **OPS_GetVariableTimeStepTransientAnalysis(void); -int *OPS_GetNumEigen(void); -StaticIntegrator **OPS_GetStaticIntegrator(void); -TransientIntegrator **OPS_GetTransientIntegrator(void); -ConvergenceTest **OPS_GetTest(void); -bool *OPS_builtModel(void); +int OPS_Error(char*, int length); +int OPS_GetIntInput(int* numData, int* data); +int OPS_GetDoubleInput(int* numData, double* data); +int OPS_GetString(char* cArray, int sizeArray); + + +matObj* OPS_GetMaterial(int* matTag, int* matType); +void OPS_GetMaterialPtr(int*, matObj*); +eleObj* OPS_GetElement(int*); +matObj* OPS_GetMaterialType(char* type, int sizeType); +eleObj* OPS_GetElementType(char*, int); +int OPS_AllocateElement(eleObj*, int* matTags, int* maType); +int OPS_AllocateMaterial(matObj*); + +limCrv* OPS_GetLimitCurveType(char* type, int sizeType);//**MRL +int OPS_AllocateLimitCurve(limCrvObj*);//**MRL + +int OPS_InvokeMaterial(struct eleObj*, int*, modelState*, double*, double*, double*, int*); +int OPS_InvokeMaterialDirectly(matObj**, modelState*, double*, double*, double*, int*); +int OPS_InvokeMaterialDirectly2(matObj*, modelState*, double*, double*, double*, int*); + +int OPS_GetNodeCrd(int* nodeTag, int* sizeData, double* data); +int OPS_GetNodeDisp(int* nodeTag, int* sizeData, double* data); +int OPS_GetNodeVel(int* nodeTag, int* sizeData, double* data); +int OPS_GetNodeAcc(int* nodeTag, int* sizeData, double* data); +int OPS_GetNodeIncrDisp(int* nodeTag, int* sizeData, double* data); +int OPS_GetNodeIncrDeltaDisp(int* nodeTag, int* sizeData, double* data); + +AnalysisModel** OPS_GetAnalysisModel(void); +EquiSolnAlgo** OPS_GetAlgorithm(void); +ConstraintHandler** OPS_GetHandler(void); +DOF_Numberer** OPS_GetNumberer(void); +LinearSOE** OPS_GetSOE(void); +EigenSOE** OPS_GetEigenSOE(void); +StaticAnalysis** OPS_GetStaticAnalysis(void); +DirectIntegrationAnalysis** OPS_GetTransientAnalysis(void); +VariableTimeStepDirectIntegrationAnalysis** OPS_GetVariableTimeStepTransientAnalysis(void); +int* OPS_GetNumEigen(void); +StaticIntegrator** OPS_GetStaticIntegrator(void); +TransientIntegrator** OPS_GetTransientIntegrator(void); +ConvergenceTest** OPS_GetTest(void); +bool* OPS_builtModel(void); #endif diff --git a/SRC/api/elementAPI_TCL.cpp b/SRC/api/elementAPI_TCL.cpp index 5a269f7ad0..e9e5989725 100644 --- a/SRC/api/elementAPI_TCL.cpp +++ b/SRC/api/elementAPI_TCL.cpp @@ -18,12 +18,12 @@ ** ** ** ****************************************************************** */ -/* +/* ** $Revision: 1.12 $ ** $Date: 2010-03-05 22:32:36 $ ** $Source: /usr/local/cvs/OpenSees/SRC/api/elementAPI.cpp,v $ - -** Written: fmk + +** Written: fmk */ #include @@ -44,126 +44,128 @@ #include #include #include -#include //MRL -#include //MRL +#include +#include #include typedef struct elementFunction { - char *funcName; - eleFunct theFunct; - struct elementFunction *next; + char* funcName; + eleFunct theFunct; + struct elementFunction* next; } ElementFunction; typedef struct materialFunction { - char *funcName; - matFunct theFunct; - struct materialFunction *next; + char* funcName; + matFunct theFunct; + struct materialFunction* next; } MaterialFunction; -//MRL start typedef struct limitCurveFunction { - char *funcName; - limCrvFunct theFunct; - struct limitCurveFunction *next; + char* funcName; + limCrvFunct theFunct; + struct limitCurveFunction* next; } LimitCurveFunction; -//MRL end - -extern AnalysisModel *theAnalysisModel; -extern EquiSolnAlgo *theAlgorithm; -extern ConstraintHandler *theHandler; -extern DOF_Numberer *theNumberer; -extern LinearSOE *theSOE; -extern EigenSOE *theEigenSOE; -extern StaticAnalysis *theStaticAnalysis; -extern DirectIntegrationAnalysis *theTransientAnalysis; -extern VariableTimeStepDirectIntegrationAnalysis *theVariableTimeStepTransientAnalysis; + +extern AnalysisModel* theAnalysisModel; +extern EquiSolnAlgo* theAlgorithm; +extern ConstraintHandler* theHandler; +extern DOF_Numberer* theNumberer; +extern LinearSOE* theSOE; +extern EigenSOE* theEigenSOE; +extern StaticAnalysis* theStaticAnalysis; +extern DirectIntegrationAnalysis* theTransientAnalysis; +extern VariableTimeStepDirectIntegrationAnalysis* theVariableTimeStepTransientAnalysis; extern int numEigen; -extern StaticIntegrator *theStaticIntegrator; -extern TransientIntegrator *theTransientIntegrator; -extern ConvergenceTest *theTest; +extern StaticIntegrator* theStaticIntegrator; +extern TransientIntegrator* theTransientIntegrator; +extern ConvergenceTest* theTest; extern bool builtModel; -static ElementFunction *theElementFunctions = NULL; -static MaterialFunction *theMaterialFunctions = NULL; -static LimitCurveFunction *theLimitCurveFunctions = NULL;//MRL +static ElementFunction* theElementFunctions = NULL; +static MaterialFunction* theMaterialFunctions = NULL; +static LimitCurveFunction* theLimitCurveFunctions = NULL; -static Tcl_Interp *theInterp = 0; -static Domain *theDomain = 0; +static Tcl_Interp* theInterp = 0; +static Domain* theDomain = 0; -static TclModelBuilder *theModelBuilder = 0; +static TclModelBuilder* theModelBuilder = 0; -static TCL_Char **currentArgv = 0; +static TCL_Char** currentArgv = 0; static int currentArg = 0; static int maxArg = 0; -extern const char *getInterpPWD(Tcl_Interp *interp); -extern FE_Datastore *theDatabase; +extern const char* getInterpPWD(Tcl_Interp* interp); +extern FE_Datastore* theDatabase; -//static int uniaxialMaterialObjectCount =0; +//static int uniaxialMaterialObjectCount = 0; modelState theModelState; struct cmp_str { - bool operator()(const char *a, const char *b) { - return strcmp(a,b)<0; - } + bool operator()(const char* a, const char* b) { + return strcmp(a, b) < 0; + } }; -std::maptheEleFunctions; // map of user added ele functions -std::maptheUniaxialMaterialFunctions; // map of user added material functions +std::maptheEleFunctions; // map of user added ele functions +std::maptheUniaxialMaterialFunctions; // map of user added material functions //std::maptheUniaxialMaterials; // map for UniaxialMaterial objects needed by user added ele functions' -static -void OPS_InvokeMaterialObject(struct matObject *theMat, modelState *theModel,double *strain, double *tang, double *stress, int *isw, int *result) +static +void OPS_InvokeMaterialObject(struct matObject* theMat, modelState* theModel, double* strain, double* tang, double* stress, int* isw, int* result) { - int matType = (int)theMat->theParam[0]; - - if (matType == 1) { - // UniaxialMaterial *theMaterial = theUniaxialMaterials[matCount]; - UniaxialMaterial *theMaterial = (UniaxialMaterial *)theMat->matObjectPtr; - if (theMaterial == 0) { - *result = -1; - return; - } - - if (*isw == ISW_COMMIT) { - *result = theMaterial->commitState(); - return; - } else if (*isw == ISW_REVERT) { - *result = theMaterial->revertToLastCommit(); - return; - } else if (*isw == ISW_REVERT_TO_START) { - *result = theMaterial->revertToStart(); - return; - } else if (*isw == ISW_FORM_TANG_AND_RESID) { - double matStress = 0.0; - double matTangent = 0.0; - int res = theMaterial->setTrial(strain[0], matStress, matTangent); - stress[0] = matStress; - tang[0] = matTangent; - *result = res; - return; + int matType = (int)theMat->theParam[0]; + + if (matType == 1) { + // UniaxialMaterial *theMaterial = theUniaxialMaterials[matCount]; + UniaxialMaterial* theMaterial = (UniaxialMaterial*)theMat->matObjectPtr; + if (theMaterial == 0) { + *result = -1; + return; + } + + if (*isw == ISW_COMMIT) { + *result = theMaterial->commitState(); + return; + } + else if (*isw == ISW_REVERT) { + *result = theMaterial->revertToLastCommit(); + return; + } + else if (*isw == ISW_REVERT_TO_START) { + *result = theMaterial->revertToStart(); + return; + } + else if (*isw == ISW_FORM_TANG_AND_RESID) { + double matStress = 0.0; + double matTangent = 0.0; + int res = theMaterial->setTrial(strain[0], matStress, matTangent); + stress[0] = matStress; + tang[0] = matTangent; + *result = res; + return; + } } - } - - return; + + return; } -extern "C" -int OPS_Error(char *errorMessage, int length) +extern "C" +int OPS_Error(char* errorMessage, int length) { - opserr << errorMessage; - opserr << endln; - return 0; + opserr << errorMessage; + opserr << endln; + + return 0; } -extern "C" +extern "C" int OPS_GetNumRemainingInputArgs() { - return maxArg-currentArg; + return maxArg - currentArg; } extern "C" @@ -175,165 +177,201 @@ int OPS_ResetCurrentInputArg(int cArg) return 0; } +//extern "C" +int OPS_ResetInput(ClientData clientData, + Tcl_Interp* interp, + int cArg, + int mArg, + TCL_Char** argv, + Domain* domain, + TclModelBuilder* builder) +{ + theInterp = interp; + theDomain = domain; + theModelBuilder = builder; + currentArgv = argv; + currentArg = cArg; + maxArg = mArg; + + return 0; +} -extern "C" -int OPS_GetIntInput(int *numData, int*data) +extern "C" +int OPS_ResetInputNoBuilder(ClientData clientData, + Tcl_Interp * interp, + int cArg, + int mArg, + TCL_Char * *argv, + Domain * domain) { - int size = *numData; + theInterp = interp; + theDomain = domain; + currentArgv = argv; + currentArg = cArg; + maxArg = mArg; - for (int i=0; i= maxArg) || (Tcl_GetInt(theInterp, currentArgv[currentArg], &data[i]) != TCL_OK)) { - //opserr << "OPS_GetIntInput -- error reading " << currentArg << endln; - return -1; + return 0; +} + +extern "C" +int OPS_GetIntInput(int* numData, int* data) +{ + int size = *numData; + + for (int i = 0; i < size; i++) { + if ((currentArg >= maxArg) || (Tcl_GetInt(theInterp, currentArgv[currentArg], &data[i]) != TCL_OK)) { + //opserr << "OPS_GetIntInput -- error reading " << currentArg << endln; + return -1; + } + else + currentArg++; } - else - currentArg++; - } - return 0; + return 0; } -extern "C" -int OPS_SetIntOutput(int *numData, int *data, bool scalar) +extern "C" +int OPS_SetIntOutput(int* numData, int* data, bool scalar) { int numArgs = *numData; char buffer[40]; - for (int i=0; i= maxArg) || (Tcl_GetDouble(theInterp, currentArgv[currentArg], &data[i]) != TCL_OK)) { - //opserr << "OPS_GetDoubleInput -- error reading " << currentArg << endln; - return -1; + int size = *numData; + for (int i = 0; i < size; i++) { + if ((currentArg >= maxArg) || (Tcl_GetDouble(theInterp, currentArgv[currentArg], &data[i]) != TCL_OK)) { + //opserr << "OPS_GetDoubleInput -- error reading " << currentArg << endln; + return -1; + } + else + currentArg++; } - else - currentArg++; - } - return 0; + + return 0; } -extern "C" -int OPS_SetDoubleOutput(int *numData, double *data, bool scalar) +extern "C" +int OPS_SetDoubleOutput(int* numData, double* data, bool scalar) { int numArgs = *numData; char buffer[40]; - for (int i=0; i= maxArg) { - opserr << "OPS_GetStringInput -- error reading " << currentArg << endln; - return res; - } - res = currentArgv[currentArg]; - - currentArg++; + const char* res = 0; + if (currentArg >= maxArg) { + opserr << "OPS_GetStringInput -- error reading " << currentArg << endln; + return res; + } + res = currentArgv[currentArg]; - return res; + currentArg++; + + return res; } -extern "C" +extern "C" int OPS_SetString(const char* str) { - Tcl_SetResult(theInterp, (char*)str, TCL_VOLATILE); - return 0; + Tcl_SetResult(theInterp, (char*)str, TCL_VOLATILE); + return 0; } -int OPS_GetStringCopy(char **arrayData) +int OPS_GetStringCopy(char** arrayData) { - if (currentArg >= maxArg) { - opserr << "OPS_GetStringInput -- error reading " << currentArg << endln; - return -1; - } - char *newData = new char[strlen(currentArgv[currentArg])+1]; - strcpy(newData, currentArgv[currentArg]); - *arrayData = newData; - currentArg++; + if (currentArg >= maxArg) { + opserr << "OPS_GetStringInput -- error reading " << currentArg << endln; + return -1; + } + char* newData = new char[strlen(currentArgv[currentArg]) + 1]; + strcpy(newData, currentArgv[currentArg]); + *arrayData = newData; + currentArg++; - return 0; + return 0; } - -extern "C" -matObj *OPS_GetMaterial(int *matTag, int *matType) +extern "C" +matObj * OPS_GetMaterial(int* matTag, int* matType) { + if (*matType == OPS_UNIAXIAL_MATERIAL_TYPE) { + UniaxialMaterial* theUniaxialMaterial = OPS_getUniaxialMaterial(*matTag); - if (*matType == OPS_UNIAXIAL_MATERIAL_TYPE) { - UniaxialMaterial *theUniaxialMaterial = OPS_getUniaxialMaterial(*matTag); - - if (theUniaxialMaterial != 0) { - - UniaxialMaterial *theCopy = theUniaxialMaterial->getCopy(); - // uniaxialMaterialObjectCount++; - // theUniaxialMaterials[uniaxialMaterialObjectCount] = theCopy; - - matObject *theMatObject = new matObject; - theMatObject->tag = *matTag; - theMatObject->nParam = 1; - theMatObject->nState = 0; - - theMatObject->theParam = new double[1]; - // theMatObject->theParam[0] = uniaxialMaterialObjectCount; - theMatObject->theParam[0] = 1; // code for uniaxial material - - theMatObject->tState = 0; - theMatObject->cState = 0; - theMatObject->matFunctPtr = OPS_InvokeMaterialObject; - - theMatObject->matObjectPtr = theCopy; - - return theMatObject; - } - - fprintf(stderr,"getMaterial - no uniaxial material exists with tag %d\n", *matTag); - return 0; + if (theUniaxialMaterial != 0) { - } else if (*matType == OPS_SECTION_TYPE) { - fprintf(stderr,"getMaterial - not yet implemented for Section\n"); - return 0; - } else { + UniaxialMaterial* theCopy = theUniaxialMaterial->getCopy(); + // uniaxialMaterialObjectCount++; + // theUniaxialMaterials[uniaxialMaterialObjectCount] = theCopy; - // NDMaterial *theNDMaterial = theModelBuilder->getNDMaterial(*matTag); + matObject* theMatObject = new matObject; + theMatObject->tag = *matTag; + theMatObject->nParam = 1; + theMatObject->nState = 0; - // if (theNDMaterial != 0) - // theNDMaterial = theNDMaterial->getCopy(matType); - // else { - // fprintf(stderr,"getMaterial - no nd material exists with tag %d\n", *matTag); - // return 0; - // } + theMatObject->theParam = new double[1]; + // theMatObject->theParam[0] = uniaxialMaterialObjectCount; + theMatObject->theParam[0] = 1; // code for uniaxial material - // if (theNDMaterial == 0) { - // fprintf(stderr,"getMaterial - material with tag %d cannot deal with %d\n", *matTag, matType); - // return 0; - // } + theMatObject->tState = 0; + theMatObject->cState = 0; + theMatObject->matFunctPtr = OPS_InvokeMaterialObject; - fprintf(stderr,"getMaterial - not yet implemented for nDMaterial\n"); - return 0; - } + theMatObject->matObjectPtr = theCopy; - fprintf(stderr,"getMaterial - unknown material type\n"); - return 0; + return theMatObject; + } + fprintf(stderr, "getMaterial - no uniaxial material exists with tag %d\n", *matTag); + return 0; + + } + else if (*matType == OPS_SECTION_TYPE) { + fprintf(stderr, "getMaterial - not yet implemented for Section\n"); + return 0; + } + else { + + // NDMaterial *theNDMaterial = theModelBuilder->getNDMaterial(*matTag); + + // if (theNDMaterial != 0) + // theNDMaterial = theNDMaterial->getCopy(matType); + // else { + // fprintf(stderr,"getMaterial - no nd material exists with tag %d\n", *matTag); + // return 0; + // } + + // if (theNDMaterial == 0) { + // fprintf(stderr,"getMaterial - material with tag %d cannot deal with %d\n", *matTag, matType); + // return 0; + // } + + fprintf(stderr, "getMaterial - not yet implemented for nDMaterial\n"); + return 0; + } + + fprintf(stderr, "getMaterial - unknown material type\n"); + return 0; } /* -extern "C" +extern "C" void OPS_GetMaterialPtr(int *matTag, matObj *theRes) { UniaxialMaterial *theUniaxialMaterial = theModelBuilder->getUniaxialMaterial(*matTag); @@ -342,7 +380,7 @@ void OPS_GetMaterialPtr(int *matTag, matObj *theRes) UniaxialMaterial *theCopy = theUniaxialMaterial->getCopy(); if (theCopy == 0) { - fprintf(stderr,"OPS_GetMaterialPtr() failed - no material of type %d \n", *matTag); + fprintf(stderr,"OPS_GetMaterialPtr() failed - no material of type %d \n", *matTag); theRes = 0; return; } @@ -369,755 +407,720 @@ void OPS_GetMaterialPtr(int *matTag, matObj *theRes) } */ - -extern "C" -eleObj *OPS_GetElement(int *eleTag) { - return 0; +extern "C" +eleObj * OPS_GetElement(int* eleTag) { + return 0; } -extern "C" -eleObj *OPS_GetElementType(char *type, int sizeType) { - - // try existing loaded routines - - ElementFunction *eleFunction = theElementFunctions; - bool found = false; - while (eleFunction != NULL && found == false) { - if (strcmp(type, eleFunction->funcName) == 0) { - - // create a new eleObject, set the function ptr & return it - - eleObj *theEleObject = new eleObj; - theEleObject->eleFunctPtr = eleFunction->theFunct; - return theEleObject; - } - else - eleFunction = eleFunction->next; - } +extern "C" +eleObj * OPS_GetElementType(char* type, int sizeType) { - // ty to load new routine from dynamic library in load path - - eleFunct eleFunctPtr; - void *libHandle; - - int res = getLibraryFunction(type, type, &libHandle, (void **)&eleFunctPtr); - - if (res == 0) { - - // add the routine to the list of possible elements - - char *funcName = new char[strlen(type)+1]; - strcpy(funcName, type); - eleFunction = new ElementFunction; - eleFunction->theFunct = eleFunctPtr; - eleFunction->funcName = funcName; - eleFunction->next = theElementFunctions; - theElementFunctions = eleFunction; - - // create a new eleObject, set the function ptr & return it - - eleObj *theEleObject = new eleObj; - //eleObj *theEleObject = (eleObj *)malloc(sizeof( eleObj));; + // try existing loaded routines - theEleObject->eleFunctPtr = eleFunction->theFunct; + ElementFunction* eleFunction = theElementFunctions; + bool found = false; + while (eleFunction != NULL && found == false) { + if (strcmp(type, eleFunction->funcName) == 0) { - return theEleObject; - } - return 0; -} + // create a new eleObject, set the function ptr & return it -extern "C" -matObj *OPS_GetMaterialType(char *type, int sizeType) { - - // try existing loaded routines - MaterialFunction *matFunction = theMaterialFunctions; - bool found = false; - while (matFunction != NULL && found == false) { - if (strcmp(type, matFunction->funcName) == 0) { - - // create a new eleObject, set the function ptr & return it - - matObj *theMatObject = new matObj; - theMatObject->matFunctPtr = matFunction->theFunct; - /* opserr << "matObj *OPS_GetMaterialType() - FOUND " << endln; */ - return theMatObject; + eleObj* theEleObject = new eleObj; + theEleObject->eleFunctPtr = eleFunction->theFunct; + return theEleObject; + } + else + eleFunction = eleFunction->next; } - else - matFunction = matFunction->next; - } - // ty to load new routine from dynamic library in load path - matFunct matFunctPtr; - void *libHandle; - - int res = getLibraryFunction(type, type, &libHandle, (void **)&matFunctPtr); - - if (res == 0) { + // ty to load new routine from dynamic library in load path - // add the routine to the list of possible elements - - char *funcName = new char[strlen(type)+1]; - strcpy(funcName, type); - matFunction = new MaterialFunction; - matFunction->theFunct = matFunctPtr; - matFunction->funcName = funcName; - matFunction->next = theMaterialFunctions; - theMaterialFunctions = matFunction; - - // create a new eleObject, set the function ptr & return it - - matObj *theMatObject = new matObj; - //eleObj *theEleObject = (eleObj *)malloc(sizeof( eleObj));; + eleFunct eleFunctPtr; + void* libHandle; - theMatObject->matFunctPtr = matFunction->theFunct; + int res = getLibraryFunction(type, type, &libHandle, (void**)&eleFunctPtr); - // fprintf(stderr,"getMaterial Address %p\n",theMatObject); + if (res == 0) { - return theMatObject; - } + // add the routine to the list of possible elements - return 0; -} + char* funcName = new char[strlen(type) + 1]; + strcpy(funcName, type); + eleFunction = new ElementFunction; + eleFunction->theFunct = eleFunctPtr; + eleFunction->funcName = funcName; + eleFunction->next = theElementFunctions; + theElementFunctions = eleFunction; + // create a new eleObject, set the function ptr & return it -// MRL start -extern "C" -limCrvObj *OPS_GetLimitCurveType(char *type, int sizeType) { - - // try existing loaded routines - LimitCurveFunction *limCrvFunction = theLimitCurveFunctions; - bool found = false; - while (limCrvFunction != NULL && found == false) { - if (strcmp(type, limCrvFunction->funcName) == 0) { - - // create a new eleObject, set the function ptr & return it - - limCrvObj *theLimCrvObject = new limCrvObj; - theLimCrvObject->limCrvFunctPtr = limCrvFunction->theFunct; - /* opserr << "limCrvObj *OPS_GetLimitCurveType() - FOUND " << endln; */ - return theLimCrvObject; - } - else - limCrvFunction = limCrvFunction->next; - } + eleObj* theEleObject = new eleObj; + //eleObj *theEleObject = (eleObj *)malloc(sizeof( eleObj));; - // try to load new routine from dynamic library in load path - limCrvFunct limCrvFunctPtr; - void *libHandle; - int res = getLibraryFunction(type, type, &libHandle, (void **)&limCrvFunctPtr); - - if (res == 0) - { - // add the routine to the list of possible elements - char *funcName = new char[strlen(type)+1]; - strcpy(funcName, type); - limCrvFunction = new LimitCurveFunction; - limCrvFunction->theFunct = limCrvFunctPtr; - limCrvFunction->funcName = funcName; - limCrvFunction->next = theLimitCurveFunctions; - theLimitCurveFunctions = limCrvFunction; - - // create a new eleObject, set the function ptr & return it - limCrvObj *theLimCrvObject = new limCrvObj; - theLimCrvObject->limCrvFunctPtr = limCrvFunction->theFunct; - return theLimCrvObject; - } + theEleObject->eleFunctPtr = eleFunction->theFunct; - return 0; + return theEleObject; + } + + return 0; } -// MRL end -//MRL start -extern "C" -int OPS_AllocateLimitCurve(limCrvObject *theLimCrv){ +extern "C" +matObj * OPS_GetMaterialType(char* type, int sizeType) { + + // try existing loaded routines + MaterialFunction* matFunction = theMaterialFunctions; + bool found = false; + while (matFunction != NULL && found == false) { + if (strcmp(type, matFunction->funcName) == 0) { + + // create a new eleObject, set the function ptr & return it + + matObj* theMatObject = new matObj; + theMatObject->matFunctPtr = matFunction->theFunct; + /* opserr << "matObj *OPS_GetMaterialType() - FOUND " << endln; */ + return theMatObject; + } + else + matFunction = matFunction->next; + } - /*fprintf(stderr,"allocateLimitCurve Address %p\n",theLimCrv);*/ + // ty to load new routine from dynamic library in load path + matFunct matFunctPtr; + void* libHandle; - if (theLimCrv->nParam > 0) - theLimCrv->theParam = new double[theLimCrv->nParam]; + int res = getLibraryFunction(type, type, &libHandle, (void**)&matFunctPtr); - int nState = theLimCrv->nState; + if (res == 0) { - if (nState > 0) { - theLimCrv->cState = new double[nState]; - theLimCrv->tState = new double[nState]; - for (int i=0; icState[i] = 0; - theLimCrv->tState[i] = 0; - } - } else { - theLimCrv->cState = 0; - theLimCrv->tState = 0; - } + // add the routine to the list of possible elements - return 0; -} -//MRL end + char* funcName = new char[strlen(type) + 1]; + strcpy(funcName, type); + matFunction = new MaterialFunction; + matFunction->theFunct = matFunctPtr; + matFunction->funcName = funcName; + matFunction->next = theMaterialFunctions; + theMaterialFunctions = matFunction; -extern "C" -int OPS_AllocateMaterial(matObject *theMat){ + // create a new eleObject, set the function ptr & return it - /*fprintf(stderr,"allocateMaterial Address %p\n",theMat);*/ + matObj* theMatObject = new matObj; + //eleObj *theEleObject = (eleObj *)malloc(sizeof( eleObj));; - if (theMat->nParam > 0) - theMat->theParam = new double[theMat->nParam]; + theMatObject->matFunctPtr = matFunction->theFunct; - int nState = theMat->nState; + // fprintf(stderr,"getMaterial Address %p\n",theMatObject); - if (nState > 0) { - theMat->cState = new double[nState]; - theMat->tState = new double[nState]; - for (int i=0; icState[i] = 0; - theMat->tState[i] = 0; + return theMatObject; } - } else { - theMat->cState = 0; - theMat->tState = 0; - } - return 0; -} + return 0; +} -extern "C" -int OPS_AllocateElement(eleObject *theEle, int *matTags, int *matType){ - if (theEle->nNode > 0) - theEle->node = new int[theEle->nNode]; +extern "C" +limCrvObj * OPS_GetLimitCurveType(char* type, int sizeType) { + + // try existing loaded routines + LimitCurveFunction* limCrvFunction = theLimitCurveFunctions; + bool found = false; + while (limCrvFunction != NULL && found == false) { + if (strcmp(type, limCrvFunction->funcName) == 0) { + + // create a new eleObject, set the function ptr & return it + + limCrvObj* theLimCrvObject = new limCrvObj; + theLimCrvObject->limCrvFunctPtr = limCrvFunction->theFunct; + /* opserr << "limCrvObj *OPS_GetLimitCurveType() - FOUND " << endln; */ + return theLimCrvObject; + } + else + limCrvFunction = limCrvFunction->next; + } - if (theEle->nParam > 0) - theEle->param = new double[theEle->nParam]; + // try to load new routine from dynamic library in load path + limCrvFunct limCrvFunctPtr; + void* libHandle; + int res = getLibraryFunction(type, type, &libHandle, (void**)&limCrvFunctPtr); + + if (res == 0) + { + // add the routine to the list of possible elements + char* funcName = new char[strlen(type) + 1]; + strcpy(funcName, type); + limCrvFunction = new LimitCurveFunction; + limCrvFunction->theFunct = limCrvFunctPtr; + limCrvFunction->funcName = funcName; + limCrvFunction->next = theLimitCurveFunctions; + theLimitCurveFunctions = limCrvFunction; + + // create a new eleObject, set the function ptr & return it + limCrvObj* theLimCrvObject = new limCrvObj; + theLimCrvObject->limCrvFunctPtr = limCrvFunction->theFunct; + return theLimCrvObject; + } - if (theEle->nState > 0) { - theEle->cState = new double[theEle->nState]; - theEle->tState = new double[theEle->nState]; - } + return 0; +} - int numMat = theEle->nMat; - if (numMat > 0) - theEle->mats = new matObject *[numMat]; +extern "C" +int OPS_AllocateLimitCurve(limCrvObject * theLimCrv) { - - for (int i=0; i< numMat; i++) { - /* opserr << "AllocateElement - matTag " << matTags[i] << "\n"; */ + /*fprintf(stderr,"allocateLimitCurve Address %p\n",theLimCrv);*/ - matObject *theMat = OPS_GetMaterial(&(matTags[i]), matType); - // matObject *theMat = OPS_GetMaterial(&(matTags[i])); + if (theLimCrv->nParam > 0) + theLimCrv->theParam = new double[theLimCrv->nParam]; - theEle->mats[i] = theMat; - } + int nState = theLimCrv->nState; - return 0; -} + if (nState > 0) { + theLimCrv->cState = new double[nState]; + theLimCrv->tState = new double[nState]; + for (int i = 0; i < nState; i++) { + theLimCrv->cState[i] = 0; + theLimCrv->tState[i] = 0; + } + } + else { + theLimCrv->cState = 0; + theLimCrv->tState = 0; + } + return 0; +} +extern "C" +int OPS_AllocateMaterial(matObject * theMat) { -extern "C" -int OPS_GetNodeCrd(int *nodeTag, int *sizeCrd, double *data) -{ - Node *theNode = theDomain->getNode(*nodeTag); - if (theNode == 0) { - opserr << "OPS_GetNodeCrd - no node with tag " << *nodeTag << endln; - return -1; - } - int size = *sizeCrd; - const Vector &crd = theNode->getCrds(); - if (crd.Size() != size) { - opserr << "OPS_GetNodeCrd - crd size mismatch\n"; - opserr << "Actual crd size is: " << crd.Size() << endln; //MRL Add Error Detection - return -1; - } - for (int i=0; i < size; i++) - data[i] = crd(i); - - return 0; -} + /*fprintf(stderr,"allocateMaterial Address %p\n",theMat);*/ -extern "C" -int OPS_GetNodeDisp(int *nodeTag, int *sizeData, double *data) -{ - Node *theNode = theDomain->getNode(*nodeTag); + if (theMat->nParam > 0) + theMat->theParam = new double[theMat->nParam]; - if (theNode == 0) { - opserr << "OPS_GetNodeDisp - no node with tag " << *nodeTag << endln; - return -1; - } - int size = *sizeData; - const Vector &disp = theNode->getTrialDisp(); + int nState = theMat->nState; - if (disp.Size() != size) { - opserr << "OPS_GetNodeDisp - crd size mismatch\n"; - return -1; - } - for (int i=0; i < size; i++) - data[i] = disp(i); - - return 0; + if (nState > 0) { + theMat->cState = new double[nState]; + theMat->tState = new double[nState]; + for (int i = 0; i < nState; i++) { + theMat->cState[i] = 0; + theMat->tState[i] = 0; + } + } + else { + theMat->cState = 0; + theMat->tState = 0; + } + + return 0; } -extern "C" -int OPS_GetNodeVel(int *nodeTag, int *sizeData, double *data) -{ - Node *theNode = theDomain->getNode(*nodeTag); +extern "C" +int OPS_AllocateElement(eleObject * theEle, int* matTags, int* matType) { + if (theEle->nNode > 0) + theEle->node = new int[theEle->nNode]; - if (theNode == 0) { - opserr << "OPS_GetNodeVel - no node with tag " << *nodeTag << endln; - return -1; - } - int size = *sizeData; - const Vector &vel = theNode->getTrialVel(); + if (theEle->nParam > 0) + theEle->param = new double[theEle->nParam]; - if (vel.Size() != size) { - opserr << "OPS_GetNodeVel - crd size mismatch\n"; - return -1; - } - for (int i=0; i < size; i++) - data[i] = vel(i); - - return 0; -} + if (theEle->nState > 0) { + theEle->cState = new double[theEle->nState]; + theEle->tState = new double[theEle->nState]; + } -extern "C" -int OPS_GetNodeAccel(int *nodeTag, int *sizeData, double *data) -{ - Node *theNode = theDomain->getNode(*nodeTag); + int numMat = theEle->nMat; + if (numMat > 0) + theEle->mats = new matObject * [numMat]; - if (theNode == 0) { - opserr << "OPS_GetNodeAccel - no node with tag " << *nodeTag << endln; - return -1; - } - int size = *sizeData; - const Vector &accel = theNode->getTrialAccel(); - if (accel.Size() != size) { - opserr << "OPS_GetNodeAccel - accel size mismatch\n"; - return -1; - } - for (int i=0; i < size; i++) - data[i] = accel(i); - - return 0; -} + for (int i = 0; i < numMat; i++) { + /* opserr << "AllocateElement - matTag " << matTags[i] << "\n"; */ -extern "C" -int OPS_GetNodeIncrDisp(int *nodeTag, int *sizeData, double *data) -{ - Node *theNode = theDomain->getNode(*nodeTag); + matObject* theMat = OPS_GetMaterial(&(matTags[i]), matType); + // matObject *theMat = OPS_GetMaterial(&(matTags[i])); - if (theNode == 0) { - opserr << "OPS_GetNodeIncrDisp - no node with tag " << *nodeTag << endln; - return -1; - } - int size = *sizeData; - const Vector &disp = theNode->getIncrDisp(); + theEle->mats[i] = theMat; + } - if (disp.Size() != size) { - opserr << "OPS_GetNodeIncrDis - crd size mismatch\n"; - return -1; - } - for (int i=0; i < size; i++) - data[i] = disp(i); - - return 0; + return 0; } - -extern "C" -int OPS_GetNodeIncrDeltaDisp(int *nodeTag, int *sizeData, double *data) +extern "C" +int OPS_GetNodeCrd(int* nodeTag, int* sizeCrd, double* data) { - Node *theNode = theDomain->getNode(*nodeTag); - - if (theNode == 0) { - opserr << "OPS_GetNodeIncrDeltaDisp - no node with tag " << *nodeTag << endln; - return -1; - } - int size = *sizeData; - const Vector &disp = theNode->getIncrDeltaDisp(); + Node* theNode = theDomain->getNode(*nodeTag); + if (theNode == 0) { + opserr << "OPS_GetNodeCrd - no node with tag " << *nodeTag << endln; + return -1; + } + int size = *sizeCrd; + const Vector& crd = theNode->getCrds(); + if (crd.Size() != size) { + opserr << "OPS_GetNodeCrd - crd size mismatch\n"; + opserr << "Actual crd size is: " << crd.Size() << endln; //MRL Add Error Detection + return -1; + } + for (int i = 0; i < size; i++) + data[i] = crd(i); - if (disp.Size() != size) { - opserr << "OPS_GetNodeIncrDis - crd size mismatch\n"; - return -1; - } - for (int i=0; i < size; i++) - data[i] = disp(i); - - return 0; + return 0; } +extern "C" +int OPS_GetNodeDisp(int* nodeTag, int* sizeData, double* data) +{ + Node* theNode = theDomain->getNode(*nodeTag); + if (theNode == 0) { + opserr << "OPS_GetNodeDisp - no node with tag " << *nodeTag << endln; + return -1; + } + int size = *sizeData; + const Vector& disp = theNode->getTrialDisp(); -int -Tcl_addWrapperElement(eleObj *theEle, ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv, Domain* domain, TclModelBuilder *builder) + if (disp.Size() != size) { + opserr << "OPS_GetNodeDisp - crd size mismatch\n"; + return -1; + } + for (int i = 0; i < size; i++) + data[i] = disp(i); + + return 0; +} + +extern "C" +int OPS_GetNodeVel(int* nodeTag, int* sizeData, double* data) { - theInterp = interp; - theDomain = domain; - theModelBuilder = builder; - currentArgv = argv; - currentArg = 2; - maxArg = argc; - - // get the current load factor - double time = theDomain->getCurrentTime(); - double dt = theDomain->getCurrentTime() - time; - - static modelState theModelState; - theModelState.time = time; - theModelState.dt = dt; - - // invoke the ele function with isw = 0 - int isw = ISW_INIT; - int result = 0; - theEle->eleFunctPtr(theEle, &theModelState, 0, 0, &isw, &result); - - if (result != 0) { - opserr << "Tcl_addWrapperElement - failed in element function " << result << endln; - return TCL_ERROR; - } + Node* theNode = theDomain->getNode(*nodeTag); - WrapperElement *theElement = new WrapperElement(argv[1], theEle); + if (theNode == 0) { + opserr << "OPS_GetNodeVel - no node with tag " << *nodeTag << endln; + return -1; + } + int size = *sizeData; + const Vector& vel = theNode->getTrialVel(); - if (theDomain->addElement(theElement) == false) { - opserr << "WARNING could not add element of type: " << argv[1] << " to the domain\n"; - delete theElement; - return TCL_ERROR; - } + if (vel.Size() != size) { + opserr << "OPS_GetNodeVel - crd size mismatch\n"; + return -1; + } + for (int i = 0; i < size; i++) + data[i] = vel(i); - return 0; + return 0; } - -UniaxialMaterial * -Tcl_addWrapperUniaxialMaterial(matObj *theMat, ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +extern "C" +int OPS_GetNodeAccel(int* nodeTag, int* sizeData, double* data) { - theInterp = interp; + Node* theNode = theDomain->getNode(*nodeTag); - currentArgv = argv; - currentArg = 2; - maxArg = argc; + if (theNode == 0) { + opserr << "OPS_GetNodeAccel - no node with tag " << *nodeTag << endln; + return -1; + } + int size = *sizeData; + const Vector& accel = theNode->getTrialAccel(); - // get the current load factor - static modelState theModelState; - if (theDomain != 0) { - double time = theDomain->getCurrentTime(); - double dt = theDomain->getCurrentTime() - time; - theModelState.time = time; - theModelState.dt = dt; - } + if (accel.Size() != size) { + opserr << "OPS_GetNodeAccel - accel size mismatch\n"; + return -1; + } + for (int i = 0; i < size; i++) + data[i] = accel(i); + return 0; +} - // invoke the mat function with isw = 0 - int isw = ISW_INIT; - int result = 0; - theMat->matFunctPtr(theMat, &theModelState, 0, 0, 0, &isw, &result); - int matType = theMat->matType; // GR added to support material +extern "C" +int OPS_GetNodeIncrDisp(int* nodeTag, int* sizeData, double* data) +{ + Node* theNode = theDomain->getNode(*nodeTag); - if (result != 0 || matType != OPS_UNIAXIAL_MATERIAL_TYPE) { - opserr << "Tcl_addWrapperUniaxialMaterial - failed in element function " << result << endln; - return 0; - } + if (theNode == 0) { + opserr << "OPS_GetNodeIncrDisp - no node with tag " << *nodeTag << endln; + return -1; + } + int size = *sizeData; + const Vector& disp = theNode->getIncrDisp(); - WrapperUniaxialMaterial*theMaterial = new WrapperUniaxialMaterial(argv[1], theMat); + if (disp.Size() != size) { + opserr << "OPS_GetNodeIncrDis - crd size mismatch\n"; + return -1; + } + for (int i = 0; i < size; i++) + data[i] = disp(i); - return theMaterial; + return 0; } -NDMaterial * -Tcl_addWrapperNDMaterial(matObj *theMat, ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv, TclModelBuilder *builder) +extern "C" +int OPS_GetNodeIncrDeltaDisp(int* nodeTag, int* sizeData, double* data) { - theInterp = interp; + Node* theNode = theDomain->getNode(*nodeTag); + + if (theNode == 0) { + opserr << "OPS_GetNodeIncrDeltaDisp - no node with tag " << *nodeTag << endln; + return -1; + } + int size = *sizeData; + const Vector& disp = theNode->getIncrDeltaDisp(); - theModelBuilder = builder; - currentArgv = argv; - currentArg = 2; - maxArg = argc; + if (disp.Size() != size) { + opserr << "OPS_GetNodeIncrDis - crd size mismatch\n"; + return -1; + } + for (int i = 0; i < size; i++) + data[i] = disp(i); + + return 0; +} - // get the current load factor - static modelState theModelState; - if (theDomain != 0) { +int +Tcl_addWrapperElement(eleObj* theEle, ClientData clientData, Tcl_Interp* interp, int argc, + TCL_Char** argv, Domain* domain, TclModelBuilder* builder) +{ + theInterp = interp; + theDomain = domain; + theModelBuilder = builder; + currentArgv = argv; + currentArg = 2; + maxArg = argc; + + // get the current load factor double time = theDomain->getCurrentTime(); double dt = theDomain->getCurrentTime() - time; + + static modelState theModelState; theModelState.time = time; theModelState.dt = dt; - } + // invoke the ele function with isw = 0 + int isw = ISW_INIT; + int result = 0; + theEle->eleFunctPtr(theEle, &theModelState, 0, 0, &isw, &result); - // invoke the mat function with isw = 0 - int isw = ISW_INIT; - int result = 0; - theMat->matFunctPtr(theMat, &theModelState, 0, 0, 0, &isw, &result); - int matType = theMat->matType; // GR added to support material + if (result != 0) { + opserr << "Tcl_addWrapperElement - failed in element function " << result << endln; + return TCL_ERROR; + } - if (result != 0 || (matType != OPS_PLANESTRESS_TYPE && - matType != OPS_PLANESTRAIN_TYPE && - matType != OPS_THREEDIMENSIONAL_TYPE) ) { - opserr << "Tcl_addWrapperNDMaterial - failed in element function " << result << endln; - return 0; - } + WrapperElement* theElement = new WrapperElement(argv[1], theEle); - WrapperNDMaterial*theMaterial = new WrapperNDMaterial(argv[1], theMat, theMat->matType); + if (theDomain->addElement(theElement) == false) { + opserr << "WARNING could not add element of type: " << argv[1] << " to the domain\n"; + delete theElement; + return TCL_ERROR; + } - return theMaterial; + return 0; } - -//MRL start -LimitCurve * -Tcl_addWrapperLimitCurve(limCrvObj *theLimCrv, ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) - +UniaxialMaterial* +Tcl_addWrapperUniaxialMaterial(matObj* theMat, ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) { - theInterp = interp; + theInterp = interp; + + currentArgv = argv; + currentArg = 2; + maxArg = argc; + + // get the current load factor + static modelState theModelState; + if (theDomain != 0) { + double time = theDomain->getCurrentTime(); + double dt = theDomain->getCurrentTime() - time; + theModelState.time = time; + theModelState.dt = dt; + } - // theModelBuilder = builder; - currentArgv = argv; - currentArg = 2; - maxArg = argc; + // invoke the mat function with isw = 0 + int isw = ISW_INIT; + int result = 0; + theMat->matFunctPtr(theMat, &theModelState, 0, 0, 0, &isw, &result); + int matType = theMat->matType; // GR added to support material - // get the current load factor - static modelState theModelState; - if (theDomain != 0) { - double time = theDomain->getCurrentTime(); - double dt = theDomain->getCurrentTime() - time; - theModelState.time = time; - theModelState.dt = dt; - } + if (result != 0 || matType != OPS_UNIAXIAL_MATERIAL_TYPE) { + opserr << "Tcl_addWrapperUniaxialMaterial - failed in element function " << result << endln; + return 0; + } + WrapperUniaxialMaterial* theMaterial = new WrapperUniaxialMaterial(argv[1], theMat); - // invoke the limit curve function with isw = 0 - int isw = ISW_INIT; - int result; - theLimCrv->limCrvFunctPtr(theLimCrv, &theModelState, 0, 0, 0, &isw, &result); + return theMaterial; +} - if (result != 0) { - opserr << "Tcl_addWrapperLimitCurve - failed in limit curve function " << result << endln; - return 0; - } +NDMaterial* +Tcl_addWrapperNDMaterial(matObj* theMat, ClientData clientData, Tcl_Interp* interp, int argc, + TCL_Char** argv, TclModelBuilder* builder) +{ + theInterp = interp; + + theModelBuilder = builder; + currentArgv = argv; + currentArg = 2; + maxArg = argc; + + // get the current load factor + static modelState theModelState; + if (theDomain != 0) { + double time = theDomain->getCurrentTime(); + double dt = theDomain->getCurrentTime() - time; + theModelState.time = time; + theModelState.dt = dt; + } - WrapperLimitCurve*theLimitCurve = new WrapperLimitCurve(argv[1], theLimCrv); + // invoke the mat function with isw = 0 + int isw = ISW_INIT; + int result = 0; + theMat->matFunctPtr(theMat, &theModelState, 0, 0, 0, &isw, &result); + int matType = theMat->matType; // GR added to support material + + if (result != 0 || (matType != OPS_PLANESTRESS_TYPE && + matType != OPS_PLANESTRAIN_TYPE && + matType != OPS_THREEDIMENSIONAL_TYPE)) { + opserr << "Tcl_addWrapperNDMaterial - failed in element function " << result << endln; + return 0; + } - return theLimitCurve; + WrapperNDMaterial* theMaterial = new WrapperNDMaterial(argv[1], theMat, theMat->matType); + + return theMaterial; } -//MRL end -extern "C" int -OPS_InvokeMaterial(eleObject *theEle, int *mat, modelState *model, double *strain, double *stress, double *tang, int *isw) +LimitCurve* +Tcl_addWrapperLimitCurve(limCrvObj* theLimCrv, ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) { - int error =0; + theInterp = interp; + + // theModelBuilder = builder; + currentArgv = argv; + currentArg = 2; + maxArg = argc; + + // get the current load factor + static modelState theModelState; + if (theDomain != 0) { + double time = theDomain->getCurrentTime(); + double dt = theDomain->getCurrentTime() - time; + theModelState.time = time; + theModelState.dt = dt; + } - matObject *theMat = theEle->mats[*mat]; - /* fprintf(stderr,"invokeMaterial Address %d %d %d\n",*mat, theMat, sizeof(int)); */ + // invoke the limit curve function with isw = 0 + int isw = ISW_INIT; + int result; + theLimCrv->limCrvFunctPtr(theLimCrv, &theModelState, 0, 0, 0, &isw, &result); - if (theMat != 0) - theMat->matFunctPtr(theMat, model, strain, tang, stress, isw, &error); - else - error = -1; + if (result != 0) { + opserr << "Tcl_addWrapperLimitCurve - failed in limit curve function " << result << endln; + return 0; + } + WrapperLimitCurve* theLimitCurve = new WrapperLimitCurve(argv[1], theLimCrv); - return error; + return theLimitCurve; } -extern "C" int -OPS_InvokeMaterialDirectly(matObject **theMat, modelState *model, double *strain, double *stress, double *tang, int *isw) +extern "C" int +OPS_InvokeMaterial(eleObject * theEle, int* mat, modelState * model, double* strain, double* stress, double* tang, int* isw) { - int error =0; - // fprintf(stderr,"invokeMaterialDirectly Address %d %d %d\n",theMat, sizeof(int), *theMat); - if (*theMat != 0) - (*theMat)->matFunctPtr(*theMat, model, strain, tang, stress, isw, &error); - else - error = -1; + int error = 0; + + matObject* theMat = theEle->mats[*mat]; + /* fprintf(stderr,"invokeMaterial Address %d %d %d\n",*mat, theMat, sizeof(int)); */ + + if (theMat != 0) + theMat->matFunctPtr(theMat, model, strain, tang, stress, isw, &error); + else + error = -1; + + return error; +} +extern "C" int +OPS_InvokeMaterialDirectly(matObject * *theMat, modelState * model, double* strain, double* stress, double* tang, int* isw) +{ + int error = 0; + // fprintf(stderr,"invokeMaterialDirectly Address %d %d %d\n",theMat, sizeof(int), *theMat); + if (*theMat != 0) + (*theMat)->matFunctPtr(*theMat, model, strain, tang, stress, isw, &error); + else + error = -1; - return error; + return error; } -extern "C" int -OPS_InvokeMaterialDirectly2(matObject *theMat, modelState *model, double *strain, double *stress, double *tang, int *isw) +extern "C" int +OPS_InvokeMaterialDirectly2(matObject * theMat, modelState * model, double* strain, double* stress, double* tang, int* isw) { - int error =0; - // fprintf(stderr,"invokeMaterialDirectly Address %d %d\n",theMat, sizeof(int)); - if (theMat != 0) - theMat->matFunctPtr(theMat, model, strain, tang, stress, isw, &error); - else - error = -1; - - return error; + int error = 0; + // fprintf(stderr,"invokeMaterialDirectly Address %d %d\n",theMat, sizeof(int)); + if (theMat != 0) + theMat->matFunctPtr(theMat, model, strain, tang, stress, isw, &error); + else + error = -1; + + return error; } -UniaxialMaterial * +UniaxialMaterial* OPS_GetUniaxialMaterial(int matTag) { - return OPS_getUniaxialMaterial(matTag); + return OPS_getUniaxialMaterial(matTag); } -NDMaterial * +NDMaterial* OPS_GetNDMaterial(int matTag) { - return OPS_getNDMaterial(matTag); + return OPS_getNDMaterial(matTag); } -SectionForceDeformation * +SectionForceDeformation* OPS_GetSectionForceDeformation(int secTag) { - return OPS_getSectionForceDeformation(secTag); + return OPS_getSectionForceDeformation(secTag); } -CrdTransf * +CrdTransf* OPS_GetCrdTransf(int crdTag) { - return OPS_getCrdTransf(crdTag); + return OPS_getCrdTransf(crdTag); } -FrictionModel * +FrictionModel* OPS_GetFrictionModel(int frnTag) { - return OPS_getFrictionModel(frnTag); + return OPS_getFrictionModel(frnTag); } int -OPS_ResetInput(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain, - TclModelBuilder *builder) +OPS_GetNDF() { - theInterp = interp; - theDomain = domain; - theModelBuilder = builder; - currentArgv = argv; - currentArg = cArg; - maxArg = mArg; - - return 0; + return theModelBuilder->getNDF(); } int -OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain) +OPS_GetNDM() { - theInterp = interp; - theDomain = domain; - currentArgv = argv; - currentArg = cArg; - maxArg = mArg; - - return 0; + return theModelBuilder->getNDM(); } -int -OPS_GetNDF() +FE_Datastore* +OPS_GetFEDatastore() { - return theModelBuilder->getNDF(); + return theDatabase; } -int -OPS_GetNDM() +const char* +OPS_GetInterpPWD() { - return theModelBuilder->getNDM(); + return getInterpPWD(theInterp); } -FE_Datastore *OPS_GetFEDatastore() +Domain* +OPS_GetDomain(void) { - return theDatabase; + return theDomain; } -const char *OPS_GetInterpPWD() +void +TCL_OPS_setModelBuilder(TclModelBuilder* theNewBuilder) { - return getInterpPWD(theInterp); + theModelBuilder = theNewBuilder; } -Domain *OPS_GetDomain(void) +LimitCurve* +OPS_GetLimitCurve(int LimCrvTag) { - return theDomain; -} - -void TCL_OPS_setModelBuilder(TclModelBuilder *theNewBuilder) { - theModelBuilder = theNewBuilder; + return OPS_getLimitCurve(LimCrvTag); } -//////////start MRL -LimitCurve * -OPS_GetLimitCurve(int LimCrvTag) { - return OPS_getLimitCurve(LimCrvTag); -} -/////////end MRL - -AnalysisModel **OPS_GetAnalysisModel(void) +AnalysisModel** +OPS_GetAnalysisModel(void) { - return &theAnalysisModel; + return &theAnalysisModel; } -EquiSolnAlgo **OPS_GetAlgorithm(void) +EquiSolnAlgo** +OPS_GetAlgorithm(void) { - return &theAlgorithm; + return &theAlgorithm; } -ConstraintHandler **OPS_GetHandler(void) +ConstraintHandler** +OPS_GetHandler(void) { - return &theHandler; + return &theHandler; } -DOF_Numberer **OPS_GetNumberer(void) +DOF_Numberer** +OPS_GetNumberer(void) { - return &theNumberer; + return &theNumberer; } -LinearSOE **OPS_GetSOE(void) +LinearSOE** +OPS_GetSOE(void) { - return &theSOE; + return &theSOE; } -EigenSOE **OPS_GetEigenSOE(void) +EigenSOE** +OPS_GetEigenSOE(void) { - return &theEigenSOE; + return &theEigenSOE; } -StaticAnalysis **OPS_GetStaticAnalysis(void) +StaticAnalysis** +OPS_GetStaticAnalysis(void) { - return &theStaticAnalysis; + return &theStaticAnalysis; } -DirectIntegrationAnalysis **OPS_GetTransientAnalysis(void) +DirectIntegrationAnalysis** +OPS_GetTransientAnalysis(void) { - return &theTransientAnalysis; + return &theTransientAnalysis; } -VariableTimeStepDirectIntegrationAnalysis **OPS_GetVariableTimeStepTransientAnalysis(void) +VariableTimeStepDirectIntegrationAnalysis** +OPS_GetVariableTimeStepTransientAnalysis(void) { - return &theVariableTimeStepTransientAnalysis; + return &theVariableTimeStepTransientAnalysis; } -int *OPS_GetNumEigen(void) +int* +OPS_GetNumEigen(void) { - return &numEigen; + return &numEigen; } -StaticIntegrator **OPS_GetStaticIntegrator(void) +StaticIntegrator** +OPS_GetStaticIntegrator(void) { - return &theStaticIntegrator; + return &theStaticIntegrator; } -TransientIntegrator **OPS_GetTransientIntegrator(void) +TransientIntegrator** +OPS_GetTransientIntegrator(void) { - return &theTransientIntegrator; + return &theTransientIntegrator; } -ConvergenceTest **OPS_GetTest(void) +ConvergenceTest** +OPS_GetTest(void) { - return &theTest; + return &theTest; } -bool *OPS_builtModel(void) +bool* +OPS_builtModel(void) { - return &builtModel; + return &builtModel; } -int OPS_numIter() +int +OPS_numIter() { return 0; } diff --git a/SRC/api/packages.cpp b/SRC/api/packages.cpp index 1517ea82b0..0482c5306c 100644 --- a/SRC/api/packages.cpp +++ b/SRC/api/packages.cpp @@ -17,327 +17,336 @@ ** ** ** ****************************************************************** */ -/* +/* ** $Revision: 1.13 $ ** $Date: 2009-10-02 22:20:35 $ ** $Source: /usr/local/cvs/OpenSees/SRC/api/packages.cpp,v $ - -** Written: fmk -*/ + +** Written: fmk +*/ #include #include #include +#include +#include #include #include - - extern #ifdef _WIN32 int __cdecl #else int #endif -httpGET_File(char const *URL, char const *page, unsigned int port, const char *filename); +httpGET_File(char const* URL, char const* page, unsigned int port, const char* filename); #ifdef _WIN32 #include #include -extern SimulationInformation *theSimulationInfoPtr; +extern SimulationInformation* theSimulationInfoPtr; #else #include #endif -int -getLibraryFunction(const char *libName, const char *funcName, void **libHandle, void **funcHandle) { +int +getLibraryFunction(const char* libName, const char* funcName, void** libHandle, void** funcHandle) { + + int result = 0; - int result = 0; - - *libHandle = NULL; - *funcHandle = NULL; + *libHandle = NULL; + *funcHandle = NULL; - struct stat stFileInfo; - bool blnReturn; - int intStat; + //struct stat stFileInfo; + //bool blnReturn; + //int intStat; - #ifdef _WIN32 - - // - // first try and open dll - // - - int libNameLength = (int)strlen(libName); - char *localLibName = new char[libNameLength+5]; - strcpy(localLibName, libName); - strcpy(&localLibName[libNameLength], ".dll"); - - HINSTANCE hLib = LoadLibrary(localLibName); - - delete [] localLibName; - - if (hLib != NULL) { - - char mod[124]; - GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, 124); - + // - // Now look for function with funcName + // first try and open dll // - - (*funcHandle) = (void *)GetProcAddress((HMODULE)hLib, funcName); - - if (*funcHandle == NULL) { - char *underscoreFunctionName = new char[strlen(funcName)+2]; - strcpy(underscoreFunctionName, funcName); - strcpy(&underscoreFunctionName[strlen(funcName)], "_"); - (*funcHandle) = (void *)GetProcAddress((HMODULE)hLib, underscoreFunctionName); - delete [] underscoreFunctionName; - } - - if (*funcHandle == NULL) { - FreeLibrary((HMODULE)hLib); - return -2; - } + int libNameLength = (int)strlen(libName); + char* localLibName = new char[libNameLength + 5]; + strcpy(localLibName, libName); + strcpy(&localLibName[libNameLength], ".dll"); - // - // we need to set the OpenSees pointer global variables if function there - // + HINSTANCE hLib = LoadLibrary(localLibName); + + delete[] localLibName; + + if (hLib != NULL) { + + char mod[124]; + GetModuleFileName((HMODULE)hLib, (LPTSTR)mod, 124); + + // + // Now look for function with funcName + // + + (*funcHandle) = (void*)GetProcAddress((HMODULE)hLib, funcName); + + if (*funcHandle == NULL) { + char* underscoreFunctionName = new char[strlen(funcName) + 2]; + strcpy(underscoreFunctionName, funcName); + strcpy(&underscoreFunctionName[strlen(funcName)], "_"); + (*funcHandle) = (void*)GetProcAddress((HMODULE)hLib, underscoreFunctionName); + delete[] underscoreFunctionName; + } + + + if (*funcHandle == NULL) { + FreeLibrary((HMODULE)hLib); + return -2; + } + + // + // we need to set the OpenSees pointer global variables if function there + // + + typedef int(_cdecl* LocalInitPtrType)(); + typedef int(_cdecl* OPS_ErrorPtrType)(char*, int); + typedef int(_cdecl* OPS_GetNumRemainingInputArgsType)(); + typedef int(_cdecl* OPS_ResetCurrentInputArgType)(int); + //typedef int(_cdecl* OPS_ResetInputType)(ClientData, Tcl_Interp*, int, int, TCL_Char**, Domain*, TclModelBuilder*); + typedef int(_cdecl* OPS_ResetInputNoBuilderType)(ClientData, Tcl_Interp*, int, int, TCL_Char**, Domain*); + typedef int(_cdecl* OPS_GetIntInputPtrType)(int*, int*); + typedef int(_cdecl* OPS_GetDoubleInputPtrType)(int*, double*); + typedef const char* (_cdecl* OPS_GetStringType)(); + typedef int(_cdecl* OPS_GetStringCopyType)(char**); + typedef int(_cdecl* OPS_AllocateElementPtrType)(eleObj*, int*, int*); + typedef int(_cdecl* OPS_AllocateMaterialPtrType)(matObj*); + typedef UniaxialMaterial* (*OPS_GetUniaxialMaterialPtrType)(int); + typedef NDMaterial* (*OPS_GetNDMaterialPtrType)(int); + typedef SectionForceDeformation* (*OPS_GetSectionForceDeformationPtrType)(int); + typedef CrdTransf* (*OPS_GetCrdTransfPtrType)(int); + typedef FrictionModel* (*OPS_GetFrictionModelPtrType)(int); + typedef int(_cdecl* OPS_GetNodeInfoPtrType)(int*, int*, double*); + typedef int(_cdecl* OPS_InvokeMaterialDirectlyPtrType)(matObject**, modelState*, double*, double*, double*, int*); + typedef int(_cdecl* OPS_GetIntPtrType)(); + + typedef FE_Datastore* (*OPS_GetFEDatastorePtrType)(); + typedef const char* (_cdecl* OPS_GetInterpPWD_PtrType)(); + + typedef Domain* (*OPS_GetDomainPointerType)(); + typedef AnalysisModel** (*OPS_GetAnalysisModelPtrType)(); + typedef EquiSolnAlgo** (*OPS_GetAlgorithmPtrType)(); + typedef ConstraintHandler** (*OPS_GetHandlerPtrType)(); + typedef DOF_Numberer** (*OPS_GetNumbererPtrType)(); + typedef LinearSOE** (*OPS_GetSOEPtrType)(); + typedef EigenSOE** (*OPS_GetEigenSOEPtrType)(); + typedef StaticAnalysis** (*OPS_GetStaticAnalysisPtrType)(); + typedef DirectIntegrationAnalysis** (*OPS_GetTransientAnalysisPtrType)(); + typedef VariableTimeStepDirectIntegrationAnalysis** (*OPS_GetVariableTimeStepTransientAnalysisPtrType)(); + typedef int* (*OPS_GetNumEigenPtrType)(); + typedef StaticIntegrator** (*OPS_GetStaticIntegratorPtrType)(); + typedef TransientIntegrator** (*OPS_GetTransientIntegratorPtrType)(); + typedef ConvergenceTest** (*OPS_GetTestPtrType)(); + typedef bool* (*OPS_builtModelPtrType)(); + + typedef void(_cdecl* setGlobalPointersFunction)( + OPS_Stream*, + Domain*, + SimulationInformation*, + OPS_ErrorPtrType, + OPS_GetIntInputPtrType, + OPS_GetDoubleInputPtrType, + OPS_AllocateElementPtrType, + OPS_AllocateMaterialPtrType, + OPS_GetUniaxialMaterialPtrType, + OPS_GetNDMaterialPtrType, + OPS_GetSectionForceDeformationPtrType, + OPS_GetCrdTransfPtrType, + OPS_GetFrictionModelPtrType, + OPS_InvokeMaterialDirectlyPtrType, + OPS_GetNodeInfoPtrType, + OPS_GetNodeInfoPtrType, + OPS_GetNodeInfoPtrType, + OPS_GetNodeInfoPtrType, + OPS_GetNodeInfoPtrType, + OPS_GetNodeInfoPtrType, + OPS_GetNumRemainingInputArgsType, + OPS_ResetCurrentInputArgType, + //OPS_ResetInputType, + OPS_ResetInputNoBuilderType, + OPS_GetStringType, + OPS_GetStringCopyType, + OPS_GetIntPtrType, + OPS_GetIntPtrType, + OPS_GetFEDatastorePtrType, + OPS_GetInterpPWD_PtrType, + OPS_GetAnalysisModelPtrType, + OPS_GetAlgorithmPtrType, + OPS_GetHandlerPtrType, + OPS_GetNumbererPtrType, + OPS_GetSOEPtrType, + OPS_GetEigenSOEPtrType, + OPS_GetStaticAnalysisPtrType, + OPS_GetTransientAnalysisPtrType, + OPS_GetVariableTimeStepTransientAnalysisPtrType, + OPS_GetNumEigenPtrType, + OPS_GetStaticIntegratorPtrType, + OPS_GetTransientIntegratorPtrType, + OPS_GetTestPtrType, + OPS_builtModelPtrType, + OPS_GetDomainPointerType); + + setGlobalPointersFunction funcPtr; + + // look for pointer function + funcPtr = (setGlobalPointersFunction)GetProcAddress((HMODULE)hLib, "setGlobalPointers"); + if (funcPtr == 0) { + FreeLibrary((HMODULE)hLib); + return -2; + } + + // invoke pointer function + (funcPtr)(opserrPtr, + ops_TheActiveDomain, + theSimulationInfoPtr, + OPS_Error, + OPS_GetIntInput, + OPS_GetDoubleInput, + OPS_AllocateElement, + OPS_AllocateMaterial, + OPS_GetUniaxialMaterial, + OPS_GetNDMaterial, + OPS_GetSectionForceDeformation, + OPS_GetCrdTransf, + OPS_GetFrictionModel, + OPS_InvokeMaterialDirectly, + OPS_GetNodeCrd, + OPS_GetNodeDisp, + OPS_GetNodeVel, + OPS_GetNodeAccel, + OPS_GetNodeIncrDisp, + OPS_GetNodeIncrDeltaDisp, + OPS_GetNumRemainingInputArgs, + OPS_ResetCurrentInputArg, + //OPS_ResetInput, + OPS_ResetInputNoBuilder, + OPS_GetString, + OPS_GetStringCopy, + OPS_GetNDM, + OPS_GetNDF, + OPS_GetFEDatastore, + OPS_GetInterpPWD, + OPS_GetAnalysisModel, + OPS_GetAlgorithm, + OPS_GetHandler, + OPS_GetNumberer, + OPS_GetSOE, + OPS_GetEigenSOE, + OPS_GetStaticAnalysis, + OPS_GetTransientAnalysis, + OPS_GetVariableTimeStepTransientAnalysis, + OPS_GetNumEigen, + OPS_GetStaticIntegrator, + OPS_GetTransientIntegrator, + OPS_GetTest, + OPS_builtModel, + OPS_GetDomain); + + LocalInitPtrType initPtr; + initPtr = (LocalInitPtrType)GetProcAddress((HMODULE)hLib, "localInit"); + if (initPtr != 0) { + initPtr(); + } + else { + initPtr = (LocalInitPtrType)GetProcAddress((HMODULE)hLib, "localinit_"); + if (initPtr != 0) { + initPtr(); + } + } - typedef int (_cdecl *LocalInitPtrType)(); - typedef int (_cdecl *OPS_ErrorPtrType)(char *, int); - typedef int (_cdecl *OPS_GetNumRemainingInputArgsType)(); - typedef int (_cdecl *OPS_ResetCurrentInputArgType)(int); - typedef int (_cdecl *OPS_GetIntInputPtrType)(int *, int *); - typedef int (_cdecl *OPS_GetDoubleInputPtrType)(int *, double *); - typedef const char *(_cdecl *OPS_GetStringType)(); - typedef int (_cdecl *OPS_GetStringCopyType)(char **); - typedef int (_cdecl *OPS_AllocateElementPtrType)(eleObj *, int *matTags, int *maType); - typedef int (_cdecl *OPS_AllocateMaterialPtrType)(matObj *); - typedef UniaxialMaterial *(*OPS_GetUniaxialMaterialPtrType)(int matTag); - typedef NDMaterial *(*OPS_GetNDMaterialPtrType)(int matTag); - typedef SectionForceDeformation *(*OPS_GetSectionForceDeformationPtrType)(int secTag); - typedef CrdTransf *(*OPS_GetCrdTransfPtrType)(int crdTag); - typedef FrictionModel *(*OPS_GetFrictionModelPtrType)(int frnTag); - typedef int (_cdecl *OPS_GetNodeInfoPtrType)(int *, int *, double *); - typedef int (_cdecl *OPS_InvokeMaterialDirectlyPtrType)(matObject **, modelState *, double *, double *, double *, int *); - typedef int (_cdecl *OPS_GetIntPtrType)(); - - typedef FE_Datastore *(*OPS_GetFEDatastorePtrType)(); - typedef const char *(_cdecl *OPS_GetInterpPWD_PtrType)(); - - typedef AnalysisModel **(*OPS_GetAnalysisModelPtrType)(void); - typedef EquiSolnAlgo **(*OPS_GetAlgorithmPtrType)(void); - typedef ConstraintHandler **(*OPS_GetHandlerPtrType)(void); - typedef DOF_Numberer **(*OPS_GetNumbererPtrType)(void); - typedef LinearSOE **(*OPS_GetSOEPtrType)(void); - typedef EigenSOE **(*OPS_GetEigenSOEPtrType)(void); - typedef StaticAnalysis **(*OPS_GetStaticAnalysisPtrType)(void); - typedef DirectIntegrationAnalysis **(*OPS_GetTransientAnalysisPtrType)(void); - typedef VariableTimeStepDirectIntegrationAnalysis **(*OPS_GetVariableTimeStepTransientAnalysisPtrType)(void); - typedef int *(*OPS_GetNumEigenPtrType)(void); - typedef StaticIntegrator **(*OPS_GetStaticIntegratorPtrType)(void); - typedef TransientIntegrator **(*OPS_GetTransientIntegratorPtrType)(void); - typedef ConvergenceTest **(*OPS_GetTestPtrType)(void); - typedef bool *(*OPS_builtModelPtrType)(void); - typedef Domain *(*OPS_GetDomainPointerType)(void); - - typedef void (_cdecl *setGlobalPointersFunction)(OPS_Stream *, - Domain *, - SimulationInformation *, - OPS_ErrorPtrType, - OPS_GetIntInputPtrType, - OPS_GetDoubleInputPtrType, - OPS_AllocateElementPtrType, - OPS_AllocateMaterialPtrType, - OPS_GetUniaxialMaterialPtrType, - OPS_GetNDMaterialPtrType, - OPS_GetSectionForceDeformationPtrType, - OPS_GetCrdTransfPtrType, - OPS_GetFrictionModelPtrType, - OPS_InvokeMaterialDirectlyPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNodeInfoPtrType, - OPS_GetNumRemainingInputArgsType, - OPS_ResetCurrentInputArgType, - OPS_GetStringType, - OPS_GetStringCopyType, - OPS_GetIntPtrType, - OPS_GetIntPtrType, - OPS_GetFEDatastorePtrType, - OPS_GetInterpPWD_PtrType, - OPS_GetAnalysisModelPtrType, - OPS_GetAlgorithmPtrType, - OPS_GetHandlerPtrType, - OPS_GetNumbererPtrType, - OPS_GetSOEPtrType, - OPS_GetEigenSOEPtrType, - OPS_GetStaticAnalysisPtrType, - OPS_GetTransientAnalysisPtrType, - OPS_GetVariableTimeStepTransientAnalysisPtrType, - OPS_GetNumEigenPtrType, - OPS_GetStaticIntegratorPtrType, - OPS_GetTransientIntegratorPtrType, - OPS_GetTestPtrType, - OPS_builtModelPtrType, - OPS_GetDomainPointerType); - - setGlobalPointersFunction funcPtr; - - // look for pointer function - funcPtr = (setGlobalPointersFunction)GetProcAddress((HMODULE)hLib,"setGlobalPointers"); - if (funcPtr == 0) { - FreeLibrary((HMODULE)hLib); - return -2; } - - // invoke pointer function - (funcPtr)(opserrPtr, - ops_TheActiveDomain, - theSimulationInfoPtr, - OPS_Error, - OPS_GetIntInput, - OPS_GetDoubleInput, - OPS_AllocateElement, - OPS_AllocateMaterial, - OPS_GetUniaxialMaterial, - OPS_GetNDMaterial, - OPS_GetSectionForceDeformation, - OPS_GetCrdTransf, - OPS_GetFrictionModel, - OPS_InvokeMaterialDirectly, - OPS_GetNodeCrd, - OPS_GetNodeDisp, - OPS_GetNodeVel, - OPS_GetNodeAccel, - OPS_GetNodeIncrDisp, - OPS_GetNodeIncrDeltaDisp, - OPS_GetNumRemainingInputArgs, - OPS_ResetCurrentInputArg, - OPS_GetString, - OPS_GetStringCopy, - OPS_GetNDM, - OPS_GetNDF, - OPS_GetFEDatastore, - OPS_GetInterpPWD, - OPS_GetAnalysisModel, - OPS_GetAlgorithm, - OPS_GetHandler, - OPS_GetNumberer, - OPS_GetSOE, - OPS_GetEigenSOE, - OPS_GetStaticAnalysis, - OPS_GetTransientAnalysis, - OPS_GetVariableTimeStepTransientAnalysis, - OPS_GetNumEigen, - OPS_GetStaticIntegrator, - OPS_GetTransientIntegrator, - OPS_GetTest, - OPS_builtModel, - OPS_GetDomain); - - LocalInitPtrType initPtr; - initPtr = (LocalInitPtrType)GetProcAddress((HMODULE)hLib,"localInit"); - if (initPtr !=0) { - initPtr(); - } else { - initPtr = (LocalInitPtrType)GetProcAddress((HMODULE)hLib,"localinit_"); - if (initPtr !=0) { - initPtr(); - } - } - - } else // no lib exists - return -1; - - libHandle = (void **)&hLib; + else // no lib exists + return -1; + + libHandle = (void**)&hLib; #else - int libNameLength = strlen(libName); - char *localLibName = new char[libNameLength+10]; - strcpy(localLibName, libName); + int libNameLength = strlen(libName); + char* localLibName = new char[libNameLength + 10]; + strcpy(localLibName, libName); #ifdef _MACOSX - strcpy(&localLibName[libNameLength], ".dylib"); + strcpy(&localLibName[libNameLength], ".dylib"); #else - strcpy(&localLibName[libNameLength], ".so"); + strcpy(&localLibName[libNameLength], ".so"); #endif - // Attempt to get the file attributes - intStat = stat(localLibName, &stFileInfo); - /* get library - if(intStat != 0) { - opserr << "packages.cpp - NO FILE EXISTS: - trying OpenSees" << localLibName << endln; - int res = httpGET_File("opensees.berkeley.edu", localLibName, 80, localLibName); - if (res != 0) { - opserr << "packages.cpp - NO FILE EXISTS: " << localLibName << endln; - return -1; + // Attempt to get the file attributes + // intintStat = stat(localLibName, &stFileInfo); + /* get library + if(intStat != 0) { + opserr << "packages.cpp - NO FILE EXISTS: - trying OpenSees" << localLibName << endln; + int res = httpGET_File("opensees.berkeley.edu", localLibName, 80, localLibName); + if (res != 0) { + opserr << "packages.cpp - NO FILE EXISTS: " << localLibName << endln; + return -1; + } + } + */ + char* error; + + *libHandle = dlopen(localLibName, RTLD_NOW); + + if (*libHandle == NULL) { + delete[] localLibName; + return -1; // no lib exists + } + + void* funcPtr = dlsym(*libHandle, funcName); + + error = dlerror(); + + // + // look for fortran procedure, trailing underscore + // + + if (funcPtr == NULL) { + int funcNameLength = strlen(funcName); + char* underscoreFunctionName = new char[funcNameLength + 2]; + strcpy(underscoreFunctionName, funcName); + strcpy(&underscoreFunctionName[funcNameLength], "_"); + strcpy(&underscoreFunctionName[funcNameLength + 1], ""); + funcPtr = dlsym(*libHandle, underscoreFunctionName); + delete[] underscoreFunctionName; } - } - */ - char *error; - - *libHandle = dlopen (localLibName, RTLD_NOW); - - if (*libHandle == NULL) { - delete [] localLibName; - return -1; // no lib exists - } - - void *funcPtr = dlsym(*libHandle, funcName); - - error = dlerror(); - - // - // look for fortran procedure, trailing underscore - // - - if (funcPtr == NULL ) { - int funcNameLength =strlen(funcName); - char *underscoreFunctionName = new char[funcNameLength+2]; - strcpy(underscoreFunctionName, funcName); - strcpy(&underscoreFunctionName[funcNameLength], "_"); - strcpy(&underscoreFunctionName[funcNameLength+1], ""); - funcPtr = dlsym(*libHandle, underscoreFunctionName); - delete [] underscoreFunctionName; - } - - if (funcPtr == NULL) { - dlclose(*libHandle); - delete [] localLibName; - return -1; - } - - - *funcHandle = funcPtr; - - typedef int (*localInitPtrType)(); - localInitPtrType initFunct; - funcPtr = dlsym(*libHandle, "localInit"); - - if (funcPtr != NULL ) { - initFunct = (localInitPtrType)funcPtr; - initFunct(); - } else { - funcPtr = dlsym(*libHandle, "localinit_"); - if (funcPtr != NULL ) { - initFunct = (localInitPtrType)funcPtr; - initFunct(); + + if (funcPtr == NULL) { + dlclose(*libHandle); + delete[] localLibName; + return -1; } - } - - delete [] localLibName; + + + *funcHandle = funcPtr; + + typedef int (*localInitPtrType)(); + localInitPtrType initFunct; + funcPtr = dlsym(*libHandle, "localInit"); + + if (funcPtr != NULL) { + initFunct = (localInitPtrType)funcPtr; + initFunct(); + } + else { + funcPtr = dlsym(*libHandle, "localinit_"); + if (funcPtr != NULL) { + initFunct = (localInitPtrType)funcPtr; + initFunct(); + } + } + + delete[] localLibName; #endif - return result; + return result; } diff --git a/SRC/api/win32Functions.cpp b/SRC/api/win32Functions.cpp index 8b0235c2d6..3d5f533233 100644 --- a/SRC/api/win32Functions.cpp +++ b/SRC/api/win32Functions.cpp @@ -1,64 +1,84 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +/* +** Written: fmk +*/ + #include #include - //#include //#include - #include - #include -//SimulationInformation simulationInfo; #define DllExport _declspec(dllexport) -BOOL APIENTRY DllMain(HANDLE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved) +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved) { return TRUE; } -OPS_Stream *opserrPtr = 0; -SimulationInformation *theSimulationInfo = 0; +OPS_Stream* opserrPtr = 0; +SimulationInformation* theSimulationInfo = 0; //Domain *ops_TheActiveDomain = 0; -//double ops_Dt = 0; -typedef int (*OPS_ErrorPtrType)(char *, int); -typedef int (*OPS_GetNumRemainingInputArgsType)(); -typedef int (*OPS_ResetCurrentInputArgType)(int); -typedef int (*OPS_GetIntInputPtrType)(int *, int *); -typedef int (*OPS_GetDoubleInputPtrType)(int *, double *); -typedef const char *(*OPS_GetStringType)(); -typedef int (*OPS_GetStringCopyType)(char **); -typedef int (*OPS_AllocateElementPtrType)(eleObj *, int *matTags, int *maType); -typedef int (*OPS_AllocateMaterialPtrType)(matObj *); -typedef UniaxialMaterial *(*OPS_GetUniaxialMaterialPtrType)(int matTag); -typedef NDMaterial *(*OPS_GetNDMaterialPtrType)(int matTag); -typedef SectionForceDeformation *(*OPS_GetSectionForceDeformationPtrType)(int secTag); -typedef CrdTransf *(*OPS_GetCrdTransfPtrType)(int crdTag); -typedef FrictionModel *(*OPS_GetFrictionModelPtrType)(int frnTag); -typedef int (*OPS_GetNodeInfoPtrType)(int *, int *, double *); -typedef int (*OPS_InvokeMaterialDirectlyPtrType)(matObject **, modelState *, double *, double *, double *, int *); -typedef int (*OPS_GetIntPtrType)(); -typedef FE_Datastore *(*OPS_GetFEDatastorePtrType)(); -typedef const char *(_cdecl *OPS_GetInterpPWD_PtrType)(); -typedef Domain *(*OPS_GetDomainPointer)(void); -typedef AnalysisModel **(*OPS_GetAnalysisModelPtrType)(void); -typedef EquiSolnAlgo **(*OPS_GetAlgorithmPtrType)(void); -typedef ConstraintHandler **(*OPS_GetHandlerPtrType)(void); -typedef DOF_Numberer **(*OPS_GetNumbererPtrType)(void); -typedef LinearSOE **(*OPS_GetSOEPtrType)(void); -typedef EigenSOE **(*OPS_GetEigenSOEPtrType)(void); -typedef StaticAnalysis **(*OPS_GetStaticAnalysisPtrType)(void); -typedef DirectIntegrationAnalysis **(*OPS_GetTransientAnalysisPtrType)(void); -typedef VariableTimeStepDirectIntegrationAnalysis **(*OPS_GetVariableTimeStepTransientAnalysisPtrType)(void); -typedef int *(*OPS_GetNumEigenPtrType)(void); -typedef StaticIntegrator **(*OPS_GetStaticIntegratorPtrType)(void); -typedef TransientIntegrator **(*OPS_GetTransientIntegratorPtrType)(void); -typedef ConvergenceTest **(*OPS_GetTestPtrType)(void); -typedef bool *(*OPS_builtModelPtrType)(void); - -//int OPS_InvokeMaterial(struct eleObj *, int *,modelState *, double *, double *, double *, int *); +typedef int(*OPS_ErrorPtrType)(char*, int); +typedef int(*OPS_GetNumRemainingInputArgsType)(); +typedef int(*OPS_ResetCurrentInputArgType)(int); +//typedef int (*OPS_ResetInputType)(ClientData, Tcl_Interp*, int, int, TCL_Char**, Domain*, TclModelBuilder*); +typedef int(*OPS_ResetInputNoBuilderType)(ClientData, Tcl_Interp*, int, int, TCL_Char**, Domain*); +typedef int(*OPS_GetIntInputPtrType)(int*, int*); +typedef int(*OPS_GetDoubleInputPtrType)(int*, double*); +typedef const char* (*OPS_GetStringType)(); +typedef int(*OPS_GetStringCopyType)(char**); +typedef int(*OPS_AllocateElementPtrType)(eleObj*, int*, int*); +typedef int(*OPS_AllocateMaterialPtrType)(matObj*); +typedef UniaxialMaterial* (*OPS_GetUniaxialMaterialPtrType)(int); +typedef NDMaterial* (*OPS_GetNDMaterialPtrType)(int); +typedef SectionForceDeformation* (*OPS_GetSectionForceDeformationPtrType)(int); +typedef CrdTransf* (*OPS_GetCrdTransfPtrType)(int); +typedef FrictionModel* (*OPS_GetFrictionModelPtrType)(int); +typedef int(*OPS_GetNodeInfoPtrType)(int*, int*, double*); +typedef int(*OPS_InvokeMaterialDirectlyPtrType)(matObject**, modelState*, double*, double*, double*, int*); +typedef int(*OPS_GetIntPtrType)(); + +typedef FE_Datastore* (*OPS_GetFEDatastorePtrType)(); +typedef const char* (_cdecl* OPS_GetInterpPWD_PtrType)(); + +typedef Domain* (*OPS_GetDomainPointer)(void); +typedef AnalysisModel** (*OPS_GetAnalysisModelPtrType)(void); +typedef EquiSolnAlgo** (*OPS_GetAlgorithmPtrType)(void); +typedef ConstraintHandler** (*OPS_GetHandlerPtrType)(void); +typedef DOF_Numberer** (*OPS_GetNumbererPtrType)(void); +typedef LinearSOE** (*OPS_GetSOEPtrType)(void); +typedef EigenSOE** (*OPS_GetEigenSOEPtrType)(void); +typedef StaticAnalysis** (*OPS_GetStaticAnalysisPtrType)(void); +typedef DirectIntegrationAnalysis** (*OPS_GetTransientAnalysisPtrType)(void); +typedef VariableTimeStepDirectIntegrationAnalysis** (*OPS_GetVariableTimeStepTransientAnalysisPtrType)(void); +typedef int* (*OPS_GetNumEigenPtrType)(void); +typedef StaticIntegrator** (*OPS_GetStaticIntegratorPtrType)(void); +typedef TransientIntegrator** (*OPS_GetTransientIntegratorPtrType)(void); +typedef ConvergenceTest** (*OPS_GetTestPtrType)(void); +typedef bool* (*OPS_builtModelPtrType)(void); OPS_ErrorPtrType OPS_ErrorPtr = 0; OPS_GetIntInputPtrType OPS_GetIntInputPtr = 0; @@ -79,73 +99,78 @@ OPS_GetNodeInfoPtrType OPS_GetNodeIncrDeltaDispPtr = 0; OPS_InvokeMaterialDirectlyPtrType OPS_InvokeMaterialDirectlyPtr = 0; OPS_GetNumRemainingInputArgsType OPS_GetNumRemainingInputArgsPtr = 0; OPS_ResetCurrentInputArgType OPS_ResetCurrentInputArgPtr = 0; +//OPS_ResetInputType OPS_ResetInputPtr = 0; +OPS_ResetInputNoBuilderType OPS_ResetInputNoBuilderPtr = 0; OPS_GetStringType OPS_GetStringPtr = 0; OPS_GetStringCopyType OPS_GetStringCopyPtr = 0; OPS_GetIntPtrType OPS_GetNDM_Ptr = 0; OPS_GetIntPtrType OPS_GetNDF_Ptr = 0; OPS_GetFEDatastorePtrType OPS_GetFEDatastorePtr = 0; OPS_GetInterpPWD_PtrType OPS_GetInterpPWD_Ptr = 0; -OPS_GetDomainPointer OPS_GetDomainPtr = 0; -OPS_GetAnalysisModelPtrType OPS_GetAnalysisModelPtr = 0; -OPS_GetAlgorithmPtrType OPS_GetAlgorithmPtr = 0; -OPS_GetHandlerPtrType OPS_GetHandlerPtr = 0; -OPS_GetNumbererPtrType OPS_GetNumbererPtr = 0; -OPS_GetSOEPtrType OPS_GetSOEPtr = 0; -OPS_GetEigenSOEPtrType OPS_GetEigenSOEPtr = 0; -OPS_GetStaticAnalysisPtrType OPS_GetStaticAnalysisPtr = 0; -OPS_GetTransientAnalysisPtrType OPS_GetTransientAnalysisPtr = 0; -OPS_GetVariableTimeStepTransientAnalysisPtrType OPS_GetVariableTimeStepTransientAnalysisPtr = 0; -OPS_GetNumEigenPtrType OPS_GetNumEigenPtr = 0; -OPS_GetStaticIntegratorPtrType OPS_GetStaticIntegratorPtr = 0; -OPS_GetTransientIntegratorPtrType OPS_GetTransientIntegratorPtr = 0; -OPS_GetTestPtrType OPS_GetTestPtr = 0; +OPS_GetDomainPointer OPS_GetDomainPtr = 0; +OPS_GetAnalysisModelPtrType OPS_GetAnalysisModelPtr = 0; +OPS_GetAlgorithmPtrType OPS_GetAlgorithmPtr = 0; +OPS_GetHandlerPtrType OPS_GetHandlerPtr = 0; +OPS_GetNumbererPtrType OPS_GetNumbererPtr = 0; +OPS_GetSOEPtrType OPS_GetSOEPtr = 0; +OPS_GetEigenSOEPtrType OPS_GetEigenSOEPtr = 0; +OPS_GetStaticAnalysisPtrType OPS_GetStaticAnalysisPtr = 0; +OPS_GetTransientAnalysisPtrType OPS_GetTransientAnalysisPtr = 0; +OPS_GetVariableTimeStepTransientAnalysisPtrType OPS_GetVariableTimeStepTransientAnalysisPtr = 0; +OPS_GetNumEigenPtrType OPS_GetNumEigenPtr = 0; +OPS_GetStaticIntegratorPtrType OPS_GetStaticIntegratorPtr = 0; +OPS_GetTransientIntegratorPtrType OPS_GetTransientIntegratorPtr = 0; +OPS_GetTestPtrType OPS_GetTestPtr = 0; OPS_builtModelPtrType OPS_builtModelPtr = 0; extern "C" DllExport -void setGlobalPointers(OPS_Stream *theErrorStreamPtr, - Domain *theDomain, - SimulationInformation *theSimulationInfoPtr, - OPS_ErrorPtrType errorFunct, - OPS_GetIntInputPtrType getIntInputFunct, - OPS_GetDoubleInputPtrType getDoubleInputFunct, - OPS_AllocateElementPtrType allocateElementFunct, - OPS_AllocateMaterialPtrType allocateMaterialFunct, - OPS_GetUniaxialMaterialPtrType OPS_GetUniaxialMaterialFunct, - OPS_GetNDMaterialPtrType OPS_GetNDMaterialFunct, - OPS_GetSectionForceDeformationPtrType OPS_GetSectionForceDeformationFunct, - OPS_GetCrdTransfPtrType OPS_GetCrdTransfFunct, - OPS_GetFrictionModelPtrType OPS_GetFrictionModelFunct, - OPS_InvokeMaterialDirectlyPtrType OPS_InvokeMaterialDirectlyFunct, - OPS_GetNodeInfoPtrType OPS_GetNodeCrdFunct, - OPS_GetNodeInfoPtrType OPS_GetNodeDispFunct, - OPS_GetNodeInfoPtrType OPS_GetNodeVelFunct, - OPS_GetNodeInfoPtrType OPS_GetNodeAccelFunct, - OPS_GetNodeInfoPtrType OPS_GetNodeIncrDispFunct, - OPS_GetNodeInfoPtrType OPS_GetNodeIncrDeltaDispFunct, - OPS_GetNumRemainingInputArgsType OPS_GetNumRemainingArgsFunct, - OPS_ResetCurrentInputArgType OPS_ResetCurrentInputArgFunct, - OPS_GetStringType OPS_GetStringFunct, - OPS_GetStringCopyType OPS_GetStringCopyFunct, - OPS_GetIntPtrType OPS_GetNDM_Funct, - OPS_GetIntPtrType OPS_GetNDF_Funct, - OPS_GetFEDatastorePtrType OPS_GetFEDatastoreFunct, - OPS_GetInterpPWD_PtrType OPS_GetInterpPWD_Funct, - OPS_GetAnalysisModelPtrType OPS_GetAnalysisModelFunct, - OPS_GetAlgorithmPtrType OPS_GetAlgorithmFunct, - OPS_GetHandlerPtrType OPS_GetHandlerFunct, - OPS_GetNumbererPtrType OPS_GetNumbererFunct, - OPS_GetSOEPtrType OPS_GetSOEFunct, - OPS_GetEigenSOEPtrType OPS_GetEigenSOEFunct, - OPS_GetStaticAnalysisPtrType OPS_GetStaticAnalysisFunct, - OPS_GetTransientAnalysisPtrType OPS_GetTransientAnalysisFunct, - OPS_GetVariableTimeStepTransientAnalysisPtrType OPS_GetVariableTimeStepTransientAnalysisFunct, - OPS_GetNumEigenPtrType OPS_GetNumEigenFunct, - OPS_GetStaticIntegratorPtrType OPS_GetStaticIntegratorFunct, - OPS_GetTransientIntegratorPtrType OPS_GetTransientIntegratorFunct, - OPS_GetTestPtrType OPS_GetTestFunct, - OPS_builtModelPtrType OPS_builtModelFunct, - OPS_GetDomainPointer OPS_getDomainPtr) +void setGlobalPointers( + OPS_Stream * theErrorStreamPtr, + Domain * theDomain, + SimulationInformation * theSimulationInfoPtr, + OPS_ErrorPtrType errorFunct, + OPS_GetIntInputPtrType getIntInputFunct, + OPS_GetDoubleInputPtrType getDoubleInputFunct, + OPS_AllocateElementPtrType allocateElementFunct, + OPS_AllocateMaterialPtrType allocateMaterialFunct, + OPS_GetUniaxialMaterialPtrType OPS_GetUniaxialMaterialFunct, + OPS_GetNDMaterialPtrType OPS_GetNDMaterialFunct, + OPS_GetSectionForceDeformationPtrType OPS_GetSectionForceDeformationFunct, + OPS_GetCrdTransfPtrType OPS_GetCrdTransfFunct, + OPS_GetFrictionModelPtrType OPS_GetFrictionModelFunct, + OPS_InvokeMaterialDirectlyPtrType OPS_InvokeMaterialDirectlyFunct, + OPS_GetNodeInfoPtrType OPS_GetNodeCrdFunct, + OPS_GetNodeInfoPtrType OPS_GetNodeDispFunct, + OPS_GetNodeInfoPtrType OPS_GetNodeVelFunct, + OPS_GetNodeInfoPtrType OPS_GetNodeAccelFunct, + OPS_GetNodeInfoPtrType OPS_GetNodeIncrDispFunct, + OPS_GetNodeInfoPtrType OPS_GetNodeIncrDeltaDispFunct, + OPS_GetNumRemainingInputArgsType OPS_GetNumRemainingArgsFunct, + OPS_ResetCurrentInputArgType OPS_ResetCurrentInputArgFunct, + //OPS_ResetInputType OPS_ResetInputFunct, + OPS_ResetInputNoBuilderType OPS_ResetInputNoBuilderFunct, + OPS_GetStringType OPS_GetStringFunct, + OPS_GetStringCopyType OPS_GetStringCopyFunct, + OPS_GetIntPtrType OPS_GetNDM_Funct, + OPS_GetIntPtrType OPS_GetNDF_Funct, + OPS_GetFEDatastorePtrType OPS_GetFEDatastoreFunct, + OPS_GetInterpPWD_PtrType OPS_GetInterpPWD_Funct, + OPS_GetAnalysisModelPtrType OPS_GetAnalysisModelFunct, + OPS_GetAlgorithmPtrType OPS_GetAlgorithmFunct, + OPS_GetHandlerPtrType OPS_GetHandlerFunct, + OPS_GetNumbererPtrType OPS_GetNumbererFunct, + OPS_GetSOEPtrType OPS_GetSOEFunct, + OPS_GetEigenSOEPtrType OPS_GetEigenSOEFunct, + OPS_GetStaticAnalysisPtrType OPS_GetStaticAnalysisFunct, + OPS_GetTransientAnalysisPtrType OPS_GetTransientAnalysisFunct, + OPS_GetVariableTimeStepTransientAnalysisPtrType OPS_GetVariableTimeStepTransientAnalysisFunct, + OPS_GetNumEigenPtrType OPS_GetNumEigenFunct, + OPS_GetStaticIntegratorPtrType OPS_GetStaticIntegratorFunct, + OPS_GetTransientIntegratorPtrType OPS_GetTransientIntegratorFunct, + OPS_GetTestPtrType OPS_GetTestFunct, + OPS_builtModelPtrType OPS_builtModelFunct, + OPS_GetDomainPointer OPS_getDomainPtr) { opserrPtr = theErrorStreamPtr; ops_TheActiveDomain = theDomain; @@ -169,6 +194,8 @@ void setGlobalPointers(OPS_Stream *theErrorStreamPtr, OPS_InvokeMaterialDirectlyPtr = OPS_InvokeMaterialDirectlyFunct; OPS_GetNumRemainingInputArgsPtr = OPS_GetNumRemainingArgsFunct; OPS_ResetCurrentInputArgPtr = OPS_ResetCurrentInputArgFunct; + //OPS_ResetInputPtr = OPS_ResetInputFunct; + OPS_ResetInputNoBuilderPtr = OPS_ResetInputNoBuilderFunct; OPS_GetStringPtr = OPS_GetStringFunct; OPS_GetStringCopyPtr = OPS_GetStringCopyFunct; OPS_GetNDM_Ptr = OPS_GetNDM_Funct; @@ -192,210 +219,257 @@ void setGlobalPointers(OPS_Stream *theErrorStreamPtr, OPS_GetDomainPtr = OPS_getDomainPtr; } - -UniaxialMaterial * +UniaxialMaterial* OPS_GetUniaxialMaterial(int matTag) { return (*OPS_GetUniaxialMaterialPtr)(matTag); } -NDMaterial * +NDMaterial* OPS_GetNDMaterial(int matTag) { return (*OPS_GetNDMaterialPtr)(matTag); } -SectionForceDeformation * +SectionForceDeformation* OPS_GetSectionForceDeformation(int secTag) { return (*OPS_GetSectionForceDeformationPtr)(secTag); } -CrdTransf * +CrdTransf* OPS_GetCrdTransf(int crdTag) { return (*OPS_GetCrdTransfPtr)(crdTag); } -FrictionModel * +FrictionModel* OPS_GetFrictionModel(int frnTag) { return (*OPS_GetFrictionModelPtr)(frnTag); } -int OPS_Error(char *data, int length) +int +OPS_Error(char* data, int length) { return (*OPS_ErrorPtr)(data, length); } -extern "C" int OPS_GetIntInput(int *numData, int*data) +extern "C" +int OPS_GetIntInput(int* numData, int* data) { return (*OPS_GetIntInputPtr)(numData, data); } -extern "C" int OPS_GetDoubleInput(int *numData, double *data) +extern "C" +int OPS_GetDoubleInput(int* numData, double* data) { return (*OPS_GetDoubleInputPtr)(numData, data); } -extern "C" int OPS_AllocateMaterial(matObj *mat) +extern "C" +int OPS_AllocateMaterial(matObj * mat) { return (*OPS_AllocateMaterialPtr)(mat); } -extern "C" int OPS_AllocateElement(eleObj *ele, int *matTags, int *matType) +extern "C" +int OPS_AllocateElement(eleObj * ele, int* matTags, int* matType) { return (*OPS_AllocateElementPtr)(ele, matTags, matType); } -extern "C" int OPS_GetNodeCrd(int *nodeTag, int *sizeData, double *data) +extern "C" +int OPS_GetNodeCrd(int* nodeTag, int* sizeData, double* data) { return (*OPS_GetNodeCrdPtr)(nodeTag, sizeData, data); } -extern "C" int OPS_GetNodeDisp(int *nodeTag, int *sizeData, double *data) +extern "C" +int OPS_GetNodeDisp(int* nodeTag, int* sizeData, double* data) { return (*OPS_GetNodeDispPtr)(nodeTag, sizeData, data); } -extern "C" int OPS_GetNodeVel(int *nodeTag, int *sizeData, double *data) +extern "C" +int OPS_GetNodeVel(int* nodeTag, int* sizeData, double* data) { return (*OPS_GetNodeVelPtr)(nodeTag, sizeData, data); } -extern "C" int OPS_GetNodeAccel(int *nodeTag, int *sizeData, double *data) +extern "C" +int OPS_GetNodeAccel(int* nodeTag, int* sizeData, double* data) { return (*OPS_GetNodeAccelPtr)(nodeTag, sizeData, data); } -extern "C" int OPS_GetNodeIncrDisp(int *nodeTag, int *sizeData, double *data) +extern "C" +int OPS_GetNodeIncrDisp(int* nodeTag, int* sizeData, double* data) { return (*OPS_GetNodeIncrDispPtr)(nodeTag, sizeData, data); } -extern "C" int OPS_GetNodeIncrDeltaDisp(int *nodeTag, int *sizeData, double *data) +extern "C" +int OPS_GetNodeIncrDeltaDisp(int* nodeTag, int* sizeData, double* data) { return (*OPS_GetNodeIncrDeltaDispPtr)(nodeTag, sizeData, data); } -extern "C" int OPS_InvokeMaterialDirectly(matObject **theMat, modelState *model, - double *strain, double *stress, double *tang, int *isw) +extern "C" +int OPS_InvokeMaterialDirectly(matObject * *theMat, modelState * model, + double* strain, double* stress, double* tang, int* isw) { return (*OPS_InvokeMaterialDirectlyPtr)(theMat, model, strain, stress, tang, isw); } -extern "C" const char *OPS_GetString() +extern "C" +const char* OPS_GetString() { return (*OPS_GetStringPtr)(); } -extern "C" int OPS_GetStringCopy(char **cArray) +extern "C" +int OPS_GetStringCopy(char** cArray) { - return (*OPS_GetStringCopyPtr)(cArray); + return (*OPS_GetStringCopyPtr)(cArray); } -extern "C" int OPS_GetNumRemainingInputArgs() +extern "C" +int OPS_GetNumRemainingInputArgs() { - return (*OPS_GetNumRemainingInputArgsPtr)(); + return (*OPS_GetNumRemainingInputArgsPtr)(); } -extern "C" int OPS_ResetCurrentInputArg(int cArg) +extern "C" +int OPS_ResetCurrentInputArg(int cArg) +{ + return (*OPS_ResetCurrentInputArgPtr)(cArg); +} + +/*extern "C" +int OPS_ResetInput(ClientData clientData, Tcl_Interp* interp, + int cArg, int mArg, TCL_Char** argv, Domain* domain, TclModelBuilder* builder) +{ + return (*OPS_ResetInputPtr)(clientData, interp, cArg, mArg, argv, domain, builder); +}*/ + +extern "C" +int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp * interp, + int cArg, int mArg, TCL_Char * *argv, Domain * domain) { - return (*OPS_ResetCurrentInputArgPtr)(cArg); + return (*OPS_ResetInputNoBuilderPtr)(clientData, interp, cArg, mArg, argv, domain); } -extern "C" int OPS_GetNDM() +extern "C" +int OPS_GetNDM() { return (*OPS_GetNDM_Ptr)(); } -extern "C" int OPS_GetNDF() +extern "C" +int OPS_GetNDF() { return (*OPS_GetNDF_Ptr)(); } -FE_Datastore * +FE_Datastore* OPS_GetFEDatastore() { return (*OPS_GetFEDatastorePtr)(); } -extern "C" const char *OPS_GetInterpPWD() +extern "C" +const char* OPS_GetInterpPWD() { return (*OPS_GetInterpPWD_Ptr)(); } -extern "C" AnalysisModel **OPS_GetAnalysisModel(void) +extern "C" +AnalysisModel * *OPS_GetAnalysisModel(void) { - return (*OPS_GetAnalysisModelPtr)(); + return (*OPS_GetAnalysisModelPtr)(); } -extern "C" EquiSolnAlgo **OPS_GetAlgorithm(void) +extern "C" +EquiSolnAlgo * *OPS_GetAlgorithm(void) { - return (*OPS_GetAlgorithmPtr)(); + return (*OPS_GetAlgorithmPtr)(); } -extern "C" ConstraintHandler **OPS_GetHandler(void) +extern "C" +ConstraintHandler * *OPS_GetHandler(void) { - return (*OPS_GetHandlerPtr)(); + return (*OPS_GetHandlerPtr)(); } -extern "C" DOF_Numberer **OPS_GetNumberer(void) +extern "C" +DOF_Numberer * *OPS_GetNumberer(void) { - return (*OPS_GetNumbererPtr)(); + return (*OPS_GetNumbererPtr)(); } -extern "C" LinearSOE **OPS_GetSOE(void) +extern "C" +LinearSOE * *OPS_GetSOE(void) { - return (*OPS_GetSOEPtr)(); + return (*OPS_GetSOEPtr)(); } -extern "C" EigenSOE **OPS_GetEigenSOE(void) +extern "C" +EigenSOE * *OPS_GetEigenSOE(void) { - return (*OPS_GetEigenSOEPtr)(); + return (*OPS_GetEigenSOEPtr)(); } -extern "C" StaticAnalysis **OPS_GetStaticAnalysis(void) +extern "C" +StaticAnalysis * *OPS_GetStaticAnalysis(void) { - return (*OPS_GetStaticAnalysisPtr)(); + return (*OPS_GetStaticAnalysisPtr)(); } -extern "C" DirectIntegrationAnalysis **OPS_GetTransientAnalysis(void) +extern "C" +DirectIntegrationAnalysis * *OPS_GetTransientAnalysis(void) { - return (*OPS_GetTransientAnalysisPtr)(); + return (*OPS_GetTransientAnalysisPtr)(); } -extern "C" VariableTimeStepDirectIntegrationAnalysis **OPS_GetVariableTimeStepTransientAnalysis(void) +extern "C" +VariableTimeStepDirectIntegrationAnalysis * *OPS_GetVariableTimeStepTransientAnalysis(void) { - return (*OPS_GetVariableTimeStepTransientAnalysisPtr)(); + return (*OPS_GetVariableTimeStepTransientAnalysisPtr)(); } -extern "C" int *OPS_GetNumEigen(void) +extern "C" +int* OPS_GetNumEigen(void) { - return (*OPS_GetNumEigenPtr)(); + return (*OPS_GetNumEigenPtr)(); } -extern "C" StaticIntegrator **OPS_GetStaticIntegrator(void) +extern "C" +StaticIntegrator * *OPS_GetStaticIntegrator(void) { - return (*OPS_GetStaticIntegratorPtr)(); + return (*OPS_GetStaticIntegratorPtr)(); } -extern "C" TransientIntegrator **OPS_GetTransientIntegrator(void) +extern "C" +TransientIntegrator * *OPS_GetTransientIntegrator(void) { - return (*OPS_GetTransientIntegratorPtr)(); + return (*OPS_GetTransientIntegratorPtr)(); } -extern "C" ConvergenceTest **OPS_GetTest(void) +extern "C" +ConvergenceTest * *OPS_GetTest(void) { - return (*OPS_GetTestPtr)(); + return (*OPS_GetTestPtr)(); } -extern "C" bool *OPS_builtModel(void) +extern "C" +bool* OPS_builtModel(void) { - return (*OPS_builtModelPtr)(); + return (*OPS_builtModelPtr)(); } -Domain *OPS_GetDomain(void) +Domain* +OPS_GetDomain(void) { return (*OPS_GetDomainPtr)(); } diff --git a/SRC/classTags.h b/SRC/classTags.h index 46be6de3cb..9c9b021d43 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -215,6 +215,9 @@ #define MAT_TAG_ElasticPowerFunc 102 #define MAT_TAG_UVCuniaxial 103 #define MAT_TAG_IMKBilin 104 +#define MAT_TAG_IMKPeakOriented 105 +#define MAT_TAG_IMKPinching 106 +#define MAT_TAG_SLModel 107 #define MAT_TAG_PySimple1 205 #define MAT_TAG_TzSimple1 206 #define MAT_TAG_QzSimple1 207 @@ -225,7 +228,8 @@ #define MAT_TAG_QzSimple2 212 #define MAT_TAG_SteelBRB 213 #define MAT_TAG_PySimple3 214 - +#define MAT_TAG_PlateBearingConnectionThermal 215 +#define MAT_TAG_ASD_SMA_3K 216 #define MAT_TAG_FedeasMaterial 1000 @@ -453,7 +457,9 @@ // PM4Silt material - L.Chen #define ND_TAG_PM4Silt 14022 // J2CyclicBoundingSurface material - D.Turello -#define ND_TAG_J2CyclicBoundingSurface 14023 +#define ND_TAG_J2CyclicBoundingSurface 14023 +#define ND_TAG_J2CyclicBoundingSurface3D 14024 +#define ND_TAG_J2CyclicBoundingSurfacePlaneStrain 14025 // MultiaxialCyclicPlasticity, add by Gang Wang #define ND_TAG_MultiaxialCyclicPlasticity 10031 @@ -476,6 +482,7 @@ #define ND_TAG_InitStressNDMaterial 7009 +#define ND_TAG_IncrementalElasticIsotropicThreeDimensional 7010 //Chile @@ -756,6 +763,13 @@ #define ELE_TAG_PFEMContact2D 200 #define ELE_TAG_PML3D 201 #define ELE_TAG_PML2D 202 +#define ELE_TAG_ASDShellQ4 203 // Massimo Petracca (ASDEA) +#define ELE_TAG_ASDShellT3 204 // Massimo Petracca (ASDEA) +#define ELE_TAG_WheelRail 205 +#define ELE_TAG_DispBeamColumn3dID 206 // Jose Abell the Chileno added +#define ELE_TAG_NineNodeQuad 207 +#define ELE_TAG_EightNodeQuad 208 +#define ELE_TAG_SixNodeTri 209 #define ELE_TAG_ExternalElement 99990 @@ -874,6 +888,7 @@ #define EquiALGORITHM_TAGS_InitialNewton 13 #define EquiALGORITHM_TAGS_ElasticAlgorithm 14 #define EquiALGORITHM_TAGS_NewtonHallM 15 +#define EquiALGORITHM_TAGS_ExpressNewton 16 #define ACCELERATOR_TAGS_Krylov 1 #define ACCELERATOR_TAGS_Secant 2 @@ -945,7 +960,10 @@ #define INTEGRATOR_TAGS_KRAlphaExplicit_TP 54 #define INTEGRATOR_TAGS_ExplicitDifference 55 #define INTEGRATOR_TAGS_EQPath 56 -#define INTEGRATOR_TAGS_GimmeMCK 57 +#define INTEGRATOR_TAGS_GimmeMCK 57 +#define INTEGRATOR_TAGS_StagedLoadControl 58 +#define INTEGRATOR_TAGS_StagedNewmark 59 + #define LinSOE_TAGS_FullGenLinSOE 1 #define LinSOE_TAGS_BandGenLinSOE 2 @@ -1036,6 +1054,8 @@ #define RECORDER_TAGS_MPCORecorder 20 #define RECORDER_TAGS_GmshRecorder 21 #define RECORDER_TAGS_VTK_Recorder 22 +#define RECORDER_TAGS_NodeRecorderRMS 23 +#define RECORDER_TAGS_ElementRecorderRMS 24 #define OPS_STREAM_TAGS_FileStream 1 #define OPS_STREAM_TAGS_StandardStream 2 diff --git a/SRC/convergenceTest/CTestPFEM.cpp b/SRC/convergenceTest/CTestPFEM.cpp index 1bce009f4f..e6d1bda293 100644 --- a/SRC/convergenceTest/CTestPFEM.cpp +++ b/SRC/convergenceTest/CTestPFEM.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include "sparseGEN/PFEMLinSOE.h" #include #include #include diff --git a/SRC/coordTransformation/CorotCrdTransf2d.cpp b/SRC/coordTransformation/CorotCrdTransf2d.cpp index 2bddc44337..90025d80cb 100644 --- a/SRC/coordTransformation/CorotCrdTransf2d.cpp +++ b/SRC/coordTransformation/CorotCrdTransf2d.cpp @@ -1137,6 +1137,14 @@ CorotCrdTransf2d::getPointGlobalDisplFromBasic(double xi, const Vector &uxb) return uxg; } +const Vector & +CorotCrdTransf2d::getPointLocalDisplFromBasic(double xi, const Vector &uxb) +{ + opserr << " CorotCrdTransf2d::getPointLocalDisplFromBasic: not implemented yet" ; + + return uxg; +} + void CorotCrdTransf2d::Print(OPS_Stream &s, int flag) diff --git a/SRC/coordTransformation/CorotCrdTransf2d.h b/SRC/coordTransformation/CorotCrdTransf2d.h index 2bec7a41ff..c54bb2f404 100644 --- a/SRC/coordTransformation/CorotCrdTransf2d.h +++ b/SRC/coordTransformation/CorotCrdTransf2d.h @@ -92,6 +92,7 @@ class CorotCrdTransf2d: public CrdTransf // methods used in post-processing only const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); + const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps); private: int compElemtLengthAndOrient(void); diff --git a/SRC/coordTransformation/CorotCrdTransf3d.cpp b/SRC/coordTransformation/CorotCrdTransf3d.cpp index c76c27670b..0eadc9a254 100644 --- a/SRC/coordTransformation/CorotCrdTransf3d.cpp +++ b/SRC/coordTransformation/CorotCrdTransf3d.cpp @@ -2161,6 +2161,17 @@ CorotCrdTransf3d::getPointGlobalDisplFromBasic(double xi, const Vector &uxb) } +const Vector & +CorotCrdTransf3d::getPointLocalDisplFromBasic(double xi, const Vector &uxb) +{ + static Vector uxg(3); + opserr << " CorotCrdTransf3d::getPointLocalDisplFromBasic: not implemented yet" ; + + + return uxg; +} + + void CorotCrdTransf3d::Print(OPS_Stream &s, int flag) { diff --git a/SRC/coordTransformation/CorotCrdTransf3d.h b/SRC/coordTransformation/CorotCrdTransf3d.h index 22e8597677..b50830cf01 100644 --- a/SRC/coordTransformation/CorotCrdTransf3d.h +++ b/SRC/coordTransformation/CorotCrdTransf3d.h @@ -83,6 +83,7 @@ class CorotCrdTransf3d: public CrdTransf // methods used in post-processing only const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); + const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps); int getLocalAxes(Vector &xAxis, Vector &yAxis, Vector &zAxis); diff --git a/SRC/coordTransformation/CorotCrdTransfWarping2d.cpp b/SRC/coordTransformation/CorotCrdTransfWarping2d.cpp index f6462b88de..1a8cbb3de1 100644 --- a/SRC/coordTransformation/CorotCrdTransfWarping2d.cpp +++ b/SRC/coordTransformation/CorotCrdTransfWarping2d.cpp @@ -898,6 +898,15 @@ CorotCrdTransfWarping2d::getPointGlobalDisplFromBasic (double xi, const Vector & } +const Vector & +CorotCrdTransfWarping2d::getPointLocalDisplFromBasic (double xi, const Vector &uxb) +{ + opserr << " CorotCrdTransfWarping2d::getPointLocalDisplFromBasic: not implemented yet" ; + + return uxg; +} + + void CorotCrdTransfWarping2d::Print(OPS_Stream &s, int flag) { diff --git a/SRC/coordTransformation/CorotCrdTransfWarping2d.h b/SRC/coordTransformation/CorotCrdTransfWarping2d.h index 1351dc00db..e040093326 100644 --- a/SRC/coordTransformation/CorotCrdTransfWarping2d.h +++ b/SRC/coordTransformation/CorotCrdTransfWarping2d.h @@ -88,6 +88,7 @@ class CorotCrdTransfWarping2d: public CrdTransf // functions used in post-processing only const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); + const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps); private: int compElemtLengthAndOrient(void); diff --git a/SRC/coordTransformation/CrdTransf.h b/SRC/coordTransformation/CrdTransf.h index 41bd542ea8..696f519318 100644 --- a/SRC/coordTransformation/CrdTransf.h +++ b/SRC/coordTransformation/CrdTransf.h @@ -94,6 +94,7 @@ class CrdTransf: public TaggedObject, public MovableObject // methods used in post-processing only virtual const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords) = 0; virtual const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps) = 0; + virtual const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps) = 0; protected: diff --git a/SRC/coordTransformation/LinearCrdTransf2d.cpp b/SRC/coordTransformation/LinearCrdTransf2d.cpp index 57d847a5db..3d06858a0e 100644 --- a/SRC/coordTransformation/LinearCrdTransf2d.cpp +++ b/SRC/coordTransformation/LinearCrdTransf2d.cpp @@ -1168,6 +1168,66 @@ LinearCrdTransf2d::getPointGlobalDisplFromBasic(double xi, const Vector &uxb) } +const Vector & +LinearCrdTransf2d::getPointLocalDisplFromBasic(double xi, const Vector &uxb) +{ + // determine global displacements + const Vector &disp1 = nodeIPtr->getTrialDisp(); + const Vector &disp2 = nodeJPtr->getTrialDisp(); + + static Vector ug(6); + for (int i = 0; i < 3; i++) + { + ug(i) = disp1(i); + ug(i+3) = disp2(i); + } + + if (nodeIInitialDisp != 0) { + for (int j=0; j<3; j++) + ug[j] -= nodeIInitialDisp[j]; + } + + if (nodeJInitialDisp != 0) { + for (int j=0; j<3; j++) + ug[j+3] -= nodeJInitialDisp[j]; + } + + // transform global end displacements to local coordinates + static Vector ul(6); // total displacements + + ul(0) = cosTheta*ug(0) + sinTheta*ug(1); + ul(1) = -sinTheta*ug(0) + cosTheta*ug(1); + ul(2) = ug(2); + ul(3) = cosTheta*ug(3) + sinTheta*ug(4); + ul(4) = -sinTheta*ug(3) + cosTheta*ug(4); + ul(5) = ug(5); + + if (nodeIOffset != 0) { + double t02 = -cosTheta*nodeIOffset[1] + sinTheta*nodeIOffset[0]; + double t12 = sinTheta*nodeIOffset[1] + cosTheta*nodeIOffset[0]; + + ul(0) += t02*ug(2); + ul(1) += t12*ug(2); + } + + if (nodeJOffset != 0) { + double t35 = -cosTheta*nodeJOffset[1] + sinTheta*nodeJOffset[0]; + double t45 = sinTheta*nodeJOffset[1] + cosTheta*nodeJOffset[0]; + + ul(3) += t35*ug(5); + ul(4) += t45*ug(5); + } + + // compute displacements at point xi, in local coordinates + static Vector uxl(2); + + uxl(0) = uxb(0) + ul(0); + uxl(1) = uxb(1) + (1-xi)*ul(1) + xi*ul(4); + + return uxl; +} + + void LinearCrdTransf2d::Print(OPS_Stream &s, int flag) { @@ -1553,3 +1613,21 @@ LinearCrdTransf2d::getBasicDisplSensitivity(int gradNumber, int flag) return ub; } + +int +LinearCrdTransf2d::getLocalAxes(Vector &xAxis, Vector &yAxis, Vector &zAxis) +{ + xAxis(0) = cosTheta; + xAxis(1) = sinTheta; + xAxis(2) = 0; + + yAxis(0) = -sinTheta; + yAxis(1) = cosTheta; + yAxis(2) = 0; + + zAxis(0) = 0.0; + zAxis(1) = 0.0; + zAxis(2) = 1.0; + + return 0; +} diff --git a/SRC/coordTransformation/LinearCrdTransf2d.h b/SRC/coordTransformation/LinearCrdTransf2d.h index d6d148e7e5..6066d205d6 100644 --- a/SRC/coordTransformation/LinearCrdTransf2d.h +++ b/SRC/coordTransformation/LinearCrdTransf2d.h @@ -105,6 +105,9 @@ class LinearCrdTransf2d: public CrdTransf // methods used in post-processing only const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); + const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps); + + int getLocalAxes(Vector &xAxis, Vector &yAxis, Vector &zAxis); private: int computeElemtLengthAndOrient(void); diff --git a/SRC/coordTransformation/LinearCrdTransf3d.cpp b/SRC/coordTransformation/LinearCrdTransf3d.cpp index ec6e865744..50ec6836c6 100644 --- a/SRC/coordTransformation/LinearCrdTransf3d.cpp +++ b/SRC/coordTransformation/LinearCrdTransf3d.cpp @@ -1426,6 +1426,74 @@ LinearCrdTransf3d::getPointGlobalDisplFromBasic(double xi, const Vector &uxb) } +const Vector & +LinearCrdTransf3d::getPointLocalDisplFromBasic(double xi, const Vector &uxb) +{ + // determine global displacements + const Vector &disp1 = nodeIPtr->getTrialDisp(); + const Vector &disp2 = nodeJPtr->getTrialDisp(); + + static double ug[12]; + for (int i = 0; i < 6; i++) + { + ug[i] = disp1(i); + ug[i+6] = disp2(i); + } + + if (nodeIInitialDisp != 0) { + for (int j=0; j<6; j++) + ug[j] -= nodeIInitialDisp[j]; + } + + if (nodeJInitialDisp != 0) { + for (int j=0; j<6; j++) + ug[j+6] -= nodeJInitialDisp[j]; + } + + + + // transform global end displacements to local coordinates + //ul.addMatrixVector(0.0, Tlg, ug, 1.0); // ul = Tlg * ug; + static double ul[12]; + + ul[0] = R[0][0]*ug[0] + R[0][1]*ug[1] + R[0][2]*ug[2]; + ul[1] = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2]; + ul[2] = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2]; + + ul[7] = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8]; + ul[8] = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8]; + + static double Wu[3]; + if (nodeIOffset) { + Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5]; + Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5]; + Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4]; + + ul[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2]; + ul[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2]; + ul[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2]; + } + + if (nodeJOffset) { + Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11]; + Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11]; + Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10]; + + ul[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2]; + ul[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2]; + } + + // compute displacements at point xi, in local coordinates + static Vector uxl(3); + + uxl(0) = uxb(0) + ul[0]; + uxl(1) = uxb(1) + (1-xi)*ul[1] + xi*ul[7]; + uxl(2) = uxb(2) + (1-xi)*ul[2] + xi*ul[8]; + + return uxl; +} + + void LinearCrdTransf3d::Print(OPS_Stream &s, int flag) { diff --git a/SRC/coordTransformation/LinearCrdTransf3d.h b/SRC/coordTransformation/LinearCrdTransf3d.h index f75f50ef41..a33e655a29 100644 --- a/SRC/coordTransformation/LinearCrdTransf3d.h +++ b/SRC/coordTransformation/LinearCrdTransf3d.h @@ -85,6 +85,7 @@ class LinearCrdTransf3d: public CrdTransf // methods used in post-processing only const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); + const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps); int getLocalAxes(Vector &xAxis, Vector &yAxis, Vector &zAxis); diff --git a/SRC/coordTransformation/PDeltaCrdTransf2d.cpp b/SRC/coordTransformation/PDeltaCrdTransf2d.cpp index 6506b8e3ed..88c87bb90c 100644 --- a/SRC/coordTransformation/PDeltaCrdTransf2d.cpp +++ b/SRC/coordTransformation/PDeltaCrdTransf2d.cpp @@ -1215,6 +1215,66 @@ PDeltaCrdTransf2d::getPointGlobalDisplFromBasic(double xi, const Vector &uxb) } +const Vector & +PDeltaCrdTransf2d::getPointLocalDisplFromBasic(double xi, const Vector &uxb) +{ + // determine global displacements + const Vector &disp1 = nodeIPtr->getTrialDisp(); + const Vector &disp2 = nodeJPtr->getTrialDisp(); + + static Vector ug(6); + for (int i = 0; i < 3; i++) + { + ug(i) = disp1(i); + ug(i+3) = disp2(i); + } + + if (nodeIInitialDisp != 0) { + for (int j=0; j<3; j++) + ug[j] -= nodeIInitialDisp[j]; + } + + if (nodeJInitialDisp != 0) { + for (int j=0; j<3; j++) + ug[j+3] -= nodeJInitialDisp[j]; + } + + // transform global end displacements to local coordinates + static Vector ul(6); // total displacements + + ul(0) = cosTheta*ug(0) + sinTheta*ug(1); + ul(1) = -sinTheta*ug(0) + cosTheta*ug(1); + ul(2) = ug(2); + ul(3) = cosTheta*ug(3) + sinTheta*ug(4); + ul(4) = -sinTheta*ug(3) + cosTheta*ug(4); + ul(5) = ug(5); + + if (nodeIOffset != 0) { + double t02 = -cosTheta*nodeIOffset[1] + sinTheta*nodeIOffset[0]; + double t12 = sinTheta*nodeIOffset[1] + cosTheta*nodeIOffset[0]; + + ul(0) += t02*ug(2); + ul(1) += t12*ug(2); + } + + if (nodeJOffset != 0) { + double t35 = -cosTheta*nodeJOffset[1] + sinTheta*nodeJOffset[0]; + double t45 = sinTheta*nodeJOffset[1] + cosTheta*nodeJOffset[0]; + + ul(3) += t35*ug(5); + ul(4) += t45*ug(5); + } + + // compute displacements at point xi, in local coordinates + static Vector uxl(2); + + uxl(0) = uxb(0) + ul(0); + uxl(1) = uxb(1) + (1-xi)*ul(1) + xi*ul(4); + + return uxl; +} + + void PDeltaCrdTransf2d::Print(OPS_Stream &s, int flag) { @@ -1235,3 +1295,21 @@ PDeltaCrdTransf2d::Print(OPS_Stream &s, int flag) s << "}"; } } + +int +PDeltaCrdTransf2d::getLocalAxes(Vector &xAxis, Vector &yAxis, Vector &zAxis) +{ + xAxis(0) = cosTheta; + xAxis(1) = sinTheta; + xAxis(2) = 0; + + yAxis(0) = -sinTheta; + yAxis(1) = cosTheta; + yAxis(2) = 0; + + zAxis(0) = 0.0; + zAxis(1) = 0.0; + zAxis(2) = 1.0; + + return 0; +} diff --git a/SRC/coordTransformation/PDeltaCrdTransf2d.h b/SRC/coordTransformation/PDeltaCrdTransf2d.h index 00209164c4..525f353f8b 100644 --- a/SRC/coordTransformation/PDeltaCrdTransf2d.h +++ b/SRC/coordTransformation/PDeltaCrdTransf2d.h @@ -88,6 +88,9 @@ class PDeltaCrdTransf2d: public CrdTransf // methods used in post-processing only const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); + const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps); + + int getLocalAxes(Vector &xAxis, Vector &yAxis, Vector &zAxis); private: int computeElemtLengthAndOrient(void); diff --git a/SRC/coordTransformation/PDeltaCrdTransf3d.cpp b/SRC/coordTransformation/PDeltaCrdTransf3d.cpp index 847a27db2e..77ae1c3752 100644 --- a/SRC/coordTransformation/PDeltaCrdTransf3d.cpp +++ b/SRC/coordTransformation/PDeltaCrdTransf3d.cpp @@ -1496,6 +1496,72 @@ PDeltaCrdTransf3d::getPointGlobalDisplFromBasic(double xi, const Vector &uxb) } +const Vector & +PDeltaCrdTransf3d::getPointLocalDisplFromBasic(double xi, const Vector &uxb) +{ + // determine global displacements + const Vector &disp1 = nodeIPtr->getTrialDisp(); + const Vector &disp2 = nodeJPtr->getTrialDisp(); + + static double ug[12]; + for (int i = 0; i < 6; i++) + { + ug[i] = disp1(i); + ug[i+6] = disp2(i); + } + + if (nodeIInitialDisp != 0) { + for (int j=0; j<6; j++) + ug[j] -= nodeIInitialDisp[j]; + } + + if (nodeJInitialDisp != 0) { + for (int j=0; j<6; j++) + ug[j+6] -= nodeJInitialDisp[j]; + } + + // transform global end displacements to local coordinates + //ul.addMatrixVector(0.0, Tlg, ug, 1.0); // ul = Tlg * ug; + static double ul[12]; + + ul[0] = R[0][0]*ug[0] + R[0][1]*ug[1] + R[0][2]*ug[2]; + ul[1] = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2]; + ul[2] = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2]; + + ul[7] = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8]; + ul[8] = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8]; + + static double Wu[3]; + if (nodeIOffset) { + Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5]; + Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5]; + Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4]; + + ul[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2]; + ul[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2]; + ul[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2]; + } + + if (nodeJOffset) { + Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11]; + Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11]; + Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10]; + + ul[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2]; + ul[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2]; + } + + // compute displacements at point xi, in local coordinates + static Vector uxl(3); + + uxl(0) = uxb(0) + ul[0]; + uxl(1) = uxb(1) + (1-xi)*ul[1] + xi*ul[7]; + uxl(2) = uxb(2) + (1-xi)*ul[2] + xi*ul[8]; + + return uxl; +} + + void PDeltaCrdTransf3d::Print(OPS_Stream &s, int flag) { diff --git a/SRC/coordTransformation/PDeltaCrdTransf3d.h b/SRC/coordTransformation/PDeltaCrdTransf3d.h index ad5e11225b..fea5e6dbc1 100644 --- a/SRC/coordTransformation/PDeltaCrdTransf3d.h +++ b/SRC/coordTransformation/PDeltaCrdTransf3d.h @@ -85,6 +85,7 @@ class PDeltaCrdTransf3d: public CrdTransf // methods used in post-processing only const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); + const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps); int getLocalAxes(Vector &xAxis, Vector &yAxis, Vector &zAxis); diff --git a/SRC/doc/OpenSeesCommands.tex b/SRC/doc/OpenSeesCommands.tex index a36e2c2d93..1a64926d7b 100644 --- a/SRC/doc/OpenSeesCommands.tex +++ b/SRC/doc/OpenSeesCommands.tex @@ -1978,8 +1978,8 @@ \subsection{The equalDOF Command} } The equalDOF command is used to construct a multi-point constraint between -the nodes identified by rNodeTag and cNodeTag. rNodeTag is the retained, or -master node, and cNodeTag is the constrained, or slave node. dof1 dof2 ... +the nodes identified by rNodeTag and cNodeTag. rNodeTag is the retained node +and cNodeTag is the constrained node. dof1 dof2 ... represent the nodal degrees of freedom that are constrained at the cNode to be the same as those at the rNode. The valid range for dof1 dof2 ... is 1 through ndf, the number of nodal degrees of freedom. @@ -1987,14 +1987,14 @@ \subsection{The equalDOF Command} \subsection{The rigidDiaphragm Command} {\sf\small \begin{verbatim} - rigidDiaphragm perpDirn? masterNodeTag? slaveNodeTag1 ... + rigidDiaphragm perpDirn? rNodeTag? cNodeTag1 ... \end{verbatim} } The rigidDiaphragm command is used to construct a number of MP\_Constraint objects. These constraints will constrain certain -degrees-of-freedom at the the slave nodes listed to move as if in a -rigid plane with the master node. The rigid plane can be the 12, 13 or +degrees-of-freedom at the the constrained nodes listed to move as if in a +rigid plane with the retained node. The rigid plane can be the 12, 13 or 23 planes. The rigid plane is specified by the user providing the perpendicular plane direction, ie 3 for 12 plane. The constraint object is constructed assuming small rotations. The rigidDiaphragm @@ -2004,15 +2004,15 @@ \subsection{The rigidDiaphragm Command} \subsection{The rigidLink Command} {\sf\small \begin{verbatim} - rigidLink -type? masterNodeTag? slaveNodeTag + rigidLink -type? rNodeTag? cNodeTag \end{verbatim} } The rigidLink command is used to construct a single MP\_Constraint object. The type can be either rod or beam. If rod is specified, the translational degrees-of-freedom will be constrained to be exactly the -same as those at the master node. If beam is specified, a rigid beam -constraint is imposed on the slave node, that is the translational and +same as those at the retained node. If beam is specified, a rigid beam +constraint is imposed on the constrained node, that is the translational and rotational degrees of freedom are constrained. The constraint object constructed for the beam option assumes small rotations. diff --git a/SRC/doc/OpenSeesExamples.tex b/SRC/doc/OpenSeesExamples.tex index aed0a5978f..46512c619a 100644 --- a/SRC/doc/OpenSeesExamples.tex +++ b/SRC/doc/OpenSeesExamples.tex @@ -1900,7 +1900,7 @@ \subsection{Example 5.1} \vspace{0.2in} \noindent{\bf Output Specification} The nodal displacements at nodes 9, 14, and 19 -(the master nodes for the rigid diaphragms) +(the retained nodes for the rigid diaphragms) will be stored in the file node51.out for post-processing. \vspace{0.2in} \noindent{\bf OpenSees Script} @@ -1948,7 +1948,7 @@ \subsection{Example 5.1} node 17 [expr $bx/2] [expr -$by/2] [expr 3*$h] node 18 [expr -$bx/2] [expr -$by/2] [expr 3*$h] -# Master nodes for rigid diaphragm +# Retained nodes for rigid diaphragm # tag X Y Z node 9 0 0 $h node 14 0 0 [expr 2*$h] @@ -1962,12 +1962,12 @@ \subsection{Example 5.1} fix 4 1 1 1 1 1 1 # Define rigid diaphragm multi-point constraints -# normalDir master slaves +# normalDir retained constrained rigidDiaphragm 3 9 5 6 7 8 rigidDiaphragm 3 14 10 11 12 13 rigidDiaphragm 3 19 15 16 17 18 -# Constraints for rigid diaphragm master nodes +# Constraints for rigid diaphragm retained nodes # tag DX DY DZ RX RY RZ fix 9 0 0 1 1 1 0 fix 14 0 0 1 1 1 0 @@ -2092,14 +2092,14 @@ \subsection{Example 5.1} # 10% of column capacity set p [expr 0.1*$fc*$h*$h] -# Mass lumped at master nodes +# Mass lumped at retained nodes set g 386.4; # Gravitational constant set m [expr (4*$p)/$g] -# Rotary inertia of floor about master node +# Rotary inertia of floor about retained node set i [expr $m*($bx*$bx+$by*$by)/12.0] -# Set mass at the master nodes +# Set mass at the retained nodes # tag MX MY MZ RX RY RZ mass 9 $m $m 0 0 0 $i mass 14 $m $m 0 0 0 $i @@ -2189,7 +2189,7 @@ \subsection{Example 5.1} The results consist of the file node.out, which contains a line for every time step. Each line contains the time and the horizontal and -vertical displacements at the diaphragm master nodes (9, 14 and 19) +vertical displacements at the diaphragm retained nodes (9, 14 and 19) i.e. time Dx9 Dy9 Dx14 Dy14 Dx19 Dy19. The horizontal displacement time history of the first floor diaphragm node 9 is shown in figure~\ref{example4disp}. Notice the increase in period diff --git a/SRC/doc/g3Primer.tex b/SRC/doc/g3Primer.tex index ece6939c4d..25377cf1e2 100644 --- a/SRC/doc/g3Primer.tex +++ b/SRC/doc/g3Primer.tex @@ -1464,8 +1464,8 @@ \subsection{The equalDOF Command} } The equalDOF command is used to construct a multi-point constraint between -the nodes identified by rNodeTag and cNodeTag. rNodeTag is the retained, or -master node, and cNodeTag is the constrained, or slave node. dof1 dof2 ... +the nodes identified by rNodeTag and cNodeTag. rNodeTag is the retained node +and cNodeTag is the constrained node. dof1 dof2 ... represent the nodal degrees of freedom that are constrained at the cNode to be the same as those at the rNode. The valid range for dof1 dof2 ... is 1 through ndf, the number of nodal degrees of freedom. @@ -1473,14 +1473,14 @@ \subsection{The equalDOF Command} \subsection{The rigidDiaphragm Command} {\sf\small \begin{verbatim} - rigidDiaphragm perpDirn? masterNodeTag? slaveNodeTag1 ... + rigidDiaphragm perpDirn? rNodeTag? cNodeTag1 ... \end{verbatim} } The rigidDiaphragm command is used to construct a number of MP\_Constraint objects. These constraints will constrain certain -degrees-of-freedom at the the slave nodes listed to move as if in a -rigid plane with the master node. The rigid plane can be the 12, 13 or +degrees-of-freedom at the the constrained nodes listed to move as if in a +rigid plane with the retained node. The rigid plane can be the 12, 13 or 23 planes. The rigid plane is specified by the user providing the perpendicular plane direction, ie 3 for 12 plane. The constraint object is constructed assuming small rotations. The rigidDiaphragm @@ -1490,15 +1490,15 @@ \subsection{The rigidDiaphragm Command} \subsection{The rigidLink Command} {\sf\small \begin{verbatim} - rigidLink -type? masterNodeTag? slaveNodeTag + rigidLink -type? rNodeTag? cNodeTag \end{verbatim} } The rigidLink command is used to construct a single MP\_Constraint object. The type can be either rod or beam. If rod is specified, the translational degrees-of-freedom will be constrained to be exactly the -same as those at the master node. If beam is specified, a rigid beam -constraint is imposed on the slave node, that is the translational and +same as those at the retained node. If beam is specified, a rigid beam +constraint is imposed on the constraint node, that is the translational and rotational degrees of freedom are constrained. The constraint object constructed for the beam option assumes small rotations. diff --git a/SRC/domain/constraints/RigidDiaphragm.cpp b/SRC/domain/constraints/RigidDiaphragm.cpp index 745ccb9f00..491ca78e42 100644 --- a/SRC/domain/constraints/RigidDiaphragm.cpp +++ b/SRC/domain/constraints/RigidDiaphragm.cpp @@ -72,14 +72,14 @@ RigidDiaphragm::RigidDiaphragm(Domain &theDomain, int nR, ID &nC, // check plane is valid, i.e. perpPlaneConstrained must be 0, 1 or 2 if (perpPlaneConstrained < 0 || perpPlaneConstrained > 2) { opserr << "RigidDiaphragm::RigidDiaphragm - " << - "the dirn of perpendicular to constrained plane" << perpPlaneConstrained << "not valid\n"; + "the dirn of perpendicular to constrained plane " << perpPlaneConstrained << " not valid\n"; return; } // check constrainedNodes ID does not contain the retained node if (nC.getLocation(nR) >= 0) { opserr << "RigidDiaphragm::RigidDiaphragm - " << - "retained node" << nR << "is in constrained node list\n"; + "retained node " << nR << " is in constrained node list\n"; return; } @@ -87,14 +87,14 @@ RigidDiaphragm::RigidDiaphragm(Domain &theDomain, int nR, ID &nC, Node *nodeR = theDomain.getNode(nR); if (nodeR == 0) { opserr << "RigidDiaphragm::RigidDiaphragm - " << - "retained Node" << nR << "not in domain\n"; + "retained Node " << nR << " not in domain\n"; return; } const Vector &crdR = nodeR->getCrds(); if ((nodeR->getNumberDOF() != 6) || (crdR.Size() != 3)){ opserr << "RigidDiaphragm::RigidDiaphragm - " << - "retained Node" << nR << "not in 3d space with 6 dof\n"; + "retained Node " << nR << " not in 3d space with 6 dof\n"; return; @@ -205,7 +205,7 @@ RigidDiaphragm::RigidDiaphragm(Domain &theDomain, int nR, ID &nC, } } else // node not in 3d space - opserr << "RigidDiaphragm::RigidDiaphragm - ignoring constrained Node " << ndC << + opserr << "RigidDiaphragm::RigidDiaphragm - ignoring constrained Node " << ndC << ", not 3d node\n"; } else // node does not exist diff --git a/SRC/domain/domain/Domain.cpp b/SRC/domain/domain/Domain.cpp index f1baefa18d..f7eaee432b 100644 --- a/SRC/domain/domain/Domain.cpp +++ b/SRC/domain/domain/Domain.cpp @@ -3529,3 +3529,39 @@ Domain::getRecorder(int tag) return res; } + + + +int Domain::activateElements(const ID& elementList) +{ + ElementIter& iter = getElements(); + Element* theElement; + for (int i = 0; i < elementList.Size(); ++i) + { + int eleTag = elementList(i); + Element* theElement = this->getElement(eleTag); + if (theElement != 0) + { + theElement->activate(); + } + } + return 0; +} + + + +int Domain::deactivateElements(const ID& elementList) +{ + // ElementIter& iter = getElements(); + Element* theElement; + for (int i = 0; i < elementList.Size(); ++i) + { + int eleTag = elementList(i); + Element* theElement = this->getElement(eleTag); + if (theElement != 0) + { + theElement->deactivate(); + } + } + return 0; +} diff --git a/SRC/domain/domain/Domain.h b/SRC/domain/domain/Domain.h index 3b6357f6bc..f3bb0f7dc1 100644 --- a/SRC/domain/domain/Domain.h +++ b/SRC/domain/domain/Domain.h @@ -235,6 +235,9 @@ class Domain virtual int calculateNodalReactions(int flag); Recorder* getRecorder(int tag); //by SAJalali + virtual int activateElements(const ID& elementList); + virtual int deactivateElements(const ID& elementList); + protected: virtual int buildEleGraph(Graph *theEleGraph); diff --git a/SRC/domain/domain/partitioned/PartitionedDomain.cpp b/SRC/domain/domain/partitioned/PartitionedDomain.cpp index 0abac60678..e1d1334b08 100644 --- a/SRC/domain/domain/partitioned/PartitionedDomain.cpp +++ b/SRC/domain/domain/partitioned/PartitionedDomain.cpp @@ -17,17 +17,17 @@ ** Filip C. Filippou (filippou@ce.berkeley.edu) ** ** ** ** ****************************************************************** */ - + // $Revision: 1.21 $ // $Date: 2010-09-16 00:07:11 $ // $Source: /usr/local/cvs/OpenSees/SRC/domain/domain/partitioned/PartitionedDomain.cpp,v $ - -// Written: fmk + +// Written: fmk // Revision: A // // Description: This file contains the class definition for PartitionedDomain. // PartitionedDomain is an abstract class. The class is responsible for holding -// and providing access to the Elements, Nodes, LoadCases, SP_Constraints +// and providing access to the Elements, Nodes, LoadCases, SP_Constraints // and MP_Constraints just like a normal domain. In addition the domain provides // a method to partition the domain into Subdomains. // @@ -47,8 +47,9 @@ #include #include #include +#include +#include #include -#include #include #include #include @@ -66,6 +67,10 @@ #include #include +#include + +#include + typedef map MAP_INT; typedef MAP_INT::value_type MAP_INT_TYPE; typedef MAP_INT::iterator MAP_INT_ITERATOR; @@ -74,76 +79,80 @@ typedef map MAP_ID; typedef MAP_ID::value_type MAP_ID_TYPE; typedef MAP_ID::iterator MAP_ID_ITERATOR; +typedef map MAP_VERTEX; +typedef MAP_VERTEX::value_type MAP_VERTEX_TYPE; +typedef MAP_VERTEX::iterator MAP_VERTEX_ITERATOR; + PartitionedDomain::PartitionedDomain() -:Domain(), - theSubdomains(0),theDomainPartitioner(0), - theSubdomainIter(0), mySubdomainGraph(0) + : Domain(), + theSubdomains(0), theDomainPartitioner(0), + theSubdomainIter(0), mySubdomainGraph(0), has_sent_yet(false) { - elements = new ArrayOfTaggedObjects(1024); - theSubdomains = new ArrayOfTaggedObjects(32); - theSubdomainIter = new PartitionedDomainSubIter(theSubdomains); + elements = new MapOfTaggedObjects();//(1024); + theSubdomains = new ArrayOfTaggedObjects(32); + theSubdomainIter = new PartitionedDomainSubIter(theSubdomains); - mainEleIter = new SingleDomEleIter(elements); - theEleIter = new PartitionedDomainEleIter(this); - - if (theSubdomains == 0 || elements == 0 || - theSubdomainIter == 0 || - theEleIter == 0 || mainEleIter == 0) { - - opserr << "FATAL: PartitionedDomain::PartitionedDomain "; - opserr << " - ran out of memory\n"; - exit(-1); - } + mainEleIter = new SingleDomEleIter(elements); + theEleIter = new PartitionedDomainEleIter(this); + + if (theSubdomains == 0 || elements == 0 || + theSubdomainIter == 0 || + theEleIter == 0 || mainEleIter == 0) { + + opserr << "FATAL: PartitionedDomain::PartitionedDomain "; + opserr << " - ran out of memory\n"; + exit(-1); + } } PartitionedDomain::PartitionedDomain(DomainPartitioner &thePartitioner) -:Domain(), - theSubdomains(0),theDomainPartitioner(&thePartitioner), - theSubdomainIter(0), mySubdomainGraph(0) + : Domain(), + theSubdomains(0), theDomainPartitioner(&thePartitioner), + theSubdomainIter(0), mySubdomainGraph(0), has_sent_yet(false) { - elements = new ArrayOfTaggedObjects(1024); - theSubdomains = new ArrayOfTaggedObjects(32); - theSubdomainIter = new PartitionedDomainSubIter(theSubdomains); + elements = new MapOfTaggedObjects();//(1024); + theSubdomains = new ArrayOfTaggedObjects(32); + theSubdomainIter = new PartitionedDomainSubIter(theSubdomains); - mainEleIter = new SingleDomEleIter(elements); - theEleIter = new PartitionedDomainEleIter(this); - - if (theSubdomains == 0 || elements == 0 || - theSubdomainIter == 0 || theDomainPartitioner == 0 || - theEleIter == 0 || mainEleIter == 0) { - - opserr << "FATAL: PartitionedDomain::PartitionedDomain "; - opserr << " - ran out of memory\n"; - exit(-1); - } + mainEleIter = new SingleDomEleIter(elements); + theEleIter = new PartitionedDomainEleIter(this); + + if (theSubdomains == 0 || elements == 0 || + theSubdomainIter == 0 || theDomainPartitioner == 0 || + theEleIter == 0 || mainEleIter == 0) { + + opserr << "FATAL: PartitionedDomain::PartitionedDomain "; + opserr << " - ran out of memory\n"; + exit(-1); + } } PartitionedDomain::PartitionedDomain(int numNodes, int numElements, - int numSPs, int numMPs, int numLoadPatterns, - int numSubdomains, - DomainPartitioner &thePartitioner) + int numSPs, int numMPs, int numLoadPatterns, + int numSubdomains, + DomainPartitioner &thePartitioner) -:Domain(numNodes,0,numSPs,numMPs,numLoadPatterns), - theSubdomains(0),theDomainPartitioner(&thePartitioner), - theSubdomainIter(0), mySubdomainGraph(0) + : Domain(numNodes, 0, numSPs, numMPs, numLoadPatterns), + theSubdomains(0), theDomainPartitioner(&thePartitioner), + theSubdomainIter(0), mySubdomainGraph(0), has_sent_yet(false) { - elements = new ArrayOfTaggedObjects(numElements); - theSubdomains = new ArrayOfTaggedObjects(numSubdomains); - theSubdomainIter = new PartitionedDomainSubIter(theSubdomains); + elements = new MapOfTaggedObjects();//(numElements); + theSubdomains = new ArrayOfTaggedObjects(numSubdomains); + theSubdomainIter = new PartitionedDomainSubIter(theSubdomains); - mainEleIter = new SingleDomEleIter(elements); - theEleIter = new PartitionedDomainEleIter(this); - - if (theSubdomains == 0 || elements == 0 || - theSubdomainIter == 0 || - theEleIter == 0 || mainEleIter == 0) { - - opserr << "FATAL: PartitionedDomain::PartitionedDomain(int ..) "; - opserr << " - ran out of memory\n"; - exit(-1); - } + mainEleIter = new SingleDomEleIter(elements); + theEleIter = new PartitionedDomainEleIter(this); + + if (theSubdomains == 0 || elements == 0 || + theSubdomainIter == 0 || + theEleIter == 0 || mainEleIter == 0) { + + opserr << "FATAL: PartitionedDomain::PartitionedDomain(int ..) "; + opserr << " - ran out of memory\n"; + exit(-1); + } } @@ -173,73 +182,73 @@ PartitionedDomain::clearAll(void) SubdomainIter &mySubdomains = this->getSubdomains(); Subdomain *theSub; - while ((theSub = mySubdomains()) != 0) + while ((theSub = mySubdomains()) != 0) theSub->clearAll(); theSubdomains->clearAll(); this->Domain::clearAll(); elements->clearAll(); } - -bool + +bool PartitionedDomain::addElement(Element *elePtr) { if (elePtr->isSubdomain() == true) return this->addSubdomain((Subdomain *)elePtr); int eleTag = elePtr->getTag(); -#ifdef _DEBUG - - // check ele Tag >= 0 - if (eleTag < 0) { - opserr << "PartitionedDomain::addElement - Element " << eleTag; - opserr << " tag must be >= 0\n"; - return false; - } - - // check its not in this or any of the subdomains - // MISSING CODE - - // check all the elements nodes exist in the domain - const ID &nodes = elePtr->getExternalNodes(); - for (int i=0; igetNode(nodeTag); - if (nodePtr == 0) { - opserr << "PartitionedDomain::addElement - In element " << eleTag; - opserr << " no node " << nodeTag << " exists in the domain\n"; - return false; - } - } - -#endif - - TaggedObject *other = elements->getComponentPtr(eleTag); - if (other != 0) - return false; - - bool result = elements->addComponent(elePtr); - if (result == true) { - elePtr->setDomain(this); - elePtr->update(); - this->domainChange(); +#ifdef _DEBUG + + // check ele Tag >= 0 + if (eleTag < 0) { + opserr << "PartitionedDomain::addElement - Element " << eleTag; + opserr << " tag must be >= 0\n"; + return false; + } + + // check its not in this or any of the subdomains + // MISSING CODE + + // check all the elements nodes exist in the domain + const ID &nodes = elePtr->getExternalNodes(); + for (int i = 0; i < nodes.Size(); i++) { + int nodeTag = nodes(i); + Node *nodePtr = this->getNode(nodeTag); + if (nodePtr == 0) { + opserr << "PartitionedDomain::addElement - In element " << eleTag; + opserr << " no node " << nodeTag << " exists in the domain\n"; + return false; } - - return result; -} + } + +#endif + + TaggedObject *other = elements->getComponentPtr(eleTag); + if (other != 0) + return false; + + bool result = elements->addComponent(elePtr); + if (result == true) { + elePtr->setDomain(this); + elePtr->update(); + this->domainChange(); + } + return result; +} -bool + +bool PartitionedDomain::addNode(Node *nodePtr) { -#ifdef _DEBUG - +#ifdef _DEBUG + #endif - return (this->Domain::addNode(nodePtr)); + return (this->Domain::addNode(nodePtr)); } @@ -249,7 +258,16 @@ PartitionedDomain::addSP_Constraint(SP_Constraint *load) { int nodeTag = load->getNodeTag(); bool ok = false; - + + if (!has_sent_yet) + { + Node *nodePtr = this->getNode(nodeTag); + if (nodePtr != 0) { + return this->Domain::addSP_Constraint(load); + } else + return false; + } + // check the Node exists in the Domain or one of Subdomains // if in Domain add it as external .. ignore Subdomains @@ -269,9 +287,9 @@ PartitionedDomain::addSP_Constraint(SP_Constraint *load) if (res == true) { ok = theSub->addSP_Constraint(load); if (ok == false) { - opserr << "PartitiondDomain::addSP - failed to add to remote subdomain\n"; - load->Print(opserr); - return ok; + opserr << "PartitiondDomain::addSP - failed to add to remote subdomain\n"; + load->Print(opserr); + return ok; } } } @@ -279,30 +297,34 @@ PartitionedDomain::addSP_Constraint(SP_Constraint *load) // if no subdomain .. node not in model .. error message and return failure if (ok == false) { opserr << "PartitionedDomain::addSP_Constraint - cannot add as node with tag" << - nodeTag << "does not exist in model\n"; + nodeTag << "does not exist in model\n"; } - + return ok; } int -PartitionedDomain::addSP_Constraint(int axisDirn, double axisValue, - const ID &fixityCodes, double tol) +PartitionedDomain::addSP_Constraint(int axisDirn, double axisValue, + const ID &fixityCodes, double tol) { - int nextTag = 0; int numAdded = 0; numAdded = this->Domain::addSP_Constraint(axisDirn, axisValue, fixityCodes, tol); + if (!has_sent_yet) + { + return numAdded; + } + // find subdomain with node and add it .. break if find as internal node SubdomainIter &theSubdomains = this->getSubdomains(); Subdomain *theSub; while ((theSub = theSubdomains()) != 0) { - numAdded += theSub->addSP_Constraint(axisDirn, axisValue, fixityCodes, tol); + numAdded += theSub->addSP_Constraint(axisDirn, axisValue, fixityCodes, tol); } - + return numAdded; } @@ -319,10 +341,15 @@ PartitionedDomain::addSP_Constraint(SP_Constraint *load, int pattern) Node *nodePtr = this->getNode(nodeTag); if (nodePtr != 0) { ok = this->Domain::addSP_Constraint(load, pattern); - if (ok == false) + if (ok == false) return false; } + if (!has_sent_yet) + { + return ok; + } + // find subdomain with node and add it .. break if find as internal node SubdomainIter &theSubdomains = this->getSubdomains(); Subdomain *theSub; @@ -331,15 +358,15 @@ PartitionedDomain::addSP_Constraint(SP_Constraint *load, int pattern) if (res == true) { ok = theSub->addSP_Constraint(load, pattern); if (ok == false) - return false; + return false; } } - + // if no subdomain .. node not in model .. error message and return failure if (ok == false) { opserr << "PartitionedDomain::addSP_Constraint - cannot add as node with tag" << - nodeTag << "does not exist in model\n"; + nodeTag << "does not exist in model\n"; } return ok; @@ -368,20 +395,25 @@ PartitionedDomain::addMP_Constraint(MP_Constraint *load) { Node *constrainedNodePtr = this->Domain::getNode(constrainedNodeTag); if (constrainedNodePtr != 0) { if (retainedNodePtr != 0) { - - res = this->Domain::addMP_Constraint(load); + + res = this->Domain::addMP_Constraint(load); if (res == false) { - opserr << "PartitionedDomain::addMP_Constraint - problems adding to main domain\n"; - return res; + opserr << "PartitionedDomain::addMP_Constraint - problems adding to main domain\n"; + return res; } else { - addedMain = true; - } - + addedMain = true; + } + } else { getRetained = true; } } + if (!has_sent_yet) + { + return addedMain; + } + // // now we check all subdomains // if a subdomain has both nodes we add the constraint, if only the @@ -400,16 +432,16 @@ PartitionedDomain::addMP_Constraint(MP_Constraint *load) { if (hasRestrained == true) { - res = theSub->addMP_Constraint(load); + res = theSub->addMP_Constraint(load); - if (res == false) { - opserr << "PartitionedDomain::addMP_Constraint - problems adding to subdomain with retained\n"; - return res; - } else { - ; - } + if (res == false) { + opserr << "PartitionedDomain::addMP_Constraint - problems adding to subdomain with retained\n"; + return res; + } else { + ; + } } else { - getRetained = true; + getRetained = true; } } } @@ -420,7 +452,7 @@ PartitionedDomain::addMP_Constraint(MP_Constraint *load) { // 1. we first go get it // 2. then we add to main domain // 3. then we add to any subdomain - // + // if (getRetained == true) { @@ -428,29 +460,29 @@ PartitionedDomain::addMP_Constraint(MP_Constraint *load) { if (retainedNodePtr == 0) { SubdomainIter &theSubdomains2 = this->getSubdomains(); while ((theSub = theSubdomains2()) != 0 && retainedNodePtr == 0) { - - bool hasRestrained = theSub->hasNode(retainedNodeTag); - - if (hasRestrained == true) { - retainedNodePtr = theSub->getNode(retainedNodeTag); - - Matrix mass(retainedNodePtr->getNumberDOF(), retainedNodePtr->getNumberDOF()); - mass.Zero(); - retainedNodePtr->setMass(mass); - } + + bool hasRestrained = theSub->hasNode(retainedNodeTag); + + if (hasRestrained == true) { + retainedNodePtr = theSub->getNode(retainedNodeTag); + + Matrix mass(retainedNodePtr->getNumberDOF(), retainedNodePtr->getNumberDOF()); + mass.Zero(); + retainedNodePtr->setMass(mass); + } } } else { // get a copy & zero the mass retainedNodePtr = new Node(*retainedNodePtr, false); } - + if (retainedNodePtr == 0) { opserr << "partitionedDomain::addMP_Constraint - can't find retained node anywhere!\n"; return false; } else { ; } - + // // if main has it we add the retained to main & constraint // @@ -459,17 +491,17 @@ PartitionedDomain::addMP_Constraint(MP_Constraint *load) { res = this->Domain::addNode(retainedNodePtr); if (res == false) { - opserr << "PartitionedDomain::addMP_Constraint - problems adding retained to main domain\n"; - return res; - } + opserr << "PartitionedDomain::addMP_Constraint - problems adding retained to main domain\n"; + return res; + } res = this->Domain::addMP_Constraint(load); - + if (res == false) { - opserr << "PartitionedDomain::addMP_Constraint - problems adding constraint to main domain after adding node\n"; - return res; - } + opserr << "PartitionedDomain::addMP_Constraint - problems adding constraint to main domain after adding node\n"; + return res; + } } - + // // to subdmains that have the constrained but no retained // 1. we add a copy of retained @@ -480,29 +512,29 @@ PartitionedDomain::addMP_Constraint(MP_Constraint *load) { while ((theSub = theSubdomains3()) != 0) { bool hasConstrained = theSub->hasNode(constrainedNodeTag); if (hasConstrained == true) { - - bool hasRestrained = theSub->hasNode(retainedNodeTag); - if (hasRestrained == false) { - - res = theSub->addExternalNode(retainedNodePtr); - - if (res == false) { - opserr << "PartitionedDomain::addMP_Constraint - problems adding retained to subdomain\n"; - return res; - } - - res = theSub->addMP_Constraint(load); - - if (res == false) { - opserr << "PartitionedDomain::addMP_Constraint - problems adding constraint to subdomain after adding node\n"; - return res; - } - } + + bool hasRestrained = theSub->hasNode(retainedNodeTag); + if (hasRestrained == false) { + + res = theSub->addExternalNode(retainedNodePtr); + + if (res == false) { + opserr << "PartitionedDomain::addMP_Constraint - problems adding retained to subdomain\n"; + return res; + } + + res = theSub->addMP_Constraint(load); + + if (res == false) { + opserr << "PartitionedDomain::addMP_Constraint - problems adding constraint to subdomain after adding node\n"; + return res; + } + } } } // clean up memory - if (addedMain == true && getRetained == true) + if (addedMain == true && getRetained == true) delete retainedNodePtr; } @@ -512,7 +544,7 @@ PartitionedDomain::addMP_Constraint(MP_Constraint *load) { } -bool +bool PartitionedDomain::addLoadPattern(LoadPattern *loadPattern) { bool result = true; @@ -520,40 +552,47 @@ PartitionedDomain::addLoadPattern(LoadPattern *loadPattern) int tag = loadPattern->getTag(); if (this->getLoadPattern(tag) != 0) { opserr << "PartitionedDomain::addLoadPattern - cannot add as LoadPattern with tag" << - tag << "already exists in model\n"; + tag << "already exists in model\n"; return false; } - SubdomainIter &theSubdomains = this->getSubdomains(); - Subdomain *theSub; - while ((theSub = theSubdomains()) != 0) { - bool res = theSub->addLoadPattern(loadPattern); - if (res != true) { - opserr << "PartitionedDomain::addLoadPattern - cannot add as LoadPattern with tag: " << - tag << " to subdomain\n"; - result = res; + if (has_sent_yet) + { + SubdomainIter &theSubdomains = this->getSubdomains(); + Subdomain *theSub; + while ((theSub = theSubdomains()) != 0) { + bool res = theSub->addLoadPattern(loadPattern); + if (res != true) { + opserr << "PartitionedDomain::addLoadPattern - cannot add as LoadPattern with tag: " << + tag << " to subdomain\n"; + result = res; + } } } this->Domain::addLoadPattern(loadPattern); return result; -} +} -bool +bool PartitionedDomain::addNodalLoad(NodalLoad *load, int pattern) { int nodeTag = load->getNodeTag(); - + // check the Node exists in the Domain or one of Subdomains // if in Domain add it as external .. ignore Subdomains Node *nodePtr = this->getNode(nodeTag); if (nodePtr != 0) { - return (this->Domain::addNodalLoad(load, pattern)); + return (this->Domain::addNodalLoad(load, pattern)); } + if (!has_sent_yet) + { + return false; + } // find subdomain with node and add it .. break if find as internal node SubdomainIter &theSubdomains = this->getSubdomains(); @@ -568,24 +607,28 @@ PartitionedDomain::addNodalLoad(NodalLoad *load, int pattern) // if no subdomain .. node not in model opserr << "PartitionedDomain::addNodalLoad - cannot add as node with tag" << - nodeTag << "does not exist in model\n"; + nodeTag << "does not exist in model\n"; return false; -} +} -bool +bool PartitionedDomain::addElementalLoad(ElementalLoad *load, int pattern) { int eleTag = load->getElementTag(); - + // check the Node exists in the Domain or one of Subdomains // if in Domain add it as external .. ignore Subdomains Element *elePtr = this->getElement(eleTag); if (elePtr != 0) { - return (this->Domain::addElementalLoad(load, pattern)); + return (this->Domain::addElementalLoad(load, pattern)); } + if (!has_sent_yet) + { + return false; + } // find subdomain with node and add it .. break if find as internal node SubdomainIter &theSubdomains = this->getSubdomains(); @@ -600,7 +643,7 @@ PartitionedDomain::addElementalLoad(ElementalLoad *load, int pattern) // if no subdomain .. node not in model opserr << "PartitionedDomain::addElementalLoad - cannot add as element with tag" << - eleTag << "does not exist in model\n"; + eleTag << "does not exist in model\n"; return false; } @@ -609,101 +652,119 @@ PartitionedDomain::addElementalLoad(ElementalLoad *load, int pattern) Element * PartitionedDomain::removeElement(int tag) { - // we first see if its in the original domain - TaggedObject *res = elements->removeComponent(tag); - Element *result = 0; - if (res != 0) { - result = (Element *)res; - this->domainChange(); - return result; - } - // if not there we must check all the other subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - result = theSub->removeElement(tag); - if (result != 0) { - return result; - } - } - } - - // its not there + // opserr << " PartitionedDomain::removeElement() - Removing element with tag " << tag << endln; + // we first see if its in the original domain + TaggedObject *res = elements->removeComponent(tag); + Element *result = 0; + if (res != 0) { + result = (Element *)res; + this->domainChange(); + return result; + } + if (!has_sent_yet) + { return 0; -} + } + // opserr << " PartitionedDomain::removeElement() - Searching subdomains for element # " << tag << endln; + + // if not there we must check all the other subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + result = theSub->removeElement(tag); + if (result != 0) { + return result; + } + } + } + // opserr << " PartitionedDomain::removeElement() - element not found, tag = " << tag << endln; + + // its not there + return 0; +} Node * -PartitionedDomain::removeNode(int tag) +PartitionedDomain::removeNode(int tag) { - // we first remove it form the original domain (in case on boundary) - Node *result = this->Domain::removeNode(tag); - - // we must also try removing from the subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - Node *res = theSub->removeNode(tag); - if (res != 0) - result = res; - } - } - - if (result != 0) - this->domainChange(); - + // we first remove it form the original domain (in case on boundary) + Node *result = this->Domain::removeNode(tag); + if (!has_sent_yet) + { return result; -} + } + // we must also try removing from the subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + Node *res = theSub->removeNode(tag); + if (res != 0) + result = res; + } + } + + if (result != 0) + this->domainChange(); + + return result; +} SP_Constraint * PartitionedDomain::removeSP_Constraint(int tag) { - // we first see if its in the original domain - SP_Constraint *result = this->Domain::removeSP_Constraint(tag); - if (result != 0) { - this->domainChange(); - return result; + // we first see if its in the original domain + SP_Constraint *result = this->Domain::removeSP_Constraint(tag); + if (result != 0) { + this->domainChange(); + return result; + } + if (!has_sent_yet) + { + return result; + } + + // if not there we must check all the other subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + result = theSub->removeSP_Constraint(tag); + if (result != 0) { + return result; + } } - + } - // if not there we must check all the other subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - result = theSub->removeSP_Constraint(tag); - if (result != 0) { - return result; - } - } - } - - // its not there - return 0; + // its not there + return 0; } -int +int PartitionedDomain::removeSP_Constraint(int nodeTag, int dof, int loadPatternTag) { // we first see if its in the original domain int result = this->Domain::removeSP_Constraint(nodeTag, dof, loadPatternTag); + if (!has_sent_yet) + { + return result; + } // if not there we must check all the other subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; result += theSub->removeSP_Constraint(nodeTag, dof, loadPatternTag); - } + } } if (result != 0) { @@ -711,7 +772,7 @@ PartitionedDomain::removeSP_Constraint(int nodeTag, int dof, int loadPatternTag) } // its not there - return result; + return result; } @@ -719,160 +780,171 @@ PartitionedDomain::removeSP_Constraint(int nodeTag, int dof, int loadPatternTag) MP_Constraint * PartitionedDomain::removeMP_Constraint(int tag) { - // we first see if its in the original domain - MP_Constraint *result = this->Domain::removeMP_Constraint(tag); - if (result != 0) { - this->domainChange(); - return result; + // we first see if its in the original domain + MP_Constraint *result = this->Domain::removeMP_Constraint(tag); + if (result != 0) { + this->domainChange(); + return result; + } + if (!has_sent_yet) + { + return result; + } + + // if not there we must check all the other subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + result = theSub->removeMP_Constraint(tag); + if (result != 0) { + return result; + } } + } - // if not there we must check all the other subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - result = theSub->removeMP_Constraint(tag); - if (result != 0) { - return result; - } - } - } - - // its not there - return 0; + // its not there + return 0; } int PartitionedDomain::removeMP_Constraints(int tag) { - // we first see if its in the original domain - int result = this->Domain::removeMP_Constraints(tag); - - // if not there we must check all the other subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - result += theSub->removeMP_Constraints(tag); - } - } - - if (result != 0) { - this->domainChange(); - } - - // its not there + // we first see if its in the original domain + int result = this->Domain::removeMP_Constraints(tag); + if (!has_sent_yet) + { return result; + } + // if not there we must check all the other subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + result += theSub->removeMP_Constraints(tag); + } + } + + if (result != 0) { + this->domainChange(); + } + + // its not there + return result; } -LoadPattern * +LoadPattern * PartitionedDomain::removeLoadPattern(int tag) { - // we first see if its in the original domain - LoadPattern *result = this->Domain::removeLoadPattern(tag); + // we first see if its in the original domain + LoadPattern *result = this->Domain::removeLoadPattern(tag); + if (!has_sent_yet) + { + return result; + } - // we must also try removing from the subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - LoadPattern *res = theSub->removeLoadPattern(tag); - if (res != 0) - result = res; - } + // we must also try removing from the subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + LoadPattern *res = theSub->removeLoadPattern(tag); + if (res != 0) + result = res; } - - if (result != 0) - this->domainChange(); - - return result; -} + } + + if (result != 0) + this->domainChange(); + + return result; +} // public member functions which have to be modified ElementIter & PartitionedDomain::getElements() { - theEleIter->reset(); - return *theEleIter; -} + theEleIter->reset(); + return *theEleIter; +} Element * -PartitionedDomain::getElement(int tag) +PartitionedDomain::getElement(int tag) { - // we first see if its in the original domain - TaggedObject *res = elements->getComponentPtr(tag); - Element *result =0; - if (res != 0) { - result = (Element *)res; - return result; - } + // we first see if its in the original domain + TaggedObject *res = elements->getComponentPtr(tag); + Element *result = 0; + if (res != 0) { + result = (Element *)res; + return result; + } - /* - // go through the other subdomains until we find it or we run out of subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - result = theSub->getElement(tag); - if (result != 0) - return result; - } - } - */ - - // its not there - return 0; + /* + // go through the other subdomains until we find it or we run out of subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + result = theSub->getElement(tag); + if (result != 0) + return result; + } + } + */ + + // its not there + return 0; } -int +int PartitionedDomain::getNumElements(void) const { - int result = elements->getNumComponents(); + int result = elements->getNumComponents(); - // add the number of subdomains - result += theSubdomains->getNumComponents(); - return result; + // add the number of subdomains + result += theSubdomains->getNumComponents(); + return result; } void PartitionedDomain::applyLoad(double timeStep) { - this->Domain::applyLoad(timeStep); + this->Domain::applyLoad(timeStep); - // do the same for all the subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - theSub->applyLoad(timeStep); - } + // do the same for all the subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + theSub->applyLoad(timeStep); } + } } void PartitionedDomain::setCommitTag(int newTag) { - this->Domain::setCommitTag(newTag); + this->Domain::setCommitTag(newTag); - // do the same for all the subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - theSub->setCommitTag(newTag); - } + // do the same for all the subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + theSub->setCommitTag(newTag); } + } } @@ -880,69 +952,69 @@ PartitionedDomain::setCommitTag(int newTag) void PartitionedDomain::setCurrentTime(double newTime) { - this->Domain::setCurrentTime(newTime); + this->Domain::setCurrentTime(newTime); - // do the same for all the subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - theSub->setCurrentTime(newTime); - } + // do the same for all the subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + theSub->setCurrentTime(newTime); } + } } void PartitionedDomain::setCommittedTime(double newTime) { - this->Domain::setCommittedTime(newTime); + this->Domain::setCommittedTime(newTime); - // do the same for all the subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - theSub->setCommittedTime(newTime); - } + // do the same for all the subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + theSub->setCommittedTime(newTime); } + } } void PartitionedDomain::setLoadConstant(void) { - this->Domain::setLoadConstant(); + this->Domain::setLoadConstant(); - // do the same for all the subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - theSub->setLoadConstant(); - } + // do the same for all the subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + theSub->setLoadConstant(); } + } } int PartitionedDomain::setRayleighDampingFactors(double alphaM, double betaK, double betaK0, double betaKc) { - this->Domain::setRayleighDampingFactors(alphaM, betaK, betaK0, betaKc); + this->Domain::setRayleighDampingFactors(alphaM, betaK, betaK0, betaKc); - // do the same for all the subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - theSub->setRayleighDampingFactors(alphaM, betaK, betaK0, betaKc); - } + // do the same for all the subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + theSub->setRayleighDampingFactors(alphaM, betaK, betaK0, betaKc); } - return 0; + } + return 0; } @@ -953,17 +1025,17 @@ PartitionedDomain::update(void) // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; theSub->computeNodalResponse(); res += theSub->update(); } } #ifdef _PARALLEL_PROCESSING - // opserr << "PartitionedDomain:: barrierCheck\n"; +// opserr << "PartitionedDomain:: barrierCheck\n"; return this->barrierCheck(res); #endif return res; @@ -978,18 +1050,18 @@ PartitionedDomain::barrierCheck(int res) // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; int subResult = theSub->barrierCheckIN(); if (subResult != 0) - result = subResult; + result = subResult; } - ArrayOfTaggedObjectsIter theSubsIter1(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter1(*theSubdomains); while ((theObject = theSubsIter1()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; theSub->barrierCheckOUT(result); } } @@ -1006,12 +1078,12 @@ PartitionedDomain::update(double newTime, double dT) // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; theSub->computeNodalResponse(); - res +=theSub->update(newTime, dT); + res += theSub->update(newTime, dT); } } @@ -1032,10 +1104,10 @@ PartitionedDomain::update(double newTime, double dT) // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; theSub->update(newTime, dT); } this->barrierCheck(result); @@ -1043,7 +1115,7 @@ PartitionedDomain::update(double newTime, double dT) opserr << "PartitionedDomain::update(double newTime, double dT) -3\n"; return result; -*/ + */ } @@ -1062,24 +1134,24 @@ PartitionedDomain::analysisStep(double dT) if (domainChangedAnySubdomain == false) { // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while (((theObject = theSubsIter()) != 0) && (domainChangedAnySubdomain == false)) { - Subdomain *theSub = (Subdomain *)theObject; - domainChangedAnySubdomain = theSub->getDomainChangeFlag(); - } + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while (((theObject = theSubsIter()) != 0) && (domainChangedAnySubdomain == false)) { + Subdomain *theSub = (Subdomain *)theObject; + domainChangedAnySubdomain = theSub->getDomainChangeFlag(); + } } } if (domainChangedAnySubdomain == true) { this->Domain::domainChange(); if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while (((theObject = theSubsIter()) != 0) && (domainChangedAnySubdomain == false)) { - Subdomain *theSub = (Subdomain *)theObject; - theSub->domainChange(); - } + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while (((theObject = theSubsIter()) != 0) && (domainChangedAnySubdomain == false)) { + Subdomain *theSub = (Subdomain *)theObject; + theSub->domainChange(); + } } } @@ -1088,13 +1160,13 @@ PartitionedDomain::analysisStep(double dT) int res = 0; // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; res += theSub->analysisStep(dT); - if (res != 0) - opserr << "PartitionedDomain::step - subdomain " << theSub->getTag() << " failed in step\n"; + if (res != 0) + opserr << "PartitionedDomain::step - subdomain " << theSub->getTag() << " failed in step\n"; } } return res; @@ -1110,39 +1182,39 @@ PartitionedDomain::eigenAnalysis(int numModes, bool generalized, bool findSmalle if (domainChangedAnySubdomain == false) { // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while (((theObject = theSubsIter()) != 0) && (domainChangedAnySubdomain == false)) { - Subdomain *theSub = (Subdomain *)theObject; - domainChangedAnySubdomain = theSub->getDomainChangeFlag(); - } + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while (((theObject = theSubsIter()) != 0) && (domainChangedAnySubdomain == false)) { + Subdomain *theSub = (Subdomain *)theObject; + domainChangedAnySubdomain = theSub->getDomainChangeFlag(); + } } } if (domainChangedAnySubdomain == true) { this->Domain::domainChange(); if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while (((theObject = theSubsIter()) != 0) && (domainChangedAnySubdomain == false)) { - Subdomain *theSub = (Subdomain *)theObject; - theSub->domainChange(); - } + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while (((theObject = theSubsIter()) != 0) && (domainChangedAnySubdomain == false)) { + Subdomain *theSub = (Subdomain *)theObject; + theSub->domainChange(); + } } } this->Domain::eigenAnalysis(numModes, generalized, findSmallest); - + int res = 0; // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; res += theSub->eigenAnalysis(numModes, generalized, findSmallest); - if (res != 0) - opserr << "PartitionedDomain::step - subdomain " << theSub->getTag() << " failed in step\n"; + if (res != 0) + opserr << "PartitionedDomain::step - subdomain " << theSub->getTag() << " failed in step\n"; } } return res; @@ -1156,15 +1228,15 @@ PartitionedDomain::record(bool fromAnalysis) // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; result += theSub->record(fromAnalysis); if (result < 0) { - opserr << "PartitionedDomain::record(void)"; - opserr << " - failed in Subdomain::record()\n"; - } + opserr << "PartitionedDomain::record(void)"; + opserr << " - failed in Subdomain::record()\n"; + } } } @@ -1178,6 +1250,15 @@ PartitionedDomain::commit(void) { int result = this->Domain::commit(); + // static int ctag=0; + // char buffer[50]; + // sprintf(buffer, "domaininfo_%d.txt", ctag++); + // FileStream fid(buffer); + + // fid << "MAIN DOMAIN --------------------------------------------------\n\n"; + + // this->Print(fid); + if (result < 0) { opserr << "PartitionedDomain::commit(void) - failed in Domain::commit()\n"; return result; @@ -1185,22 +1266,29 @@ PartitionedDomain::commit(void) // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; int res = theSub->commit(); + // fid << "Sub-Domain # " << theSub->getTag() << " --------------------------------------------------\n\n"; + // theSub->Print(fid); + if (res < 0) { - opserr << "PartitionedDomain::commit(void)"; - opserr << " - failed in Subdomain::commit()\n"; - return res; - } + opserr << "PartitionedDomain::commit(void)"; + opserr << " - failed in Subdomain::commit()\n"; + return res; + } } } + // opserr << "Subdomain # MASTER " << " update_time = " << this->Domain::update_time_committed << endln; + + // now we load balance if we have subdomains and a partitioner int numSubdomains = this->getNumSubdomains(); if (numSubdomains != 0 && theDomainPartitioner != 0) { + // opserr << "Subdomain # MASTER " << " BALANCING! " << endln; Graph &theSubGraphs = this->getSubdomainGraph(); theDomainPartitioner->balance(theSubGraphs); } @@ -1212,96 +1300,102 @@ PartitionedDomain::commit(void) int PartitionedDomain::revertToLastCommit(void) { - int result = this->Domain::revertToLastCommit(); - if (result < 0) { - opserr << "PartitionedDomain::revertToLastCommit(void) - failed in Domain::revertToLastCommit()\n"; - return result; - } + int result = this->Domain::revertToLastCommit(); + if (result < 0) { + opserr << "PartitionedDomain::revertToLastCommit(void) - failed in Domain::revertToLastCommit()\n"; + return result; + } - // do the same for all the subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - int res = theSub->revertToLastCommit(); - if (res < 0) { - opserr << "PartitionedDomain::revertToLastCommit(void)"; - opserr << " - failed in Subdomain::revertToLastCommit()\n"; - return res; - } - } + // do the same for all the subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + int res = theSub->revertToLastCommit(); + if (res < 0) { + opserr << "PartitionedDomain::revertToLastCommit(void)"; + opserr << " - failed in Subdomain::revertToLastCommit()\n"; + return res; + } } + } - return 0; + return 0; } int PartitionedDomain::revertToStart(void) { - int result = this->Domain::revertToStart(); - if (result < 0) { - opserr << "PartitionedDomain::revertToLastCommit(void) - failed in Domain::revertToLastCommit()\n"; - return result; - } + int result = this->Domain::revertToStart(); + if (result < 0) { + opserr << "PartitionedDomain::revertToLastCommit(void) - failed in Domain::revertToLastCommit()\n"; + return result; + } - // do the same for all the subdomains - if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - int res = theSub->revertToStart(); - if (res < 0) { - opserr << "PartitionedDomain::revertToLastCommit(void)"; - opserr << " - failed in Subdomain::revertToLastCommit()\n"; - return res; - } - } + // do the same for all the subdomains + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + int res = theSub->revertToStart(); + if (res < 0) { + opserr << "PartitionedDomain::revertToLastCommit(void)"; + opserr << " - failed in Subdomain::revertToLastCommit()\n"; + return res; + } } + } - return 0; + return 0; } -int +int PartitionedDomain::addRecorder(Recorder &theRecorder) { - if (this->Domain::addRecorder(theRecorder) < 0) + int result = this->Domain::addRecorder(theRecorder); + if (result < 0) return -1; + if (!has_sent_yet) + { + return result; + } + // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; int res = theSub->addRecorder(theRecorder); if (res < 0) { - opserr << "PartitionedDomain::revertToLastCommit(void)"; - opserr << " - failed in Subdomain::revertToLastCommit()\n"; - return res; - } + opserr << "PartitionedDomain::revertToLastCommit(void)"; + opserr << " - failed in Subdomain::revertToLastCommit()\n"; + return res; + } } } return 0; } -int +int PartitionedDomain::removeRecorders(void) { // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; int res = theSub->removeRecorders(); if (res < 0) { - opserr << "PartitionedDomain::removeRecorders(void)"; - opserr << " - failed in Subdomain::removeRecorders()\n"; - return res; - } + opserr << "PartitionedDomain::removeRecorders(void)"; + opserr << " - failed in Subdomain::removeRecorders()\n"; + return res; + } } } @@ -1314,7 +1408,7 @@ PartitionedDomain::removeRecorders(void) } -int +int PartitionedDomain::removeRecorder(int tag) { if (this->Domain::removeRecorder(tag) < 0) @@ -1322,29 +1416,29 @@ PartitionedDomain::removeRecorder(int tag) // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; int res = theSub->removeRecorder(tag); if (res < 0) { - opserr << "PartitionedDomain::removeRecorder(void)"; - opserr << " - failed in Subdomain::removeRecorder()\n"; - return res; - } + opserr << "PartitionedDomain::removeRecorder(void)"; + opserr << " - failed in Subdomain::removeRecorder()\n"; + return res; + } } } return 0; } -void +void PartitionedDomain::Print(OPS_Stream &s, int flag) { this->Domain::Print(s, flag); s << "\nELEMENT DATA: NumEle: " << elements->getNumComponents() << "\n"; elements->Print(s); - + // print all the subdomains if (theSubdomains != 0) { ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); @@ -1356,7 +1450,7 @@ PartitionedDomain::Print(OPS_Stream &s, int flag) } -void +void PartitionedDomain::Print(OPS_Stream &s, ID *nodeTags, ID *eleTags, int flag) { if (nodeTags != 0) @@ -1364,21 +1458,21 @@ PartitionedDomain::Print(OPS_Stream &s, ID *nodeTags, ID *eleTags, int flag) if (eleTags != 0) { int numEle = eleTags->Size(); - for (int i=0; igetComponentPtr(eleTag); if (theEle != 0) - theEle->Print(s, flag); + theEle->Print(s, flag); } } - + // print all the subdomains if (theSubdomains != 0) { ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; theSub->Print(s, nodeTags, eleTags, flag); } } @@ -1386,24 +1480,25 @@ PartitionedDomain::Print(OPS_Stream &s, ID *nodeTags, ID *eleTags, int flag) -int +int PartitionedDomain::setPartitioner(DomainPartitioner *thePartitioner) { theDomainPartitioner = thePartitioner; + return 0; } -int +int PartitionedDomain::partition(int numPartitions, bool usingMain, int mainPartitionID, int specialElementTag) { int result = 0; // need to create element graph before create new subdomains // DO NOT REMOVE THIS LINE __ EVEN IF COMPILER WARNING ABOUT UNUSED VARIABLE Graph &theEleGraph = this->getElementGraph(); - + // now we call partition on the domainPartitioner which does the partitioning - DomainPartitioner *thePartitioner = this->getPartitioner(); + DomainPartitioner *thePartitioner = 0;//this->getPartitioner(); if (thePartitioner != 0) { thePartitioner->setPartitionedDomain(*this); result = thePartitioner->partition(numPartitions, usingMain, mainPartitionID, specialElementTag); @@ -1411,28 +1506,28 @@ PartitionedDomain::partition(int numPartitions, bool usingMain, int mainPartitio opserr << "PartitionedDomain::partition(int numPartitions) - no associated partitioner\n"; return -1; } - + // // add recorder objects // // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - for (int i=0; iaddRecorder(*theRecorders[i]); - if (res != 0) { - opserr << "PartitionedDomain::partition(void)"; - opserr << " - failed to add Recorder to subdomain\n"; - return res; - } - } + Subdomain *theSub = (Subdomain *)theObject; + for (int i = 0; i < numRecorders; i++) { + int res = theSub->addRecorder(*theRecorders[i]); + if (res != 0) { + opserr << "PartitionedDomain::partition(void)"; + opserr << " - failed to add Recorder to subdomain\n"; + return res; + } + } } } - + // // add parameters // @@ -1440,63 +1535,75 @@ PartitionedDomain::partition(int numPartitions, bool usingMain, int mainPartitio Parameter *theParameter; while ((theParameter = theParameters()) != 0) { if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - int res = theSub->addParameter(theParameter); - if (res != 0) { - opserr << "PartitionedDomain::partition(void)"; - opserr << " - failed to add Parameter to subdomain\n"; - return res; - } - } + Subdomain *theSub = (Subdomain *)theObject; + int res = theSub->addParameter(theParameter); + if (res != 0) { + opserr << "PartitionedDomain::partition(void)"; + opserr << " - failed to add Parameter to subdomain\n"; + return res; + } + } } theParameter->setDomain(this); // needed as some components will move } + has_sent_yet = true; + return result; } -bool +int PartitionedDomain::repartition(int numPartitions, bool usingMain, int mainPartitionID, int specialElementTag) +{ + opserr << "PartitionedDomain::repartition() - On Master Process\n"; + + + + return 0; +} + + +bool PartitionedDomain::addSubdomain(Subdomain *theSubdomain) { - int eleTag = theSubdomain->getTag(); - TaggedObject *other = theSubdomains->getComponentPtr(eleTag); - if (other != 0) - return false; - - bool result = theSubdomains->addComponent(theSubdomain); - if (result == true) { - theSubdomain->setDomain(this); - this->domainChange(); - } - + int eleTag = theSubdomain->getTag(); + TaggedObject *other = theSubdomains->getComponentPtr(eleTag); + if (other != 0) + return false; + + bool result = theSubdomains->addComponent(theSubdomain); + if (result == true) { + theSubdomain->setDomain(this); + this->domainChange(); + } + return result; } -int +int PartitionedDomain::getNumSubdomains(void) { - return theSubdomains->getNumComponents(); + return theSubdomains->getNumComponents(); } - + Subdomain * PartitionedDomain::getSubdomainPtr(int tag) { - TaggedObject *mc = theSubdomains->getComponentPtr(tag); - if (mc == 0) return 0; - Subdomain *result = (Subdomain *)mc; - return result; -} + TaggedObject *mc = theSubdomains->getComponentPtr(tag); + if (mc == 0) return 0; + Subdomain *result = (Subdomain *)mc; + return result; +} SubdomainIter & PartitionedDomain::getSubdomains(void) { - theSubdomainIter->reset(); - return *theSubdomainIter; + theSubdomainIter->reset(); + return *theSubdomainIter; } @@ -1504,169 +1611,176 @@ PartitionedDomain::getSubdomains(void) DomainPartitioner * PartitionedDomain::getPartitioner(void) const { - return theDomainPartitioner; + return theDomainPartitioner; } - -int + +int PartitionedDomain::buildEleGraph(Graph *theEleGraph) { - // see if quick return - int numVertex = this->getNumElements(); - if (numVertex == 0) - return 0; + // see if quick return + int numVertex = this->getNumElements(); + if (numVertex == 0) + return 0; - // - // iterate over the lements of the domain - // create a vertex with a unique tag for each element - // also create a map to hold element tag - vertex tag mapping - // + // + // iterate over the lements of the domain + // create a vertex with a unique tag for each element + // also create a map to hold element tag - vertex tag mapping + // - MAP_INT theEleToVertexMap; - MAP_INT_ITERATOR theEleToVertexMapEle; + MAP_INT theEleToVertexMap; + MAP_INT_ITERATOR theEleToVertexMapEle; - TaggedObject *theTagged; - TaggedObjectIter &theElements = elements->getComponents(); - int count = START_VERTEX_NUM; - while ((theTagged = theElements()) != 0) { - int eleTag = theTagged->getTag(); - Vertex *vertexPtr = new Vertex(count, eleTag); + TaggedObject *theTagged; + TaggedObjectIter &theElements = elements->getComponents(); + int count = START_VERTEX_NUM; + while ((theTagged = theElements()) != 0) { + int eleTag = theTagged->getTag(); + Vertex *vertexPtr = new Vertex(count, eleTag); - if (vertexPtr == 0) { - opserr << "WARNING Domain::buildEleGraph - Not Enough Memory to create the " << count << " vertex\n"; - return -1; - } + if (vertexPtr == 0) { + opserr << "WARNING Domain::buildEleGraph - Not Enough Memory to create the " << count << " vertex\n"; + return -1; + } - theEleGraph->addVertex(vertexPtr); - theEleToVertexMapEle = theEleToVertexMap.find(eleTag); - if (theEleToVertexMapEle == theEleToVertexMap.end()) { - theEleToVertexMap.insert(MAP_INT_TYPE(eleTag, count)); + // Get the compute cost and communications cost. + Element * theElement = static_cast(theTagged); + double eleWeight = (double) theElement->getNumDOF(); //theElement->getTime(); + int eleCommCost = 0;//theElement->getMoveCost(); + vertexPtr->setWeight(eleWeight); + // vertexPtr->setTmp(eleCommCost); - // check if successfully added - theEleToVertexMapEle = theEleToVertexMap.find(eleTag); - if (theEleToVertexMapEle == theEleToVertexMap.end()) { - opserr << "Domain::buildEleGraph - map STL failed to add object with tag : " << eleTag << endln; - return false; - } + theEleGraph->addVertex(vertexPtr); + theEleToVertexMapEle = theEleToVertexMap.find(eleTag); + if (theEleToVertexMapEle == theEleToVertexMap.end()) { + theEleToVertexMap.insert(MAP_INT_TYPE(eleTag, count)); - count++; + // check if sucessfully added + theEleToVertexMapEle = theEleToVertexMap.find(eleTag); + if (theEleToVertexMapEle == theEleToVertexMap.end()) { + opserr << "Domain::buildEleGraph - map STL failed to add object with tag : " << eleTag << endln; + return false; } + + count++; } + } - // - // We now need to determine which elements are associated with each node. - // As this info is not in the Node interface we must build it; - // - // again we will use an stl map, index will be nodeTag, object will be Vertex - // do using vertices for each node, when we addVertex at these nodes we - // will not be adding vertices but element tags. - // + // + // We now need to determine which elements are asssociated with each node. + // As this info is not in the Node interface we must build it; + // + // again we will use an stl map, index will be nodeTag, object will be Vertex + // do using vertices for each node, when we addVertex at thes nodes we + // will not be adding vertices but element tags. + // - MAP_ID theNodeToVertexMap; - MAP_ID_ITERATOR theNodeEle; + MAP_ID theNodeToVertexMap; + MAP_ID_ITERATOR theNodeEle; - Node *nodPtr; + Node *nodPtr; - // now create the vertices with a reference equal to the node number. - // and a tag which ranges from 0 through numVertex-1 and placed in - // theNodeTagVertices at a position equal to the node's tag. + // now create the vertices with a reference equal to the node number. + // and a tag which ranges from 0 through numVertex-1 and placed in + // theNodeTagVertices at a position equal to the node's tag. - NodeIter &theNodes = this->getNodes(); - while ((nodPtr = theNodes()) != 0) { - int nodeTag = nodPtr->getTag(); - ID *eleTags = new ID(0, 4); + NodeIter &theNodes = this->getNodes(); + while ((nodPtr = theNodes()) != 0) { + int nodeTag = nodPtr->getTag(); + ID *eleTags = new ID(0, 4); - if (eleTags == 0) { - opserr << "WARNING Domain::buildEleGraph - Not Enough Memory to create the " << count << " vertex\n"; - return -1; - } + if (eleTags == 0) { + opserr << "WARNING Domain::buildEleGraph - Not Enough Memory to create the " << count << " vertex\n"; + return -1; + } + + theNodeEle = theNodeToVertexMap.find(nodeTag); + if (theNodeEle == theNodeToVertexMap.end()) { + theNodeToVertexMap.insert(MAP_ID_TYPE(nodeTag, eleTags)); + // check if sucessfully added theNodeEle = theNodeToVertexMap.find(nodeTag); if (theNodeEle == theNodeToVertexMap.end()) { - theNodeToVertexMap.insert(MAP_ID_TYPE(nodeTag, eleTags)); - - // check if successfully added - theNodeEle = theNodeToVertexMap.find(nodeTag); - if (theNodeEle == theNodeToVertexMap.end()) { - opserr << "Domain::buildEleGraph - map STL failed to add object with tag : " << nodeTag << endln; - return false; - } + opserr << "Domain::buildEleGraph - map STL failed to add object with tag : " << nodeTag << endln; + return false; } } + } - // now add the the Elements to the node vertices - Element *theEle; - TaggedObjectIter &theEle3 = elements->getComponents(); + // now add the the Elements to the node vertices + Element *theEle; + TaggedObjectIter &theEle3 = elements->getComponents(); - while((theTagged = theEle3()) != 0) { - theEle = (Element *)theTagged; - int eleTag = theEle->getTag(); - const ID &id = theEle->getExternalNodes(); + while ((theTagged = theEle3()) != 0) { + theEle = (Element *)theTagged; + int eleTag = theEle->getTag(); + const ID &id = theEle->getExternalNodes(); - int size = id.Size(); - for (int i=0; iinsert(eleTag); - } + MAP_ID_ITERATOR theNodeEle; + theNodeEle = theNodeToVertexMap.find(nodeTag); + if (theNodeEle == theNodeToVertexMap.end()) { + return -1; + } else { + ID *theNodeEleTags = (*theNodeEle).second; + theNodeEleTags->insert(eleTag); } } + } - // - // now add the edges to the vertices of our element graph; - // this is done by looping over the Node vertices, getting their - // Adjacenecy and adding edges between elements with common nodes - // + // + // now add the edges to the vertices of our element graph; + // this is done by looping over the Node vertices, getting their + // Adjacenecy and adding edges between elements with common nodes + // - MAP_ID_ITERATOR currentComponent; - currentComponent = theNodeToVertexMap.begin(); - while (currentComponent != theNodeToVertexMap.end()) { - ID *id = (*currentComponent).second; + MAP_ID_ITERATOR currentComponent; + currentComponent = theNodeToVertexMap.begin(); + while (currentComponent != theNodeToVertexMap.end()) { + ID *id = (*currentComponent).second; - int size = id->Size(); - for (int i=0; iSize(); + for (int i = 0; i < size; i++) { + int eleTag1 = (*id)(i); - theEleToVertexMapEle = theEleToVertexMap.find(eleTag1); - if (theEleToVertexMapEle != theEleToVertexMap.end()) { - int vertexTag1 = (*theEleToVertexMapEle).second; + theEleToVertexMapEle = theEleToVertexMap.find(eleTag1); + if (theEleToVertexMapEle != theEleToVertexMap.end()) { + int vertexTag1 = (*theEleToVertexMapEle).second; - for (int j=0; j vertexTag2) { - theEleGraph->addEdge(vertexTag1,vertexTag2); - theEleGraph->addEdge(vertexTag2,vertexTag1); - } + if (vertexTag1 > vertexTag2) { + theEleGraph->addEdge(vertexTag1, vertexTag2); + theEleGraph->addEdge(vertexTag2, vertexTag1); } } - } + } } - currentComponent++; } + currentComponent++; + } - // clean up - delete the ID's associated with the nodes - currentComponent = theNodeToVertexMap.begin(); - while (currentComponent != theNodeToVertexMap.end()) { - delete (*currentComponent).second; - currentComponent++; - } - - return 0; + // clean up - delete the ID's associated with the nodes + currentComponent = theNodeToVertexMap.begin(); + while (currentComponent != theNodeToVertexMap.end()) { + delete (*currentComponent).second; + currentComponent++; + } + + return 0; } @@ -1676,177 +1790,145 @@ PartitionedDomain::buildEleGraph(Graph *theEleGraph) Node * PartitionedDomain::removeExternalNode(int tag) { - return (this->Domain::removeNode(tag)); + return (this->Domain::removeNode(tag)); } Graph & PartitionedDomain::getSubdomainGraph(void) { - // delete the old always - only object that will - // use this is a DomainBalancer & it is always looking for latest - if (mySubdomainGraph != 0) { - delete mySubdomainGraph; - mySubdomainGraph = 0; - } - - // create a new graph - if (mySubdomainGraph == 0) - mySubdomainGraph = new Graph(this->getNumSubdomains()+START_VERTEX_NUM); - - if (mySubdomainGraph == 0) // if still 0 try a smaller one - mySubdomainGraph = new Graph(); + //The subdomain graph has number of vertices equal to number of subdomains, including P0 + int numVertex = theSubdomains->getNumComponents() + 1; // Use P0 as a vertex toooo + + // delete the old always - only object that will + // use this is a DomainBalancer & it is always looking for latest + if (mySubdomainGraph != 0) { + delete mySubdomainGraph; + mySubdomainGraph = 0; + } - int numVertex = theSubdomains->getNumComponents(); + // create a new graph + if (mySubdomainGraph == 0) + mySubdomainGraph = new Graph(numVertex + START_VERTEX_NUM); - // see if quick return + if (mySubdomainGraph == 0) // if still 0 try a smaller one + mySubdomainGraph = new Graph(); - if (numVertex == 0) - return *mySubdomainGraph; - - // create another vertices array which aids in adding edges - - int *theElementTagVertices = 0; - int maxEleNum = 0; - TaggedObject *tagdObjPtr; - TaggedObjectIter &theEles = theSubdomains->getComponents(); - while ((tagdObjPtr = theEles()) != 0) - if (tagdObjPtr->getTag() > maxEleNum) - maxEleNum = tagdObjPtr->getTag(); + // see if quick return + if (numVertex == 0) + return *mySubdomainGraph; - theElementTagVertices = new int[maxEleNum+1]; + //Mapping element tags to vertex corresponding vertex + MAP_INT subDTagToVtxTag; - if (theElementTagVertices == 0) { - opserr << "WARNING PartitionedDomain::buildEleGraph "; - opserr << " - Not Enough Memory for ElementTagVertices\n"; - exit(-1); - } + //Add P0 to the graph + SubdomainIter &theSubdomains = this->getSubdomains(); + Subdomain *subDPtr = 0; + int subDTag = 1; + double myCostP0 = 0.0;//this->getUpdateTime(); - for (int j=0; j<=maxEleNum; j++) theElementTagVertices[j] = -1; + Vertex *selfvertexPtr = new Vertex(subDTag, subDTag, myCostP0); + mySubdomainGraph->addVertex(selfvertexPtr); + + subDTagToVtxTag.insert(MAP_INT_TYPE(subDTag, subDTag)); - // now create the vertices with a reference equal to the subdomain number. - // and a tag equal to the subdomain number and a weighed according to - // the subdomain cost + while ((subDPtr = theSubdomains()) != 0) { + int subDTag = subDPtr->getTag(); - TaggedObjectIter &theEles2 = theSubdomains->getComponents(); + //Vertex for current subD + Vertex *vertexPtr = new Vertex(subDTag, subDTag, subDPtr->getCost()); - while ((tagdObjPtr = theEles2()) != 0) { - Subdomain *theSub = (Subdomain *)tagdObjPtr; // upward cast ok as - // only subdomais can be added - int ElementTag = tagdObjPtr->getTag(); + //Add to graph and map + mySubdomainGraph->addVertex(vertexPtr); + subDTagToVtxTag.insert(MAP_INT_TYPE(subDTag, subDTag)); + } - Vertex *vertexPtr = new Vertex(ElementTag, ElementTag, theSub->getCost()); - if (vertexPtr == 0) { - opserr << "WARNING Domain::buildEleGraph"; - opserr << " - Not Enough Memory to create "; - opserr << ElementTag << "th Vertex\n"; - delete [] theElementTagVertices; - exit(-1); - } + // We now need to determine which theSubdomains are asssociated with each node. + // As this info is not in the Node interface we must build it; which we + // do using vertices for each node, when we addVertex at thes nodes we + // will not be adding vertices but element tags. - mySubdomainGraph->addVertex(vertexPtr); + MAP_VERTEX nodeTagToVtx; - theElementTagVertices[ElementTag] = ElementTag; - } - // We now need to determine which theSubdomains are associated with each node. - // As this info is not in the Node interface we must build it; which we - // do using vertices for each node, when we addVertex at these nodes we - // will not be adding vertices but element tags. + // now create the vertices with a reference equal to the node number. + // and a tag which ranges from 0 through numVertex-1 and placed in + // theNodeTagVertices at a position equal to the node's tag. - Vertex **theNodeTagVertices = 0; - int maxNodNum = 0; - Node *nodPtr; - NodeIter &nodeIter = this->getNodes(); - while ((nodPtr = nodeIter()) != 0) - if (nodPtr->getTag() > maxNodNum) - maxNodNum = nodPtr->getTag(); + NodeIter &niter = this->getNodes(); + Node *nodPtr = 0; + int count = START_VERTEX_NUM; + while ((nodPtr = niter()) != 0) { + int nodeTag = nodPtr->getTag(); + Vertex *vertexPtr = new Vertex(count++, nodeTag); + vertexPtr->addEdge(1); - theNodeTagVertices = new Vertex *[maxNodNum+1]; + nodeTagToVtx.insert(MAP_VERTEX_TYPE(nodeTag, vertexPtr)); + } - if (theNodeTagVertices == 0) { - opserr << "WARNING Domain::buildEleGraph "; - opserr << " - Not Enough Memory for NodeTagVertices\n"; - exit(-1); + // now add the the TheSubdomains to the nodes + SubdomainIter &theSubdomains2 = this->getSubdomains(); + while ((subDPtr = theSubdomains2()) != 0) { + int subdTag = subDPtr->getTag(); + const ID &subdEdgeNodes = subDPtr->getExternalNodes(); + int numberExternalNodes = subdEdgeNodes.Size(); + for (int i = 0; i < numberExternalNodes; i++) + { + int currentNodeTag = subdEdgeNodes(i); + + MAP_VERTEX_ITERATOR mpvtx = nodeTagToVtx.find(currentNodeTag); + if(mpvtx != nodeTagToVtx.end()) // If we find current node Tag.... + { + mpvtx->second->addEdge(subdTag); + } + else //If not found + { + Vertex *newvtxptr = new Vertex(count++, currentNodeTag); + newvtxptr->addEdge(subdTag); + nodeTagToVtx.insert(MAP_VERTEX_TYPE(currentNodeTag, newvtxptr)); + } } + } - for (int l=0; l<=maxNodNum; l++) theNodeTagVertices[l] = 0; - - // now create the vertices with a reference equal to the node number. - // and a tag which ranges from 0 through numVertex-1 and placed in - // theNodeTagVertices at a position equal to the node's tag. - - NodeIter &nodeIter2 = this->getNodes(); - int count = START_VERTEX_NUM; - while ((nodPtr = nodeIter2()) != 0) { - int nodeTag = nodPtr->getTag(); - Vertex *vertexPtr = new Vertex(count++,nodeTag); - theNodeTagVertices[nodeTag] = vertexPtr; + // now add the edges to the vertices of our element graph; + // this is done by looping over the Node vertices, getting their + // Adjacenecy and adding edges between theSubdomains with common nodes - if (vertexPtr == 0) { - opserr << "WARNING Domain::buildEleGraph"; - opserr << " - Not Enough Memory to create "; opserr << count << "th Node Vertex\n"; - delete [] theNodeTagVertices; - exit(-1); - } - } - - // now add the the TheSubdomains to the nodes - Element *elePtr; - TaggedObjectIter &theEles3 = theSubdomains->getComponents(); + for (auto it=nodeTagToVtx.begin(); it!=nodeTagToVtx.end(); ++it) + { + int nodeTag = it->first; + Vertex *vertexPtr = it->second; - while((tagdObjPtr = theEles3()) != 0) { - elePtr = (Element *)tagdObjPtr; - int eleTag = elePtr->getTag(); - const ID &id = elePtr->getExternalNodes(); - - int size = id.Size(); - for (int i=0; iaddEdge(eleTag); - } - - // now add the edges to the vertices of our element graph; - // this is done by looping over the Node vertices, getting their - // Adjacenecy and adding edges between theSubdomains with common nodes - - Vertex *vertexPtr; - for (int k=0; k<=maxNodNum; k++) - if ((vertexPtr = theNodeTagVertices[k]) != 0) { - - const ID &id = vertexPtr->getAdjacency(); - - int size = id.Size(); - for (int i=0; igetAdjacency(); - for (int j=0; jfirst; - int Element2 = id(j); - int vertexTag2 = theElementTagVertices[Element2]; + for (int j = 0; j < numberOfConnectedSubdomains; j++) + if (i != j) { + int subdomainTag2 = connectedSubdomains(j); - // addEdge() adds for both vertices - do only once - if (vertexTag1 > vertexTag2) - mySubdomainGraph->addEdge(vertexTag1,vertexTag2); - mySubdomainGraph->addEdge(vertexTag2,vertexTag1); - } - } - } + int vertexTag2 = subDTagToVtxTag.find(subdomainTag2)->second; - // done now delete theElementTagVertices, the node Vertices and - // theNodeTagVertices - - delete [] theElementTagVertices; + // addEdge() adds for both vertices - do only once + if (vertexTag1 > vertexTag2) + { + mySubdomainGraph->addEdge(vertexTag1, vertexTag2); + mySubdomainGraph->addEdge(vertexTag2, vertexTag1); + } + } + } + } - for (int i=0; i<=maxNodNum; i++) - if ((vertexPtr = theNodeTagVertices[i]) != 0) - delete vertexPtr; + for (auto it=nodeTagToVtx.begin(); it!=nodeTagToVtx.end(); ++it) + { + delete it->second; + } - delete [] theNodeTagVertices; - return *mySubdomainGraph; + return *mySubdomainGraph; } @@ -1859,17 +1941,17 @@ PartitionedDomain::getNodeDisp(int nodeTag, int dof, int &errorFlag) // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0 && errorFlag != 0) { - Subdomain *theSub = (Subdomain *)theObject; - result = theSub->getNodeDisp(nodeTag, dof, errorFlag); - if (errorFlag == 0) - return result; - } + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0 && errorFlag != 0) { + Subdomain *theSub = (Subdomain *)theObject; + result = theSub->getNodeDisp(nodeTag, dof, errorFlag); + if (errorFlag == 0) + return result; + } } } - + return result; } @@ -1883,35 +1965,39 @@ PartitionedDomain::setMass(const Matrix &mass, int nodeTag) // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0 && result != 0) { - Subdomain *theSub = (Subdomain *)theObject; - result = theSub->setMass(mass, nodeTag); - } + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0 && result != 0) { + Subdomain *theSub = (Subdomain *)theObject; + result = theSub->setMass(mass, nodeTag); + } } } - + return result; } const Vector * PartitionedDomain::getNodeResponse(int nodeTag, NodeResponseType response) { - const Vector *res = this->Domain::getNodeResponse(nodeTag, response); + const Vector *res = this->Domain::getNodeResponse(nodeTag, response); if (res != 0) return res; + // opserr << "PartitionedDomain::getNodeResponse - Did not find response for node # " << nodeTag << " in main domain\n"; + // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - const Vector *result = theSub->getNodeResponse(nodeTag, response); + Subdomain *theSub = (Subdomain *)theObject; + const Vector *result = theSub->getNodeResponse(nodeTag, response); if (result != 0) - return result; - } + return result; + // else + // opserr << "PartitionedDomain::getNodeResponse - Did not find response for node # " << nodeTag << " in domain # " << theSub->getTag() << "\n"; + } } return NULL; @@ -1919,75 +2005,75 @@ PartitionedDomain::getNodeResponse(int nodeTag, NodeResponseType response) const Vector * PartitionedDomain::getElementResponse(int eleTag, const char **argv, int argc) { - - const Vector *res = this->Domain::getElementResponse(eleTag, argv, argc); + + const Vector *res = this->Domain::getElementResponse(eleTag, argv, argc); if (res != 0) { return res; } - + // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - const Vector *result = theSub->getElementResponse(eleTag, argv, argc); + Subdomain *theSub = (Subdomain *)theObject; + const Vector *result = theSub->getElementResponse(eleTag, argv, argc); if (result != 0) { - return result; - } - } + return result; + } + } } return NULL; } -int +int PartitionedDomain::calculateNodalReactions(bool inclInertia) { - int res = this->Domain::calculateNodalReactions(inclInertia); + int res = this->Domain::calculateNodalReactions(inclInertia); // do the same for all the subdomains /* if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - res += theSub->calculateNodalReactions(inclInertia); + Subdomain *theSub = (Subdomain *)theObject; + res += theSub->calculateNodalReactions(inclInertia); } } */ return res; } -bool +bool PartitionedDomain::addParameter(Parameter *param) { - bool res = this->Domain::addParameter(param); - - // do the same for all the subdomains - if (theSubdomains != 0) { - - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); - TaggedObject *theObject; - while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; - theSub->addParameter(param); + bool res = this->Domain::addParameter(param); + + // do the same for all the subdomains + if (theSubdomains != 0) { + + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + Subdomain *theSub = (Subdomain *)theObject; + theSub->addParameter(param); - } } + } - return res; + return res; } Parameter * PartitionedDomain::removeParameter(int tag) { Parameter *res = this->Domain::removeParameter(tag); - + // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { Subdomain *theSub = (Subdomain *)theObject; @@ -1999,15 +2085,15 @@ PartitionedDomain::removeParameter(int tag) } -int +int PartitionedDomain::updateParameter(int tag, int value) { int res = 0; // do the same for all the subdomains - + if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { @@ -2023,26 +2109,88 @@ PartitionedDomain::updateParameter(int tag, int value) } -int +int PartitionedDomain::updateParameter(int tag, double value) { - + int res = 0; res += this->Domain::updateParameter(tag, value); - + // do the same for all the subdomains if (theSubdomains != 0) { - ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); TaggedObject *theObject; while ((theObject = theSubsIter()) != 0) { - Subdomain *theSub = (Subdomain *)theObject; + Subdomain *theSub = (Subdomain *)theObject; res += theSub->updateParameter(tag, value); } } - + res += this->Domain::updateParameter(tag, value); - + + return res; +} + +TaggedObjectStorage* PartitionedDomain::getElementsStorage() +{ + return elements; +} + + +GraphPartitioner* PartitionedDomain::getGraphPartitioner(void) +{ + return theDomainPartitioner->getGraphPartitioner(); +} + + + +int +PartitionedDomain::activateElements(const ID& elementList) +{ + int res = 0; + + // do the same for all the subdomains + + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + + Subdomain *theSub = (Subdomain *)theObject; + + // opserr << "PartitionedDomain::activateElements elementList = " << elementList << endln; + res += theSub->activateElements(elementList); + + } + } + + res += this->Domain::activateElements(elementList); + return res; } +int +PartitionedDomain::deactivateElements(const ID& elementList) +{ + int res = 0; + + // do the same for all the subdomains + + if (theSubdomains != 0) { + ArrayOfTaggedObjectsIter theSubsIter(*theSubdomains); + TaggedObject *theObject; + while ((theObject = theSubsIter()) != 0) { + + Subdomain *theSub = (Subdomain *)theObject; + + // opserr << "PartitionedDomain::activateElements elementList = " << elementList << endln; + res += theSub->deactivateElements(elementList); + + } + } + + res += this->Domain::deactivateElements(elementList); + + return res; +} diff --git a/SRC/domain/domain/partitioned/PartitionedDomain.h b/SRC/domain/domain/partitioned/PartitionedDomain.h index 2313ea6595..226fc0ec28 100644 --- a/SRC/domain/domain/partitioned/PartitionedDomain.h +++ b/SRC/domain/domain/partitioned/PartitionedDomain.h @@ -45,11 +45,12 @@ class DomainPartitioner; class Subdomain; class SubdomainIter; -class ArrayOfTaggedObjects; -class PartitionedDomainSubIter; -class PartitionedDomainEleIter; +class ArrayOfTaggedObjects; +class PartitionedDomainSubIter; +class PartitionedDomainEleIter; class SingleDomEleIter; class Parameter; +class GraphPartitioner; class PartitionedDomain: public Domain { @@ -130,6 +131,7 @@ class PartitionedDomain: public Domain // public member functions in addition to the standard domain virtual int setPartitioner(DomainPartitioner *thePartitioner); virtual int partition(int numPartitions, bool usingMain = false, int mainPartitionID = 0, int specialElementTag = 0); + virtual int repartition(int numPartitions, bool usingMain = false, int mainPartitionID = 0, int specialElementTag = 0); virtual bool addSubdomain(Subdomain *theSubdomain); virtual int getNumSubdomains(void); @@ -147,15 +149,20 @@ class PartitionedDomain: public Domain virtual int calculateNodalReactions(bool inclInertia); + virtual int activateElements(const ID& elementList); + virtual int deactivateElements(const ID& elementList); + // friend classes friend class PartitionedDomainEleIter; protected: int barrierCheck(int result); + GraphPartitioner *getGraphPartitioner(void); DomainPartitioner *getPartitioner(void) const; virtual int buildEleGraph(Graph *theEleGraph); + virtual TaggedObjectStorage* getElementsStorage(); + - private: TaggedObjectStorage *elements; ArrayOfTaggedObjects *theSubdomains; DomainPartitioner *theDomainPartitioner; @@ -165,6 +172,8 @@ class PartitionedDomain: public Domain PartitionedDomainEleIter *theEleIter; Graph *mySubdomainGraph; // a graph of subdomain connectivity + + bool has_sent_yet; }; #endif diff --git a/SRC/domain/partitioner/DomainPartitioner.cpp b/SRC/domain/partitioner/DomainPartitioner.cpp index 7f7b2dbe21..0c5ff00532 100644 --- a/SRC/domain/partitioner/DomainPartitioner.cpp +++ b/SRC/domain/partitioner/DomainPartitioner.cpp @@ -62,6 +62,16 @@ #include +#include + +#include + +//================================================================================================== +// NodeLocations +//================================================================================================== + +// This helper class maps each node tag to the partitions it belongs to.... useful to figure out +// the boundaries between subdomains.... class NodeLocations: public TaggedObject { public: @@ -96,8 +106,27 @@ NodeLocations::addPartition(int partition) return 0; } + +//================================================================================================== +// Some maps that help handling graphs +//================================================================================================== + +typedef map MAP_INT; +typedef MAP_INT::value_type MAP_INT_TYPE; +typedef MAP_INT::iterator MAP_INT_ITERATOR; + +typedef map MAP_ID; +typedef MAP_ID::value_type MAP_ID_TYPE; +typedef MAP_ID::iterator MAP_ID_ITERATOR; + + +//================================================================================================== +// DomainPartitioner +//================================================================================================== + + DomainPartitioner::DomainPartitioner(GraphPartitioner &theGraphPartitioner) -:myDomain(0),thePartitioner(theGraphPartitioner),theBalancer(0), + : myDomain(0), thePartitioner(theGraphPartitioner), theBalancer(0), theElementGraph(0), theBoundaryElements(0), theNodeLocations(0),elementPlace(0), numPartitions(0), partitionFlag(false), usingMainDomain(false) { @@ -106,7 +135,7 @@ DomainPartitioner::DomainPartitioner(GraphPartitioner &theGraphPartitioner) DomainPartitioner::DomainPartitioner(GraphPartitioner &theGraphPartitioner, LoadBalancer &theLoadBalancer) -:myDomain(0),thePartitioner(theGraphPartitioner),theBalancer(&theLoadBalancer), + : myDomain(0), thePartitioner(theGraphPartitioner), theBalancer(&theLoadBalancer), theElementGraph(0), theBoundaryElements(0), theNodeLocations(0),elementPlace(0), numPartitions(0), partitionFlag(false), usingMainDomain(false) { @@ -125,6 +154,7 @@ DomainPartitioner::~DomainPartitioner() } } + void DomainPartitioner::setPartitionedDomain(PartitionedDomain &theDomain) { @@ -135,6 +165,9 @@ int DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, int specialElementTag) { + opserr << "DomainPartitioner::partition() - Start\n"; + + usingMainDomain = usingMain; mainPartition = mainPartitionTag; @@ -164,11 +197,12 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, opserr << " - the graph partioner failed to partition the "; opserr << "element graph\n"; return -10+theError; + } else { + opserr << "DomainPartitioner::partition - Succesfull partition. Now redistributing data accordingly.\n"; } /* print graph */ - // opserr << "DomainPartitioner::partition - eleGraph: \n"; - // theElementGraph->Print(opserr, 4); + opserr << " * Identifying components to transfer.\n"; VertexIter &theVertices1 = theElementGraph->getVertices(); Vertex *vertexPtr = 0; @@ -178,6 +212,7 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, int vertexOnePartition = 0; if (vertexPtr != 0) vertexOnePartition = vertexPtr->getColor(); + while ((moreThanOne == false) && ((vertexPtr = theVertices1()) != 0)) { int partition = vertexPtr->getColor(); if (partition != vertexOnePartition ) { @@ -190,7 +225,8 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, return -1; } - int specialElementColor = 1; + opserr << " + Elements.\n"; + // No idea what this is for.... if (specialElementTag != 0) { bool found = false; VertexIter &theVerticesSpecial = theElementGraph->getVertices(); @@ -250,6 +286,7 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, return -1; } + opserr << " + Nodes.\n"; NodeIter &theNodes = myDomain->getNodes(); Node *nodePtr; while ((nodePtr = theNodes()) != 0) { @@ -277,21 +314,29 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, // have to be added to the subdomain. // + opserr << " + Boundary Nodes.\n"; + //Transverse the graph VertexIter &theVertexIter = theElementGraph->getVertices(); while ((vertexPtr = theVertexIter()) != 0) { int eleTag = vertexPtr->getRef(); int vertexColor = vertexPtr->getColor(); + // For each element, transverse its neighboring element const ID &adjacency = vertexPtr->getAdjacency(); int size = adjacency.Size(); for (int i=0; igetVertexPtr(adjacency(i)); + + //If a neighbor has a different color (partition) if (otherVertex->getColor() != vertexColor) { + + //Add it into the boundary elements graph theBoundaryElements[vertexColor-1]->addVertex(vertexPtr,false); i = size; } } + //Also for each element, transverse its connected nodes Element *elePtr = myDomain->getElement(eleTag); const ID &nodes = elePtr->getExternalNodes(); size = nodes.Size(); @@ -304,6 +349,8 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, numPartitions = 0; return -1; } + + // Add current partition as a location into current node's location map... NodeLocations *theNodeLocation = (NodeLocations *)theTaggedObject; theNodeLocation->addPartition(vertexColor); } @@ -311,6 +358,7 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, // now go through the MP_Constraints and ensure the retained node is in every // partition the constrained node is in + opserr << " + MP constraints.\n"; MP_ConstraintIter &theMPs = myDomain->getMPs(); MP_Constraint *mpPtr; while ((mpPtr = theMPs()) != 0) { @@ -332,14 +380,65 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, NodeLocations *theRetainedLocation = (NodeLocations *)theRetainedObject; NodeLocations *theConstrainedLocation = (NodeLocations *)theConstrainedObject; + ID &theConstrainedNodesPartitions = theConstrainedLocation->nodePartitions; int numPartitions = theConstrainedNodesPartitions.Size(); for (int i=0; iaddPartition(theConstrainedNodesPartitions(i)); + int part = theConstrainedNodesPartitions(i); + // opserr << "Retained node " << retained << " (equaldof with " << constrained << " ) added to partition " << part << endln; + theRetainedLocation->addPartition(part); } + // if(retained == 5) + // { + // opserr << " + Retained: " << *theRetainedLocation; + // opserr << " + Constrained: " << *theConstrainedLocation; + // } } + opserr << " + MP constraints (2nd pass).\n"; + MP_ConstraintIter &theMPs2 = myDomain->getMPs(); // we now add the nodes, + while ((mpPtr = theMPs2()) != 0) { + int retained = mpPtr->getNodeRetained(); + int constrained = mpPtr->getNodeConstrained(); + + TaggedObject *theRetainedObject = theNodeLocations->getComponentPtr(retained); + TaggedObject *theConstrainedObject = theNodeLocations->getComponentPtr(constrained); + + if (theRetainedObject == 0 || theConstrainedObject == 0) { + opserr << "DomainPartitioner::partition(int numParts)"; + if (theRetainedObject == 0) + opserr << " - failed to find NodeLocation in Map for Node: " << retained << " -- A BUG!!\n"; + if (theConstrainedObject == 0) + opserr << " - failed to find NodeLocation in Map for Node: " << constrained << " -- A BUG!!\n"; + numPartitions = 0; + return -1; + } + + NodeLocations *theRetainedLocation = (NodeLocations *)theRetainedObject; + NodeLocations *theConstrainedLocation = (NodeLocations *)theConstrainedObject; + + ID &theConstrainedNodesPartitions = theConstrainedLocation->nodePartitions; + int numPartitions = theConstrainedNodesPartitions.Size(); + for (int i = 0; i < numPartitions; i++) { + int part = theConstrainedNodesPartitions(i); + // opserr << " ** Retained node " << retained << " (equaldof with " << constrained << " ) added to partition " << part << endln; + theRetainedLocation->addPartition(part); + } + if(retained == 5) + { + // opserr << " + Retained: " << *theRetainedLocation; + // opserr << " + Constrained: " << *theConstrainedLocation; + } + } + + + // we now add the nodes, + + // opserr << "DomainPartitioner::partition() - Sending Nodes\n"; + + //Transverse the node locations..... + opserr << " * Sending nodes.\n"; TaggedObjectIter &theNodeLocationIter = theNodeLocations->getComponents(); TaggedObject *theNodeObject; @@ -350,14 +449,25 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, ID &nodePartitions = theNodeLocation->nodePartitions; int numPartitions = theNodeLocation->numPartitions; + //Cycle the partitions that this node belongs to for (int i=0; igetSubdomainPtr(partition); + + // opserr << "Adding node # " << nodeTag << " to partition # " << partition; + //If the node belongs to only one partition if (numPartitions == 1) { + // opserr << " ... internal\n"; + // Remove it from current and add it as internal node in the remote partition Node *nodePtr = myDomain->removeNode(nodeTag); theSubdomain->addNode(nodePtr); } else { + // opserr << " ... external\n"; + // Otherwise, the node belongs to several partitions and is, therefore, a boundary node + // Add it to the external nodes in the remote partition Node *nodePtr = myDomain->getNode(nodeTag); theSubdomain->addExternalNode(nodePtr); } @@ -366,6 +476,8 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, } // we now move the elements + // opserr << "DomainPartitioner::partition() - Sending Elements\n"; + opserr << " * Sending elements.\n"; VertexIter &theVertices = theElementGraph->getVertices(); while ((vertexPtr = theVertices()) != 0) { // move the element @@ -385,7 +497,7 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, // opserr << "adding ele - done\n"; } else { - opserr << "DomainPartitioner::partioner - element GONE! - eleTag " << eleTag << endln; + opserr << "DomainPartitioner::partitioner - element GONE! - eleTag " << eleTag << endln; } } } @@ -395,6 +507,7 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, // 2) move nodal loads // 3) move SP_Constraints + opserr << " * Sending Load Patterns\n"; LoadPatternIter &theLoadPatterns = myDomain->getLoadPatterns(); LoadPattern *theLoadPattern; while ((theLoadPattern = theLoadPatterns()) != 0) { @@ -502,6 +615,7 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, // add the single point constraints, + opserr << " * Sending homogeneous SP Constraints`\n"; SP_ConstraintIter &theDomainSP = myDomain->getSPs(); SP_Constraint *spPtr; while ((spPtr = theDomainSP()) != 0) { @@ -534,13 +648,21 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, } // move MP_Constraints - add an MP_Constraint to every partition a constrained node is in + opserr << " * Sending MP Constraints\n"; MP_ConstraintIter &moreMPs = myDomain->getMPs(); while ((mpPtr = moreMPs()) != 0) { int constrained = mpPtr->getNodeConstrained(); + int retained = mpPtr->getNodeRetained(); TaggedObject *theConstrainedObject = theNodeLocations->getComponentPtr(constrained); NodeLocations *theConstrainedLocation = (NodeLocations *)theConstrainedObject; ID &theConstrainedNodesPartitions = theConstrainedLocation->nodePartitions; int numPartitions = theConstrainedLocation->numPartitions; + // if(retained == 5) + // { + // NodeLocations *theRetainedLocation = (NodeLocations *)theNodeLocations->getComponentPtr(retained); + // opserr << " > Retained: " << *theRetainedLocation; + // opserr << " > Constrained: " << *theConstrainedLocation; + // } for (int i=0; iaddMP_Constraint(mpPtr); if (res < 0) opserr << "DomainPartitioner::partition() - failed to add MP Constraint\n"; + // else + // opserr << "DomainPartitioner::partition() - add MP constraint for c = " << constrained << " r = " << retained << " to partition # " << partition << "\n"; + } } } @@ -557,6 +682,7 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, // now we go through all the subdomains and tell them to update // their analysis for the new layouts + SubdomainIter &theSubDomains = myDomain->getSubdomains(); Subdomain *theSubDomain; while ((theSubDomain = theSubDomains()) != 0) @@ -570,10 +696,26 @@ DomainPartitioner::partition(int numParts, bool usingMain, int mainPartitionTag, // we are done partitionFlag = true; + opserr << "DomainPartitioner::partition() - Done\n"; + + + // myDomain->Print(opserr); + return 0; } +#define DOMAINPARTITIONER_REPARTITION_DEBUG_DISABLED_LV_1 0 +#define DEBUGSTREAM1 \ + if (DOMAINPARTITIONER_REPARTITION_DEBUG_DISABLED_LV_1) {} \ + else opserr + +#define DOMAINPARTITIONER_REPARTITION_DEBUG_DISABLED_LV_2 0 +#define DEBUGSTREAM2 \ + if (DOMAINPARTITIONER_REPARTITION_DEBUG_DISABLED_LV_2) {} \ + else opserr + + int DomainPartitioner::balance(Graph &theWeightedPGraph) { @@ -586,21 +728,40 @@ DomainPartitioner::balance(Graph &theWeightedPGraph) return -1; } + if (theBalancer != 0) { // call on the LoadBalancer to partition + + // timer.start(); + // If we have a balancer, then call the balance function res = theBalancer->balance(theWeightedPGraph); // now invoke domainChanged on Subdomains and PartitionedDomain + // { + + + // All domains are informed that there has been a domain change SubdomainIter &theSubDomains = myDomain->getSubdomains(); Subdomain *theSubDomain; while ((theSubDomain = theSubDomains()) != 0) theSubDomain->domainChange(); + myDomain->domainChange(); // we invoke change on the PartitionedDomain - myDomain->domainChange(); + + // if(res > 0) + // { + // fid << myDomain->getCurrentTime() << " " << timer.getReal() << endln; + // } + // } } + else + { + // If there is no balancer.... we cant balance... continue with a static domain decomposition + } + return res; } @@ -1493,3 +1654,9 @@ DomainPartitioner::releaseBoundary(int from, return 0; } + +GraphPartitioner* DomainPartitioner::getGraphPartitioner() +{ + std::cout << "DomainPartitioner::getGraphPartitioner() - thePartitioner is @ " << static_cast(&thePartitioner) << "\n" << std::endl; + return &thePartitioner; +} diff --git a/SRC/domain/partitioner/DomainPartitioner.h b/SRC/domain/partitioner/DomainPartitioner.h index 083d49e4bb..ad7e1e03e7 100644 --- a/SRC/domain/partitioner/DomainPartitioner.h +++ b/SRC/domain/partitioner/DomainPartitioner.h @@ -89,6 +89,8 @@ class DomainPartitioner double factorGreater = 1.0, bool adjacentVertexNotInOther = true); + + virtual GraphPartitioner* getGraphPartitioner(); protected: private: diff --git a/SRC/domain/pattern/TclPatternCommand.cpp b/SRC/domain/pattern/TclPatternCommand.cpp index 5b6df22259..3983d14469 100644 --- a/SRC/domain/pattern/TclPatternCommand.cpp +++ b/SRC/domain/pattern/TclPatternCommand.cpp @@ -89,7 +89,7 @@ TclSeriesCommand(ClientData clientData, Tcl_Interp *interp, TCL_Char *arg); int TclPatternCommand(ClientData clientData, Tcl_Interp *interp, - int argc, TCL_Char **argv, Domain *theDomain) + int argc, TCL_Char **argv, Domain *theDomain) { LoadPattern *thePattern = 0; @@ -107,7 +107,7 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, if (Tcl_GetInt(interp, argv[2], &patternID) != TCL_OK) { opserr << "WARNING invalid patternID: pattern type " << argv[2] - << "\n"; + << "\n"; return TCL_ERROR; } @@ -150,75 +150,75 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, //--Adding FireLoadPattern:[BEGIN] by UoE OpenSees Group--// else if (strcmp(argv[1],"Fire") == 0) { - FireLoadPattern *theFirePattern = new FireLoadPattern(patternID); - thePattern = theFirePattern; - TimeSeries *theSeries1 = TclSeriesCommand(clientData, interp, argv[3]); - TimeSeries *theSeries2 = TclSeriesCommand(clientData, interp, argv[4]); - TimeSeries *theSeries3 = TclSeriesCommand(clientData, interp, argv[5]); - TimeSeries *theSeries4 = TclSeriesCommand(clientData, interp, argv[6]); - TimeSeries *theSeries5 = TclSeriesCommand(clientData, interp, argv[7]); - TimeSeries *theSeries6 = TclSeriesCommand(clientData, interp, argv[8]); - TimeSeries *theSeries7 = TclSeriesCommand(clientData, interp, argv[9]); - TimeSeries *theSeries8 = TclSeriesCommand(clientData, interp, argv[10]); - TimeSeries *theSeries9 = TclSeriesCommand(clientData, interp, argv[11]); - - //opserr << "series1 "; - //*theSeries1->Print; - // if (thePattern == 0 || theSeries == 0) { - - if (thePattern == 0) { - opserr << "WARNING - out of memory creating LoadPattern "; - opserr << patternID << endln; - } - else if (theSeries1 == 0) { - opserr << "WARNING - problem creating TimeSeries1 for LoadPattern "; - opserr << patternID << endln; - } - else if (theSeries2 == 0) { - opserr << "WARNING - problem creating TimeSeries2 for LoadPattern "; - opserr << patternID << endln; - } - else if (theSeries3 == 0) { - opserr << "WARNING - problem creating TimeSeries3 for LoadPattern "; - opserr << patternID << endln; - } - else if (theSeries4 == 0) { - opserr << "WARNING - problem creating TimeSeries4 for LoadPattern "; - opserr << patternID << endln; - } - else if (theSeries5 == 0) { - opserr << "WARNING - problem creating TimeSeries5 for LoadPattern "; - opserr << patternID << endln; - } - else if (theSeries6 == 0) { - opserr << "WARNING - problem creating TimeSeries6 for LoadPattern "; - opserr << patternID << endln; - } - else if (theSeries7 == 0) { - opserr << "WARNING - problem creating TimeSeries7 for LoadPattern "; - opserr << patternID << endln; - } - else if (theSeries8 == 0) { - opserr << "WARNING - problem creating TimeSeries8 for LoadPattern "; - opserr << patternID << endln; - } - else if (theSeries9 == 0){ - opserr << "WARNING - problem creating TimeSeries9 for LoadPattern "; - opserr << patternID << endln; - } - - // clean up the memory and return an error - //if (thePattern != 0) - // delete thePattern; - //if (theSeries != 0) - // delete theSeries; - //return TCL_ERROR; - // } - - theFirePattern->setFireTimeSeries(theSeries1, theSeries2, - theSeries3, theSeries4, theSeries5, - theSeries6, theSeries7, theSeries8, theSeries9); - + FireLoadPattern *theFirePattern = new FireLoadPattern(patternID); + thePattern = theFirePattern; + TimeSeries *theSeries1 = TclSeriesCommand(clientData, interp, argv[3]); + TimeSeries *theSeries2 = TclSeriesCommand(clientData, interp, argv[4]); + TimeSeries *theSeries3 = TclSeriesCommand(clientData, interp, argv[5]); + TimeSeries *theSeries4 = TclSeriesCommand(clientData, interp, argv[6]); + TimeSeries *theSeries5 = TclSeriesCommand(clientData, interp, argv[7]); + TimeSeries *theSeries6 = TclSeriesCommand(clientData, interp, argv[8]); + TimeSeries *theSeries7 = TclSeriesCommand(clientData, interp, argv[9]); + TimeSeries *theSeries8 = TclSeriesCommand(clientData, interp, argv[10]); + TimeSeries *theSeries9 = TclSeriesCommand(clientData, interp, argv[11]); + + //opserr << "series1 "; + //*theSeries1->Print; + // if (thePattern == 0 || theSeries == 0) { + + if (thePattern == 0) { + opserr << "WARNING - out of memory creating LoadPattern "; + opserr << patternID << endln; + } + else if (theSeries1 == 0) { + opserr << "WARNING - problem creating TimeSeries1 for LoadPattern "; + opserr << patternID << endln; + } + else if (theSeries2 == 0) { + opserr << "WARNING - problem creating TimeSeries2 for LoadPattern "; + opserr << patternID << endln; + } + else if (theSeries3 == 0) { + opserr << "WARNING - problem creating TimeSeries3 for LoadPattern "; + opserr << patternID << endln; + } + else if (theSeries4 == 0) { + opserr << "WARNING - problem creating TimeSeries4 for LoadPattern "; + opserr << patternID << endln; + } + else if (theSeries5 == 0) { + opserr << "WARNING - problem creating TimeSeries5 for LoadPattern "; + opserr << patternID << endln; + } + else if (theSeries6 == 0) { + opserr << "WARNING - problem creating TimeSeries6 for LoadPattern "; + opserr << patternID << endln; + } + else if (theSeries7 == 0) { + opserr << "WARNING - problem creating TimeSeries7 for LoadPattern "; + opserr << patternID << endln; + } + else if (theSeries8 == 0) { + opserr << "WARNING - problem creating TimeSeries8 for LoadPattern "; + opserr << patternID << endln; + } + else if (theSeries9 == 0){ + opserr << "WARNING - problem creating TimeSeries9 for LoadPattern "; + opserr << patternID << endln; + } + + // clean up the memory and return an error + //if (thePattern != 0) + // delete thePattern; + //if (theSeries != 0) + // delete theSeries; + //return TCL_ERROR; + // } + + theFirePattern->setFireTimeSeries(theSeries1, theSeries2, + theSeries3, theSeries4, theSeries5, + theSeries6, theSeries7, theSeries8, theSeries9); + } //--Adding FireLoadPattern:[END] by UoE OpenSees Group--// @@ -228,7 +228,7 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, if (Tcl_GetInt(interp, argv[3], &dir) != TCL_OK) { opserr << "WARNING invalid patternID: pattern type " << argv[2] - << "\n"; + << "\n"; return TCL_ERROR; } @@ -246,86 +246,86 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, while (currentArg < argc-1 && doneSeries == false) { if ((strcmp(argv[currentArg],"-vel0") == 0) || - (strcmp(argv[currentArg],"-initialVel") == 0)) { - - currentArg++; - if ((currentArg < argc) && - (Tcl_GetDouble(interp, argv[currentArg], &vel0) != TCL_OK)) { - opserr << "WARNING invalid vel0: pattern type UniformExcitation\n"; - return TCL_ERROR; - } - - currentArg++; + (strcmp(argv[currentArg],"-initialVel") == 0)) { + + currentArg++; + if ((currentArg < argc) && + (Tcl_GetDouble(interp, argv[currentArg], &vel0) != TCL_OK)) { + opserr << "WARNING invalid vel0: pattern type UniformExcitation\n"; + return TCL_ERROR; + } + + currentArg++; } else if ((strcmp(argv[currentArg],"-fact") == 0) || (strcmp(argv[currentArg],"-factor") == 0)) { - - currentArg++; - if ((currentArg < argc) && - (Tcl_GetDouble(interp, argv[currentArg], &fact) != TCL_OK)) { - opserr << "WARNING invalid fact: pattern type UniformExcitation\n"; - return TCL_ERROR; - } - - currentArg++; + + currentArg++; + if ((currentArg < argc) && + (Tcl_GetDouble(interp, argv[currentArg], &fact) != TCL_OK)) { + opserr << "WARNING invalid fact: pattern type UniformExcitation\n"; + return TCL_ERROR; + } + + currentArg++; } else if ((strcmp(argv[currentArg],"-accel") == 0) || - (strcmp(argv[currentArg],"-acceleration") == 0)) { - - currentArg++; - accelSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); - - if (accelSeries == 0) { - opserr << "WARNING invalid accel series: " << argv[currentArg]; - opserr << " pattern UniformExcitation -accel {series}\n"; - return TCL_ERROR; - } - currentArg++; - + (strcmp(argv[currentArg],"-acceleration") == 0)) { + + currentArg++; + accelSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); + + if (accelSeries == 0) { + opserr << "WARNING invalid accel series: " << argv[currentArg]; + opserr << " pattern UniformExcitation -accel {series}\n"; + return TCL_ERROR; + } + currentArg++; + } else if ((strcmp(argv[currentArg],"-vel") == 0) || - (strcmp(argv[currentArg],"-velocity") == 0)) { - - currentArg++; - velSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); - - if (velSeries == 0) { - opserr << "WARNING invalid vel series: " << argv[currentArg]; - opserr << " pattern UniformExcitation -vel {series}\n"; - return TCL_ERROR; - } - currentArg++; - + (strcmp(argv[currentArg],"-velocity") == 0)) { + + currentArg++; + velSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); + + if (velSeries == 0) { + opserr << "WARNING invalid vel series: " << argv[currentArg]; + opserr << " pattern UniformExcitation -vel {series}\n"; + return TCL_ERROR; + } + currentArg++; + } else if ((strcmp(argv[currentArg],"-disp") == 0) || - (strcmp(argv[currentArg],"-displacement") == 0)) { - - currentArg++; - dispSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); - - if (dispSeries == 0) { - opserr << "WARNING invalid disp series: " << argv[currentArg]; - opserr << " pattern UniformExcitation -disp {series}\n"; - return TCL_ERROR; - } - currentArg++; - + (strcmp(argv[currentArg],"-displacement") == 0)) { + + currentArg++; + dispSeries = TclSeriesCommand(clientData, interp, argv[currentArg]); + + if (dispSeries == 0) { + opserr << "WARNING invalid disp series: " << argv[currentArg]; + opserr << " pattern UniformExcitation -disp {series}\n"; + return TCL_ERROR; + } + currentArg++; + } else if ((strcmp(argv[currentArg],"-int") == 0) || - (strcmp(argv[currentArg],"-integrator") == 0)) { - - currentArg++; - seriesIntegrator = TclSeriesIntegratorCommand(clientData, interp, - argv[currentArg]); - if (seriesIntegrator == 0) { - opserr << "WARNING invalid series integrator: " << argv[currentArg]; - opserr << " - pattern UniformExcitation -int {Series Integrator}\n"; - return TCL_ERROR; - } - currentArg++; + (strcmp(argv[currentArg],"-integrator") == 0)) { + + currentArg++; + seriesIntegrator = TclSeriesIntegratorCommand(clientData, interp, + argv[currentArg]); + if (seriesIntegrator == 0) { + opserr << "WARNING invalid series integrator: " << argv[currentArg]; + opserr << " - pattern UniformExcitation -int {Series Integrator}\n"; + return TCL_ERROR; + } + currentArg++; } else - doneSeries = true; + doneSeries = true; } if (dispSeries == 0 && velSeries == 0 && accelSeries == 0) { @@ -336,7 +336,7 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, } GroundMotion *theMotion = new GroundMotion(dispSeries, velSeries, - accelSeries, seriesIntegrator); + accelSeries, seriesIntegrator); if (theMotion == 0) { opserr << "WARNING ran out of memory creating ground motion - pattern UniformExcitation "; @@ -354,7 +354,7 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, // clean up memory allocated up to this point and return an error if (theMotion != 0) - delete theMotion; + delete theMotion; return TCL_ERROR; } @@ -403,19 +403,19 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, switch (inputDir) { case 'X': case 'x': case '1': // Global X - dir = 0; - break; + dir = 0; + break; case 'Y': case 'y': case '2': // Global Y - dir = 1; - break; + dir = 1; + break; case 'Z': case 'z': case '3': // Global Z - dir = 2; + dir = 2; break; default: - opserr << "WARNING cannot read direction for excitation \n"; - opserr << "UniformExcitation " << patternID << " dir factor" << endln; - return TCL_ERROR; - break; + opserr << "WARNING cannot read direction for excitation \n"; + opserr << "UniformExcitation " << patternID << " dir factor" << endln; + return TCL_ERROR; + break; } } else dir--; // change to c++ indexing @@ -473,12 +473,43 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, thePattern = theTclMultiSupportPattern; if (thePattern == 0) { - opserr << "WARNING ran out of memory creating load pattern - pattern MultipleSupportExcitation "; - opserr << patternID << endln; + opserr << "WARNING ran out of memory creating load pattern - pattern MultipleSupportExcitation "; + opserr << patternID << endln; } commandEndMarker = 2; } + +#ifdef _H5DRM + else if ((strcmp(argv[1],"H5DRM") == 0) || + (strcmp(argv[1],"h5drm") == 0) ) + { + int tag = 0; + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING insufficient number of arguments - want: pattern "; + opserr << "H5DRM tag filename factor\n"; + return TCL_ERROR; + } + + std::string filename = argv[3]; + double factor=1.0; + if (Tcl_GetDouble(interp, argv[4], &factor) != TCL_OK) + { + opserr << "WARNING insufficient number of arguments - want: pattern "; + opserr << "H5DRM " << patternID << " filename factor\n"; + return TCL_ERROR; + } + + opserr << "Creating H5DRM tag = " << tag << " filename = " << filename.c_str() << " factor = " << factor << endln; + + thePattern = new H5DRM(tag, filename, factor); + + opserr << "Done! Creating H5DRM tag = " << tag << " filename = " << filename.c_str() << " factor = " << factor << endln; + + theDomain->addLoadPattern(thePattern); + return TCL_OK; + } +#endif //////// //////// ///////// ////////// ///// // DRMLoadPattern add BEGIN else if (strcmp(argv[1],"DRMLoadPattern") == 0) { @@ -498,7 +529,7 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, ifile >> ele_d[2]; double* drm_box_crds = new double[6]; for (int i=0; i<6; i++) - ifile >> drm_box_crds[i]; + ifile >> drm_box_crds[i]; int n1; ifile >> n1; int n2; ifile >> n2; @@ -508,21 +539,21 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, int* f_d = new int[3*(nf-1)]; int ne1,ne2; for (int i=0; i> inps; - files[i] = (char*) inps.c_str(); - if (i <(nf-1)) { - ifile >> ne1; - ifile >> ne2; - f_d[3*i] = (ne1+1)*(ne2+1); - f_d[3*i+1] = ne1; - f_d[3*i+2] = ne2; - } + ifile >> inps; + files[i] = (char*) inps.c_str(); + if (i <(nf-1)) { + ifile >> ne1; + ifile >> ne2; + f_d[3*i] = (ne1+1)*(ne2+1); + f_d[3*i+1] = ne1; + f_d[3*i+2] = ne2; + } } Mesh3DSubdomain * myMesher = new Mesh3DSubdomain(theDomain); PlaneDRMInputHandler* patternhandler = new PlaneDRMInputHandler(1.0,files,nf,dt,0,num_steps,f_d,15,n1,n2, - drm_box_crds,drm_box_crds,ele_d, - myMesher, steps_cached,theDomain); + drm_box_crds,drm_box_crds,ele_d, + myMesher, steps_cached,theDomain); DRMLoadPattern* ptr = new DRMLoadPattern(1,1.0,patternhandler,theDomain); ptr->setMaps(); thePattern = ptr; @@ -537,9 +568,9 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, double* ele_d = new double[3]; double* drm_box_crds = new double[6]; for (int i=0; i<3; i++) { - ele_d[i] = INVALID; - drm_box_crds[2*i] = INVALID; - drm_box_crds[2*i+1] = INVALID; + ele_d[i] = INVALID; + drm_box_crds[2*i] = INVALID; + drm_box_crds[2*i+1] = INVALID; } int nf =6; @@ -554,242 +585,242 @@ TclPatternCommand(ClientData clientData, Tcl_Interp *interp, while ( c_arg < end ) { - - if ((strcmp(argv[c_arg],"-dt") == 0) || (strcmp(argv[c_arg],"-deltaT") == 0) ) { - c_arg++; - if (Tcl_GetDouble(interp,argv[c_arg], &dt) != TCL_OK) { - opserr << " Error reading deltaT for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - } - - if ((strcmp(argv[c_arg],"-numSteps") == 0) || (strcmp(argv[c_arg],"-numberOfSteps") == 0) ) { - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &num_steps) != TCL_OK) { - opserr << " Error reading number of steps for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-stepsCached") == 0) || (strcmp(argv[c_arg],"-cache") == 0) ) { - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &steps_cached) != TCL_OK) { - opserr << " Error reading number of steps for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-gridSize") == 0) || (strcmp(argv[c_arg],"-eleSize") == 0) ) { - c_arg++; - if (Tcl_GetDouble(interp,argv[c_arg], &ele_d[0]) != TCL_OK) { - opserr << " Error reading deltaT for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetDouble(interp,argv[c_arg], &ele_d[1]) != TCL_OK) { - opserr << " Error reading deltaT for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetDouble(interp,argv[c_arg], &ele_d[2]) != TCL_OK) { - opserr << " Error reading deltaT for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-gridDataFace1") == 0) ) { - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &f_d[1]) != TCL_OK) { - opserr << " Error reading grid data f1 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &f_d[2]) != TCL_OK) { - opserr << " Error reading grid data f1 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - f_d[0] = (f_d[1]+1)*(f_d[2]+1); - } - - else if ((strcmp(argv[c_arg],"-gridDataFace2") == 0) ) { - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &f_d[4]) != TCL_OK) { - opserr << " Error reading grid data f2 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &f_d[5]) != TCL_OK) { - opserr << " Error reading grid data f2 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - f_d[3] = (f_d[4]+1)*(f_d[5]+1); - } - - else if ((strcmp(argv[c_arg],"-gridDataFace3") == 0) ) { - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &f_d[7]) != TCL_OK) { - opserr << " Error reading grid data f3 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &f_d[8]) != TCL_OK) { - opserr << " Error reading grid data f3 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - f_d[6] = (f_d[7]+1)*(f_d[8]+1); - } - - else if ((strcmp(argv[c_arg],"-gridDataFace4") == 0) ) { - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &f_d[10]) != TCL_OK) { - opserr << " Error reading grid data f4 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &f_d[11]) != TCL_OK) { - opserr << " Error reading grid data f4 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - f_d[9] = (f_d[10]+1)*(f_d[11]+1); - } - - else if ((strcmp(argv[c_arg],"-gridDataFace5") == 0) ) { - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &f_d[13]) != TCL_OK) { - opserr << " Error reading grid data f5 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &f_d[14]) != TCL_OK) { - opserr << " Error reading grid data f5 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - f_d[12] = (f_d[13]+1)*(f_d[14]+1); - } - - else if ((strcmp(argv[c_arg],"-filePathFace1") == 0) ) { - c_arg++; - std::string tmp(argv[c_arg]); - files[0] = new char[tmp.size()+1]; - strcpy(files[0],tmp.c_str()); - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-filePathFace2") == 0) ) { - c_arg++; - std::string tmp(argv[c_arg]); - files[1] = new char[tmp.size()+1]; - strcpy(files[1],tmp.c_str()); - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-filePathFace3") == 0) ) { - c_arg++; - std::string tmp(argv[c_arg]); - files[2] = new char[tmp.size()+1]; - strcpy(files[2],tmp.c_str()); - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-filePathFace4") == 0) ) { - c_arg++; - std::string tmp(argv[c_arg]); - files[3] = new char[tmp.size()+1]; - strcpy(files[3],tmp.c_str()); - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-filePathFace5a") == 0) ) { - c_arg++; - std::string tmp(argv[c_arg]); - files[4] = new char[tmp.size()+1]; - strcpy(files[4],tmp.c_str()); - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-filePathFace5b") == 0) ) { - c_arg++; - std::string tmp(argv[c_arg]); - files[5] = new char[tmp.size()+1]; - strcpy(files[5],tmp.c_str()); - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-fileFace5aGridPoints") == 0) ) { - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &n1) != TCL_OK) { - opserr << " Error reading grid data f5 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-fileFace5bGridPoints") == 0) ) { - c_arg++; - if (Tcl_GetInt(interp,argv[c_arg], &n2) != TCL_OK) { - opserr << " Error reading grid data f5 for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-factor") == 0) || (strcmp(argv[c_arg],"-Factor") == 0) ) { - c_arg++; - if (Tcl_GetDouble(interp,argv[c_arg], &factor) != TCL_OK) { - opserr << " Error reading number of steps for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - } - - else if ((strcmp(argv[c_arg],"-DRMBoxCrds") == 0) ) { - c_arg++; - if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[0]) != TCL_OK) { - opserr << " Error reading DRM box Crds, xmin for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[1]) != TCL_OK) { - opserr << " Error reading DRM box Crds, xmax for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[2]) != TCL_OK) { - opserr << " Error reading DRM box Crds, ymin for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[3]) != TCL_OK) { - opserr << " Error reading DRM box Crds, ymax for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[4]) != TCL_OK) { - opserr << " Error reading DRM box Crds, zmin for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[5]) != TCL_OK) { - opserr << " Error reading DRM box Crds, zmax for DRMLoadPattern \n"; - exit(-1); - } - c_arg++; - } - + + if ((strcmp(argv[c_arg],"-dt") == 0) || (strcmp(argv[c_arg],"-deltaT") == 0) ) { + c_arg++; + if (Tcl_GetDouble(interp,argv[c_arg], &dt) != TCL_OK) { + opserr << " Error reading deltaT for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + } + + if ((strcmp(argv[c_arg],"-numSteps") == 0) || (strcmp(argv[c_arg],"-numberOfSteps") == 0) ) { + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &num_steps) != TCL_OK) { + opserr << " Error reading number of steps for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-stepsCached") == 0) || (strcmp(argv[c_arg],"-cache") == 0) ) { + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &steps_cached) != TCL_OK) { + opserr << " Error reading number of steps for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-gridSize") == 0) || (strcmp(argv[c_arg],"-eleSize") == 0) ) { + c_arg++; + if (Tcl_GetDouble(interp,argv[c_arg], &ele_d[0]) != TCL_OK) { + opserr << " Error reading deltaT for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetDouble(interp,argv[c_arg], &ele_d[1]) != TCL_OK) { + opserr << " Error reading deltaT for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetDouble(interp,argv[c_arg], &ele_d[2]) != TCL_OK) { + opserr << " Error reading deltaT for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-gridDataFace1") == 0) ) { + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &f_d[1]) != TCL_OK) { + opserr << " Error reading grid data f1 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &f_d[2]) != TCL_OK) { + opserr << " Error reading grid data f1 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + f_d[0] = (f_d[1]+1)*(f_d[2]+1); + } + + else if ((strcmp(argv[c_arg],"-gridDataFace2") == 0) ) { + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &f_d[4]) != TCL_OK) { + opserr << " Error reading grid data f2 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &f_d[5]) != TCL_OK) { + opserr << " Error reading grid data f2 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + f_d[3] = (f_d[4]+1)*(f_d[5]+1); + } + + else if ((strcmp(argv[c_arg],"-gridDataFace3") == 0) ) { + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &f_d[7]) != TCL_OK) { + opserr << " Error reading grid data f3 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &f_d[8]) != TCL_OK) { + opserr << " Error reading grid data f3 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + f_d[6] = (f_d[7]+1)*(f_d[8]+1); + } + + else if ((strcmp(argv[c_arg],"-gridDataFace4") == 0) ) { + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &f_d[10]) != TCL_OK) { + opserr << " Error reading grid data f4 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &f_d[11]) != TCL_OK) { + opserr << " Error reading grid data f4 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + f_d[9] = (f_d[10]+1)*(f_d[11]+1); + } + + else if ((strcmp(argv[c_arg],"-gridDataFace5") == 0) ) { + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &f_d[13]) != TCL_OK) { + opserr << " Error reading grid data f5 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &f_d[14]) != TCL_OK) { + opserr << " Error reading grid data f5 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + f_d[12] = (f_d[13]+1)*(f_d[14]+1); + } + + else if ((strcmp(argv[c_arg],"-filePathFace1") == 0) ) { + c_arg++; + std::string tmp(argv[c_arg]); + files[0] = new char[tmp.size()+1]; + strcpy(files[0],tmp.c_str()); + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-filePathFace2") == 0) ) { + c_arg++; + std::string tmp(argv[c_arg]); + files[1] = new char[tmp.size()+1]; + strcpy(files[1],tmp.c_str()); + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-filePathFace3") == 0) ) { + c_arg++; + std::string tmp(argv[c_arg]); + files[2] = new char[tmp.size()+1]; + strcpy(files[2],tmp.c_str()); + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-filePathFace4") == 0) ) { + c_arg++; + std::string tmp(argv[c_arg]); + files[3] = new char[tmp.size()+1]; + strcpy(files[3],tmp.c_str()); + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-filePathFace5a") == 0) ) { + c_arg++; + std::string tmp(argv[c_arg]); + files[4] = new char[tmp.size()+1]; + strcpy(files[4],tmp.c_str()); + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-filePathFace5b") == 0) ) { + c_arg++; + std::string tmp(argv[c_arg]); + files[5] = new char[tmp.size()+1]; + strcpy(files[5],tmp.c_str()); + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-fileFace5aGridPoints") == 0) ) { + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &n1) != TCL_OK) { + opserr << " Error reading grid data f5 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-fileFace5bGridPoints") == 0) ) { + c_arg++; + if (Tcl_GetInt(interp,argv[c_arg], &n2) != TCL_OK) { + opserr << " Error reading grid data f5 for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-factor") == 0) || (strcmp(argv[c_arg],"-Factor") == 0) ) { + c_arg++; + if (Tcl_GetDouble(interp,argv[c_arg], &factor) != TCL_OK) { + opserr << " Error reading number of steps for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + } + + else if ((strcmp(argv[c_arg],"-DRMBoxCrds") == 0) ) { + c_arg++; + if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[0]) != TCL_OK) { + opserr << " Error reading DRM box Crds, xmin for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[1]) != TCL_OK) { + opserr << " Error reading DRM box Crds, xmax for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[2]) != TCL_OK) { + opserr << " Error reading DRM box Crds, ymin for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[3]) != TCL_OK) { + opserr << " Error reading DRM box Crds, ymax for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[4]) != TCL_OK) { + opserr << " Error reading DRM box Crds, zmin for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + if (Tcl_GetDouble(interp,argv[c_arg], &drm_box_crds[5]) != TCL_OK) { + opserr << " Error reading DRM box Crds, zmax for DRMLoadPattern \n"; + exit(-1); + } + c_arg++; + } + } thePattern = new DRMLoadPatternWrapper(patternID,factor,files,nf,dt,num_steps,f_d,15,n1,n2, - drm_box_crds,ele_d, - steps_cached); + drm_box_crds,ele_d, + steps_cached); theTclMultiSupportPattern = 0; commandEndMarker = c_arg; diff --git a/SRC/domain/pattern/TclSeriesCommand.cpp b/SRC/domain/pattern/TclSeriesCommand.cpp index ba24f95f9d..c5b14f5fde 100644 --- a/SRC/domain/pattern/TclSeriesCommand.cpp +++ b/SRC/domain/pattern/TclSeriesCommand.cpp @@ -45,7 +45,6 @@ #include #include - #ifdef _RELIABILITY #include #include @@ -58,7 +57,6 @@ extern ReliabilityDomain *theReliabilityDomain; extern RandomNumberGenerator *theRandomNumberGenerator; #endif - #include extern SimulationInformation simulationInfo; //extern const char * getInterpPWD(Tcl_Interp *interp); // commands.cpp @@ -79,16 +77,9 @@ extern void *OPS_PulseSeries(void); extern void *OPS_PeerMotion(void); extern void *OPS_PeerNGAMotion(void); +#include #include -extern int OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain); - - TimeSeries * TclTimeSeriesCommand(ClientData clientData, Tcl_Interp *interp, @@ -324,7 +315,6 @@ TclTimeSeriesCommand(ClientData clientData, endMarker++; } - if (filePathName != 0 && fileTimeName == 0 && timeIncr != 0.0) { // const char *pwd = getInterpPWD(interp); @@ -398,7 +388,6 @@ TclTimeSeriesCommand(ClientData clientData, } } - else if ((strcmp(argv[0],"PeerNGADatabase") == 0) || (strcmp(argv[0],"PeerNGAMotion") == 0)) { @@ -434,7 +423,6 @@ TclTimeSeriesCommand(ClientData clientData, } } - #ifdef _RELIABILITY else if (strcmp(argv[0],"DiscretizedRandomProcess") == 0) { @@ -573,8 +561,6 @@ TclTimeSeriesCommand(ClientData clientData, #endif - - else { for (int i = 0; i < argc; i++) opserr << argv[i] << ' '; @@ -611,4 +597,3 @@ TclSeriesCommand(ClientData clientData, Tcl_Interp *interp, TCL_Char *arg) cleanup(argv); return theSeries; } - diff --git a/SRC/domain/pattern/drm/DRMBoundaryLayerDecorator.cpp b/SRC/domain/pattern/drm/DRMBoundaryLayerDecorator.cpp index 6d4d1aab4a..f2a6c6bae5 100644 --- a/SRC/domain/pattern/drm/DRMBoundaryLayerDecorator.cpp +++ b/SRC/domain/pattern/drm/DRMBoundaryLayerDecorator.cpp @@ -1,4 +1,5 @@ #include "DRMBoundaryLayerDecorator.h" +#include DRMBoundaryLayerDecorator:: DRMBoundaryLayerDecorator() diff --git a/SRC/domain/pattern/drm/DRMBoundaryLayerDecorator.h b/SRC/domain/pattern/drm/DRMBoundaryLayerDecorator.h index 1b4f93c65d..cfb01d1bbb 100644 --- a/SRC/domain/pattern/drm/DRMBoundaryLayerDecorator.h +++ b/SRC/domain/pattern/drm/DRMBoundaryLayerDecorator.h @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/SRC/domain/pattern/drm/DRMLoadPattern.cpp b/SRC/domain/pattern/drm/DRMLoadPattern.cpp index 3a78a6e55d..4f9c66c693 100644 --- a/SRC/domain/pattern/drm/DRMLoadPattern.cpp +++ b/SRC/domain/pattern/drm/DRMLoadPattern.cpp @@ -9,8 +9,20 @@ #include "DRMLoadPattern.h" +#include +#include +#include +#include "DRMBoundaryLayerDecorator.h" +#include "DRMInputHandler.h" +#include "Mesh3DSubdomain.h" +#include +#include +#include #include #include + +//using namespace::std; + DRMLoadPattern::DRMLoadPattern(int tag, double cfact, DRMInputHandler* my_handler, Domain* domain) :LoadPattern(tag, PATTERN_TAG_DRMLoadPattern) { diff --git a/SRC/domain/pattern/drm/DRMLoadPattern.h b/SRC/domain/pattern/drm/DRMLoadPattern.h index efdcfa9003..faf1bf0793 100644 --- a/SRC/domain/pattern/drm/DRMLoadPattern.h +++ b/SRC/domain/pattern/drm/DRMLoadPattern.h @@ -34,18 +34,13 @@ #ifndef DRMLoadPattern_h #define DRMLoadPattern_h -#include -#include #include -#include -#include -#include "DRMBoundaryLayerDecorator.h" -#include "DRMInputHandler.h" -#include -#include -#include #include #include +#include + +class DRMInputHandler; +class Domain; class DRMLoadPattern : public LoadPattern { @@ -58,7 +53,6 @@ class DRMLoadPattern : public LoadPattern void applyLoad(double time); void setMaps(); - private: Domain *myDomain; @@ -68,8 +62,6 @@ class DRMLoadPattern : public LoadPattern std::map eNodes; std::map elem; - - std::map storage; std::map storage2; diff --git a/SRC/domain/pattern/drm/DRMLoadPatternWrapper.cpp b/SRC/domain/pattern/drm/DRMLoadPatternWrapper.cpp index 5d2add818e..871d213ff5 100644 --- a/SRC/domain/pattern/drm/DRMLoadPatternWrapper.cpp +++ b/SRC/domain/pattern/drm/DRMLoadPatternWrapper.cpp @@ -13,6 +13,7 @@ * */ #include "DRMLoadPatternWrapper.h" +#include "PlaneDRMInputHandler.h" DRMLoadPatternWrapper::DRMLoadPatternWrapper(int ttag, double cfact, char** on_files, int sfiles, double ddt, int numsteps, int* filedata, int fileDatasize, diff --git a/SRC/domain/pattern/drm/H5DRM.cpp b/SRC/domain/pattern/drm/H5DRM.cpp index ede07db91b..7ad4e5367f 100644 --- a/SRC/domain/pattern/drm/H5DRM.cpp +++ b/SRC/domain/pattern/drm/H5DRM.cpp @@ -33,7 +33,7 @@ #include #include -#include + #include #include #include @@ -68,7 +68,6 @@ bool read_scalar_double_dataset_into_double(const hid_t& h5drm_dataset, std::str bool read_double_dataset_into_vector(const hid_t& h5drm_dataset, std::string dataset_name, Vector& result); bool read_double_dataset_into_matrix(const hid_t& h5drm_dataset, std::string dataset_name, Matrix& result); bool read_int_dataset_into_array(const hid_t& h5drm_dataset, std::string dataset_name, int *& result); - inline void convert_h5drmcrd_to_ops_crd(Vector&v ); inline void convert_h5drmcrd_to_ops_crd(Matrix&xyz ); @@ -94,7 +93,15 @@ void* OPS_H5DRM() double factor = 1.0; OPS_GetDoubleInput(&num, &factor); - thePattern = new H5DRM(tag, filename, factor); + double crd_scale = 1.0; + + if (OPS_GetNumRemainingInputArgs() < 3) + { + OPS_GetDoubleInput(&num, &crd_scale); + opserr << "crd_scale = " << crd_scale << endln; + } + + thePattern = new H5DRM(tag, filename, factor, crd_scale); return thePattern; } @@ -122,7 +129,8 @@ H5DRM::H5DRM() DRMDisplacements(100), DRMAccelerations(100), last_integration_time(0), - crd_scale(1000), + crd_scale(0), + distance_tolerance(0), maxnodetag(0), station_id2data_pos(100) { @@ -146,7 +154,8 @@ H5DRM::H5DRM( int tag, std::string HDF5filename_, double cFactor_, - double crd_scale_) + double crd_scale_, + double distance_tolerance_) : LoadPattern(tag, PATTERN_TAG_H5DRM), HDF5filename(HDF5filename_), DRMForces(100), @@ -154,6 +163,7 @@ H5DRM::H5DRM( DRMAccelerations(100), last_integration_time(0), crd_scale(crd_scale_), + distance_tolerance(distance_tolerance_), maxnodetag(0), station_id2data_pos(100) { @@ -223,10 +233,13 @@ void H5DRM::intitialize() for (int i = 0; i < 10; ++i) { - Plane * newplane = new Plane(id_drm_file, i); - planes.push_back(newplane); + // Plane * newplane = new Plane(id_drm_file, i); + // planes.push_back(newplane); } + + H5DRMout << "Initialize" << endln; + ID internal; Matrix xyz; Vector drmbox_x0; @@ -249,8 +262,7 @@ void H5DRM::intitialize() // last_integration_time = tstart; last_integration_time = theDomain->getCurrentTime(); - - xyz *= crd_scale; + xyz *= crd_scale; drmbox_x0 *= crd_scale; drmbox_xmax *= crd_scale; drmbox_xmin *= crd_scale; @@ -263,7 +275,7 @@ void H5DRM::intitialize() convert_h5drmcrd_to_ops_crd(xyz); int NDRM_points = xyz.noRows(); - double d_tol = 3.0; + double d_tol = distance_tolerance; double d_err = 0; int n_nodes_found = 0; @@ -545,11 +557,11 @@ H5DRM::~H5DRM() { clean_all_data(); // for (int i = 0; i < 10; ++i) - for (auto iter = planes.begin(); iter != planes.end(); ++iter) - { - delete *iter;// planes[i]; - } - planes.clear(); + // for (auto iter = planes.begin(); iter != planes.end(); ++iter) + // { + // delete *iter;// planes[i]; + // } + // planes.clear(); } void H5DRM::clean_all_data() @@ -575,7 +587,7 @@ void H5DRM::clean_all_data() hid_t obj_id_list[H5DRM_MAX_RETURN_OPEN_OBJS]; hsize_t n_obj_open = 10; - while (id_drm_file > 0 && n_obj_open > 0) + while (id_drm_file > 0 and n_obj_open > 0) { int n_objects_closed = 0; n_obj_open = H5Fget_obj_count(id_drm_file, H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_ATTR | H5F_OBJ_LOCAL ); @@ -651,7 +663,7 @@ H5DRM::setDomain(Domain *theDomain) void H5DRM::applyLoad(double time) { - if (! is_initialized) + if (not is_initialized) { intitialize(); } @@ -883,10 +895,10 @@ bool H5DRM::drm_direct_read(double t) bool nanfound = false; for (int i = 0; i < 3; ++i) { - if ( std::isnan(d1[i]) || - std::isnan(a1[i]) || - std::isnan(d2[i]) || - std::isnan(a2[i]) ) + if ( isnan(d1[i]) || + isnan(a1[i]) || + isnan(d2[i]) || + isnan(a2[i]) ) { nanfound = true; } @@ -903,7 +915,7 @@ bool H5DRM::drm_direct_read(double t) if (errorflag1 < 0 || errorflag2 < 0 || errorflag3 < 0 || errorflag4 < 0 || nanfound) { - H5DRMerror << "Failed to read displacement or acceleration array!!\n" << + H5DRMerror << "H5DRM::drm_direct_read - Failed to read displacement or acceleration array!!\n" << " n = " << n << endln << " nodeTag = " << nodeTag << endln << " station_id = " << station_id << endln << @@ -916,7 +928,13 @@ bool H5DRM::drm_direct_read(double t) " mem_start = [" << mem_start[0] << "]" << endln << " stride = [" << stride[0] << ", " << stride[1] << "]" << endln << " count = [" << count[0] << ", " << count[1] << "]" << endln << - " block = [" << block[0] << ", " << block[1] << "]" << endln; + " block = [" << block[0] << ", " << block[1] << "]" << endln << + " errorflag1 = [" << errorflag1 << ", " << block[1] << "]" << endln << + " errorflag2 = [" << errorflag2 << ", " << block[1] << "]" << endln << + " errorflag3 = [" << errorflag3 << ", " << block[1] << "]" << endln << + " errorflag4 = [" << errorflag4 << ", " << block[1] << "]" << endln << + " nanfound = [" << nanfound << ", " << block[1] << "]" << endln ; + exit(-1); } @@ -963,8 +981,26 @@ bool H5DRM::drm_differentiate_displacements(double t) double dtau = (t - t1)/(t2-t1); id_displacement_dataspace = H5Dget_space(id_displacement); - - H5DRMout << "t = " << t << " dt = " << dt << " i1 = " << i1 << " i2 = " << i2 << " t1 = " << t1 << " t2 = " << t2 << " dtau = " << dtau << endln; + hsize_t i_first = i1 - 1; + hsize_t i_last = i1 + 2; + + i_first = i_first < 0 ? 0 : i_first; + i_first = i_first > (hsize_t) number_of_timesteps-1 ? number_of_timesteps-1 : i_first; + + i_last = i_last < 0 ? 0 : i_last; + i_last = i_last > (hsize_t) number_of_timesteps-1 ? number_of_timesteps-1 : i_last; + + hsize_t i_len = (i_last - i_first) + 1; + H5DRMout << "t = " << t + << " dt = " << dt + << " i1 = " << i1 + << " i2 = " << i2 + << " i_first = " << i_first + << " i_last = " << i_last + << " i_len = " << i_len + << " t1 = " << t1 + << " t2 = " << t2 + << " dtau = " << dtau << endln; double umax = -std::numeric_limits::infinity(); double amax = -std::numeric_limits::infinity(); @@ -972,6 +1008,8 @@ bool H5DRM::drm_differentiate_displacements(double t) double amin = std::numeric_limits::infinity(); double dt2 = dt*dt; + + for (int n = 0; n < Nodes.Size(); ++n) { int nodeTag = Nodes(n); @@ -986,21 +1024,12 @@ bool H5DRM::drm_differentiate_displacements(double t) d0[0][0] = d0[1][0] = d0[2][0] = 0.; d0[0][1] = d0[1][1] = d0[2][1] = 0.; d0[0][2] = d0[1][2] = d0[2][2] = 0.; + d0[0][3] = d0[1][3] = d0[2][3] = 0.; d1[0] = d1[1] = d1[2] = 0.; d2[0] = d2[1] = d2[2] = 0.; a1[0] = a1[1] = a1[2] = 0.; a2[0] = a2[1] = a2[2] = 0.; - hsize_t i_first = i1 - 1; - hsize_t i_last = i1 + 2; - - i_first = i_first < 0 ? 0 : i_first; - i_first = i_first > (hsize_t) number_of_timesteps-1 ? number_of_timesteps-1 : i_first; - - i_last = i_last < 0 ? 0 : i_last; - i_last = i_last > (hsize_t) number_of_timesteps-1 ? number_of_timesteps-1 : i_last; - - hsize_t i_len = (i_last - i_first) + 1; hsize_t start[2] = {(hsize_t) data_pos , (hsize_t) i_first}; hsize_t stride[2] = {1 , 1}; hsize_t count[2] = {3 , i_len}; @@ -1027,9 +1056,13 @@ bool H5DRM::drm_differentiate_displacements(double t) H5S_SELECT_SET, mem_start, mem_stride, mem_count, mem_block ); //Read data - herr_t errorflag1 = H5Dread( id_displacement, H5T_NATIVE_DOUBLE, memspace, + herr_t errorflag1 = 0; + if (i1 > 2) + { + errorflag1 = H5Dread( id_displacement, H5T_NATIVE_DOUBLE, memspace, id_displacement_dataspace, id_xfer_plist, d0 ); - + } + for (int dof = 0; dof < 3; ++dof) { @@ -1045,10 +1078,10 @@ bool H5DRM::drm_differentiate_displacements(double t) bool nanfound = false; for (int i = 0; i < 3; ++i) { - if ( std::isnan(d1[i]) || - std::isnan(a1[i]) || - std::isnan(d2[i]) || - std::isnan(a2[i]) ) + if ( isnan(d1[i]) || + isnan(a1[i]) || + isnan(d2[i]) || + isnan(a2[i]) ) { nanfound = true; } @@ -1084,10 +1117,10 @@ bool H5DRM::drm_differentiate_displacements(double t) exit(-1); } - // d1[2] = -d1[2]; - // d2[2] = -d2[2]; - // a1[2] = -a1[2]; - // a2[2] = -a2[2]; + d1[2] = -d1[2]; + d2[2] = -d2[2]; + a1[2] = -a1[2]; + a2[2] = -a2[2]; DRMDisplacements(3 * local_pos + 0) = d1[0]*(1-dtau) + d2[0]*(dtau); @@ -1162,9 +1195,7 @@ bool H5DRM::drm_integrate_velocity(double next_integration_time) int data_pos = station_id2data_pos[station_id]; int local_pos = nodetag2local_pos[nodeTag]; - - //FMK double v[3][Nt]; - double *v = new double[3 * Nt]; + double v[3][Nt]; hsize_t start[2] = {(hsize_t) data_pos , (hsize_t)i1}; hsize_t stride[2] = {1 , 1}; @@ -1213,131 +1244,95 @@ bool H5DRM::drm_integrate_velocity(double next_integration_time) exit(-1); } - for (hsize_t i = 0; i < Nt; ++i) - { - /* FMK - double v0 = v[0][i]; - double v1 = v[1][i]; - v[0][i] = v0; - v[1][i] = v1; - v[2][i] = -v[2][i]; - */ - double v0 = v[0 + i * 3]; - double v1 = v[1 + i * 3]; - v[0 + i * 3] = v0; - v[1 + i * 3] = v1; - v[2 + i * 3] = -v[2 + i * Nt]; + for (hsize_t i = 0; i < Nt; ++i) + { + double v0 = v[0][i]; + double v1 = v[1][i]; + v[0][i] = v0; + v[1][i] = v1; + v[2][i] = -v[2][i]; } - for (hsize_t i = 0; i < Nt; ++i) - { - double dtau = 0; - double tau_1 = tstart + i * dt; - double tau_2 = tstart + (i + 1) * dt; - tau_1 = tau_1 > t1 ? tau_1 : t1; - tau_2 = tau_2 < t2 ? tau_2 : t2; - dtau = tau_2 - tau_1; - - if (dtau <= 0) - continue; - - - - if (DEBUG_DRM_INTEGRATION) - { - /* FMK - fprintf(fptr, "i = %d dtau=%f tau_1=%f tau_2=%f dt=%f local_pos=%d dir=%d\n", (int) i, dtau, tau_1, tau_2, dt, local_pos, dir ); - fprintf(fptr, " DRMDisplacements(3 * local_pos + 0) = %f --> v[0][i] = %f v[0][i+1] = %f\n", DRMDisplacements(3 * local_pos + 0), v[0][i], v[0][i + 1] ); - fprintf(fptr, " DRMDisplacements(3 * local_pos + 1) = %f --> v[1][i] = %f v[1][i+1] = %f\n", DRMDisplacements(3 * local_pos + 1), v[1][i], v[1][i + 1] ); - fprintf(fptr, " DRMDisplacements(3 * local_pos + 2) = %f --> v[2][i] = %f v[2][i+1] = %f\n", DRMDisplacements(3 * local_pos + 2), v[2][i], v[2][i + 1] ); - ******/ - fprintf(fptr, "i = %d dtau=%f tau_1=%f tau_2=%f dt=%f local_pos=%d dir=%d\n", (int)i, dtau, tau_1, tau_2, dt, local_pos, dir); - fprintf(fptr, " DRMDisplacements(3 * local_pos + 0) = %f --> v[0][i] = %f v[0][i+1] = %f\n", DRMDisplacements(3 * local_pos + 0), v[0 + i * Nt], v[0 + (i + 1)*3]); - fprintf(fptr, " DRMDisplacements(3 * local_pos + 1) = %f --> v[1][i] = %f v[1][i+1] = %f\n", DRMDisplacements(3 * local_pos + 1), v[1 + i * Nt], v[1 + (i + 1)*3]); - fprintf(fptr, " DRMDisplacements(3 * local_pos + 2) = %f --> v[2][i] = %f v[2][i+1] = %f\n", DRMDisplacements(3 * local_pos + 2), v[2 + i * Nt], v[2 + (i + 1)*3]); - - } - - double u1 = DRMDisplacements(3 * local_pos + 0); - double u2 = DRMDisplacements(3 * local_pos + 1); - double u3 = DRMDisplacements(3 * local_pos + 2); - /* FMK - double du1 = (v[0][i] + v[0][i + 1]) * (dir * dtau / 2); - double du2 = (v[1][i] + v[1][i + 1]) * (dir * dtau / 2); - double du3 = (v[2][i] + v[2][i + 1]) * (dir * dtau / 2); - ******/ - double du1 = (v[0 + i * 3] + v[0 + (i + 1)*3]) * (dir * dtau / 2); - double du2 = (v[1 + i * 3] + v[1 + (i + 1)*3]) * (dir * dtau / 2); - double du3 = (v[2 + i * 3] + v[2 + (i + 1)*3]) * (dir * dtau / 2); - - DRMDisplacements(3 * local_pos + 0) += du1; - DRMDisplacements(3 * local_pos + 1) += du2; - DRMDisplacements(3 * local_pos + 2) += du3; - - if (DEBUG_DRM_INTEGRATION) - { - fprintf(fptr, " DRMDisplacements(3 * local_pos + 0) = %f \n", DRMDisplacements(3 * local_pos + 0)); - fprintf(fptr, " DRMDisplacements(3 * local_pos + 1) = %f \n", DRMDisplacements(3 * local_pos + 1)); - fprintf(fptr, " DRMDisplacements(3 * local_pos + 2) = %f \n", DRMDisplacements(3 * local_pos + 2)); - } - - // bool found_nan = false; - if (std::isnan(u1) || std::isnan(du1) || - std::isnan(u2) || std::isnan(du2) || - std::isnan(u3) || std::isnan(du3) || - std::isnan(dt) || std::isnan(dtau)) - { - H5DRMerror << "NAN Detected!!! \n"; - H5DRMerror << " nodeTag = " << nodeTag << endln; - H5DRMerror << " local_pos = " << local_pos << endln; - printf(" i = %d dtau=%f tau_1=%f tau_2=%f dt=%f local_pos=%d dir=%d\n", (int)i, dtau, tau_1, tau_2, dt, local_pos, dir); - printf(" u1 = %f du1 = %f \n", u1, du1); - printf(" u2 = %f du2 = %f \n", u2, du2); - printf(" u3 = %f du3 = %f \n", u3, du3); - /* FMK - printf(" DRMDisplacements(3 * local_pos + 0) = %f --> v[0][i] = %f v[0][i+1] = %f\n", DRMDisplacements(3 * local_pos + 0), v[0][i], v[0][i + 1] ); - printf(" DRMDisplacements(3 * local_pos + 1) = %f --> v[1][i] = %f v[1][i+1] = %f\n", DRMDisplacements(3 * local_pos + 1), v[1][i], v[1][i + 1] ); - printf(" DRMDisplacements(3 * local_pos + 2) = %f --> v[2][i] = %f v[2][i+1] = %f\n", DRMDisplacements(3 * local_pos + 2), v[2][i], v[2][i + 1] ); - */ - printf(" DRMDisplacements(3 * local_pos + 0) = %f --> v[0][i] = %f v[0][i+1] = %f\n", DRMDisplacements(3 * local_pos + 0), v[0 + i * 3], v[0 + (i + 1)*3]); - printf(" DRMDisplacements(3 * local_pos + 1) = %f --> v[1][i] = %f v[1][i+1] = %f\n", DRMDisplacements(3 * local_pos + 1), v[1 + i * 3], v[1 + (i + 1)*3]); - printf(" DRMDisplacements(3 * local_pos + 2) = %f --> v[2][i] = %f v[2][i+1] = %f\n", DRMDisplacements(3 * local_pos + 2), v[2 + i * 3], v[2 + (i + 1)*3]); - exit(-1); - } - - } + for (hsize_t i = 0; i < Nt; ++i) + { + double dtau = 0; + double tau_1 = tstart + i * dt; + double tau_2 = tstart + (i + 1) * dt; + tau_1 = tau_1 > t1 ? tau_1 : t1; + tau_2 = tau_2 < t2 ? tau_2 : t2; + dtau = tau_2 - tau_1; + + if (dtau <= 0) + continue; + + + + if (DEBUG_DRM_INTEGRATION) + { + fprintf(fptr, "i = %d dtau=%f tau_1=%f tau_2=%f dt=%f local_pos=%d dir=%d\n", (int) i, dtau, tau_1, tau_2, dt, local_pos, dir ); + fprintf(fptr, " DRMDisplacements(3 * local_pos + 0) = %f --> v[0][i] = %f v[0][i+1] = %f\n", DRMDisplacements(3 * local_pos + 0), v[0][i], v[0][i + 1] ); + fprintf(fptr, " DRMDisplacements(3 * local_pos + 1) = %f --> v[1][i] = %f v[1][i+1] = %f\n", DRMDisplacements(3 * local_pos + 1), v[1][i], v[1][i + 1] ); + fprintf(fptr, " DRMDisplacements(3 * local_pos + 2) = %f --> v[2][i] = %f v[2][i+1] = %f\n", DRMDisplacements(3 * local_pos + 2), v[2][i], v[2][i + 1] ); + } + + double u1 = DRMDisplacements(3 * local_pos + 0); + double u2 = DRMDisplacements(3 * local_pos + 1); + double u3 = DRMDisplacements(3 * local_pos + 2); + double du1 = (v[0][i] + v[0][i + 1]) * (dir * dtau / 2); + double du2 = (v[1][i] + v[1][i + 1]) * (dir * dtau / 2); + double du3 = (v[2][i] + v[2][i + 1]) * (dir * dtau / 2); + + DRMDisplacements(3 * local_pos + 0) += du1; + DRMDisplacements(3 * local_pos + 1) += du2; + DRMDisplacements(3 * local_pos + 2) += du3; + + if (DEBUG_DRM_INTEGRATION) + { + fprintf(fptr, " DRMDisplacements(3 * local_pos + 0) = %f \n", DRMDisplacements(3 * local_pos + 0) ); + fprintf(fptr, " DRMDisplacements(3 * local_pos + 1) = %f \n", DRMDisplacements(3 * local_pos + 1) ); + fprintf(fptr, " DRMDisplacements(3 * local_pos + 2) = %f \n", DRMDisplacements(3 * local_pos + 2) ); + } + + // bool found_nan = false; + if (isnan(u1) || isnan(du1) || + isnan(u2) || isnan(du2) || + isnan(u3) || isnan(du3) || + isnan(dt) || isnan(dtau) ) + { + H5DRMerror << "NAN Detected!!! \n"; + H5DRMerror << " nodeTag = " << nodeTag << endln; + H5DRMerror << " local_pos = " << local_pos << endln; + printf(" i = %d dtau=%f tau_1=%f tau_2=%f dt=%f local_pos=%d dir=%d\n", (int)i, dtau, tau_1, tau_2, dt, local_pos, dir ); + printf(" u1 = %f du1 = %f \n", u1, du1); + printf(" u2 = %f du2 = %f \n", u2, du2); + printf(" u3 = %f du3 = %f \n", u3, du3); + printf(" DRMDisplacements(3 * local_pos + 0) = %f --> v[0][i] = %f v[0][i+1] = %f\n", DRMDisplacements(3 * local_pos + 0), v[0][i], v[0][i + 1] ); + printf(" DRMDisplacements(3 * local_pos + 1) = %f --> v[1][i] = %f v[1][i+1] = %f\n", DRMDisplacements(3 * local_pos + 1), v[1][i], v[1][i + 1] ); + printf(" DRMDisplacements(3 * local_pos + 2) = %f --> v[2][i] = %f v[2][i+1] = %f\n", DRMDisplacements(3 * local_pos + 2), v[2][i], v[2][i + 1] ); + exit(-1); + } + + } int eval_i = (int) (t2 - t1) / dt; - /*FMK + DRMAccelerations(3 * local_pos + 0) = (v[0][eval_i] - v[0][eval_i + 1]) / dt; - DRMAccelerations(3 * local_pos + 1) = (v[1][eval_i*] - v[1][eval_i + 1]) / dt; + DRMAccelerations(3 * local_pos + 1) = (v[1][eval_i] - v[1][eval_i + 1]) / dt; DRMAccelerations(3 * local_pos + 2) = (v[2][eval_i] - v[2][eval_i + 1]) / dt; - */ - DRMAccelerations(3 * local_pos + 0) = (v[0*eval_i*3] - v[0 + (eval_i + 1)*3]) / dt; - DRMAccelerations(3 * local_pos + 1) = (v[1*eval_i*3] - v[1 + (eval_i + 1)*3]) / dt; - DRMAccelerations(3 * local_pos + 2) = (v[2*eval_i*3] - v[2 + (eval_i + 1)*3]) / dt; + if (DEBUG_DRM_INTEGRATION) { - fprintf(fptr, "eval_i = %d \n", eval_i); - /* FMK + fprintf(fptr, "eval_i = %d \n", eval_i ); fprintf(fptr, " v[0][eval_i] = %f v[0][eval_i+1] = %f\n", v[0][eval_i], v[0][eval_i + 1] ); fprintf(fptr, " v[1][eval_i] = %f v[1][eval_i+1] = %f\n", v[1][eval_i], v[1][eval_i + 1] ); fprintf(fptr, " v[2][eval_i] = %f v[2][eval_i+1] = %f\n", v[2][eval_i], v[2][eval_i + 1] ); - *****/ - fprintf(fptr, " v[0][eval_i] = %f v[0][eval_i+1] = %f\n", v[0 * eval_i*3], v[0 + (eval_i + 1)*3]); - fprintf(fptr, " v[1][eval_i] = %f v[1][eval_i+1] = %f\n", v[1 * eval_i*3], v[1 + (eval_i + 1)*3]); - fprintf(fptr, " v[2][eval_i] = %f v[2][eval_i+1] = %f\n", v[2 * eval_i*3], v[2 + (eval_i + 1)*3]); - fprintf(fptr, " DRMAccelerations(3 * local_pos + 0) = %f\n", DRMAccelerations(3 * local_pos + 0) ); fprintf(fptr, " DRMAccelerations(3 * local_pos + 1) = %f\n", DRMAccelerations(3 * local_pos + 1) ); fprintf(fptr, " DRMAccelerations(3 * local_pos + 2) = %f\n", DRMAccelerations(3 * local_pos + 2) ); } - - // FMK - delete []v; } @@ -1368,9 +1363,10 @@ H5DRM::ComputeDRMLoads(double t) DRMForces.Zero(); - if (tstart > t || t > tend) + if ( t < tstart || tend < t) { - return false; + // Will assume that DRM forces are null outside of the defined range... + return true; } @@ -1385,6 +1381,8 @@ H5DRM::ComputeDRMLoads(double t) Element *theElement = theDomain->getElement( Elements[0] ); int NIE = 8; + B_node.resize(NIEMAX); + E_node.resize(NIEMAX); for (int e = 0; e < Elements.Size(); e++) { @@ -1397,9 +1395,8 @@ H5DRM::ComputeDRMLoads(double t) const ID &elementNodes = theElement->getExternalNodes(); //Identify boundary and exterior nodes for this element - B_node.resize(NIE); - E_node.resize(NIE); - + NIE = elementNodes.Size(); + int nB = 0, nE = 0; for ( int ii = 0; ii < NIE; ii++) { @@ -1418,7 +1415,7 @@ H5DRM::ComputeDRMLoads(double t) } } - if ( nB != 0 && nE != 0 ) + if ( nB != 0 and nE != 0 ) { //Mass and stiffness matrices Matrix Me = theElement->getMass(); @@ -1480,9 +1477,9 @@ H5DRM::ComputeDRMLoads(double t) DRMForces( 3 * local_pos + 2) += Fk(3 * k + 2) + Fm(3 * k + 2); - if (std::isnan(DRMForces( 3 * local_pos + 0) ) || - std::isnan(DRMForces( 3 * local_pos + 1) ) || - std::isnan(DRMForces( 3 * local_pos + 2) ) ) + if (isnan(DRMForces( 3 * local_pos + 0) ) || + isnan(DRMForces( 3 * local_pos + 1) ) || + isnan(DRMForces( 3 * local_pos + 2) ) ) { H5DRMerror << "NAN Detected!!! \n"; H5DRMerror << " nodeTag = " << nodeTag << endln; @@ -1536,9 +1533,11 @@ H5DRM::sendSelf(int commitTag, Channel & theChannel) H5DRMout << "sending filename: " << HDF5filename << endl; - static Vector data(2); + static Vector data(3); data(0) = cFactor; data(1) = crd_scale; + data(2) = distance_tolerance; + char drmfilename[H5DRM_MAX_FILENAME]; strcpy(drmfilename, HDF5filename.c_str()); Message filename_msg(drmfilename, H5DRM_MAX_FILENAME); @@ -1564,7 +1563,7 @@ H5DRM::recvSelf(int commitTag, Channel & theChannel, FEM_ObjectBroker & theBroker) { H5DRMout << "receiving...\n"; - static Vector data(2); + static Vector data(3); char drmfilename[H5DRM_MAX_FILENAME]; Message filename_msg(drmfilename, H5DRM_MAX_FILENAME); @@ -1583,8 +1582,10 @@ H5DRM::recvSelf(int commitTag, Channel & theChannel, } cFactor = data(0); crd_scale = data(1); + distance_tolerance = data(2); HDF5filename = drmfilename; + H5DRMout << "received filename is " << drmfilename << "\n"; return 0; } @@ -1599,7 +1600,8 @@ H5DRM::Print(ostream & s, int flag) // method to obtain a blank copy of the LoadPattern LoadPattern * -H5DRM::getCopy(void){ +H5DRM::getCopy(void) +{ return new H5DRM(this->getTag(), HDF5filename); } @@ -1709,8 +1711,7 @@ void H5DRM::node_matching_BruteForce(double d_tol, const ID & internal, const Ma { H5DRMout << "node_matching_BruteForce - Begin!\n"; - //opserr << xyz.noCols() << " " << xyz.noRows() << " " << drmbox_x0.Size() << "\n"; - //opserr << xyz; + char debugfilename[100]; sprintf(debugfilename, "debugdrmbruteforce.%d.txt", myrank); FILE * fptrdrm; @@ -1723,22 +1724,16 @@ void H5DRM::node_matching_BruteForce(double d_tol, const ID & internal, const Ma Node* node_ptr = 0; int drmtag = NDRM_points; int local_pos = 0; - // int counter = 0; - // opserr << xyz; - while ((node_ptr = node_iter()) != 0) { int tag = node_ptr->getTag(); const Vector& node_xyz = node_ptr->getCrds(); double dmin = std::numeric_limits::infinity(); int ii_station_min = 0; - - //opserr << "dmin: " << dmin << " dTol: " << d_tol << "\n"; if (DEBUG_NODE_MATCHING) fprintf(fptrdrm, "%d %f %f %f\n", ++drmtag, node_xyz[0] + drmbox_x0[0], node_xyz[1] + drmbox_x0[1], node_xyz[2] + drmbox_x0[2]); - - Vector station_xyz(3); + Vector station_xyz(3); for (int ii = 0; ii < xyz.noRows(); ++ii) { station_xyz(0) = xyz(ii, 0); @@ -1751,16 +1746,8 @@ void H5DRM::node_matching_BruteForce(double d_tol, const ID & internal, const Ma ii_station_min = ii; } } - - /* - counter++; - if (counter <= 10) - opserr << tag << " " << counter << " dmin:" << dmin << " " << ii_station_min << "\n"; - */ - if (fabs(dmin) < d_tol) { - //opserr << "dmin:" << dmin << " " << ii_station_min << "\n"; int station_id = ii_station_min; static Vector station_xyz(3); for (int dir = 0; dir < 3; ++dir) @@ -1833,7 +1820,8 @@ bool read_int_dataset_into_id(const hid_t & h5drm_dataset, std::string dataset_n int ndims = H5Sget_simple_extent_ndims( id_dataspace); if (ndims != 1) { - opserr << "read_double_dataset_into_vector - array dimension should be 1\n"; + opserr << "failure trying to open dataset: " << dataset_name.c_str() << endln; + opserr << "read_int_dataset_into_id - array dimension should be 1\n"; Vector error(-1); return false; } @@ -1844,8 +1832,7 @@ bool read_int_dataset_into_id(const hid_t & h5drm_dataset, std::string dataset_n hid_t id_memspace = H5Screate_simple(1, &dim, 0); // create dataspace of memory hid_t id_xfer_plist = H5Pcreate(H5P_DATASET_XFER); - // FMK int d[dim]; - int *d = new int[dim]; + int d[dim]; H5Dread( id_dataset, H5T_NATIVE_INT, id_memspace, id_dataspace, id_xfer_plist, d); result.resize(dim); @@ -1858,9 +1845,6 @@ bool read_int_dataset_into_id(const hid_t & h5drm_dataset, std::string dataset_n H5Sclose(id_memspace); H5Dclose(id_dataset); - //FMK - delete[]d; - return true; } @@ -1871,7 +1855,8 @@ bool read_double_dataset_into_vector(const hid_t & h5drm_dataset, std::string da int ndims = H5Sget_simple_extent_ndims( id_dataspace); if (ndims != 1) { - opserr << "read_double_dataset_into_vector - array dimension should be 1\n"; + opserr << "failure trying to open dataset: " << dataset_name.c_str() << endln; + opserr << "read_double_dataset_into_vector - array dimension should be 1.\n"; Vector error(-1); return false; } @@ -1882,8 +1867,7 @@ bool read_double_dataset_into_vector(const hid_t & h5drm_dataset, std::string da hid_t id_memspace = H5Screate_simple(1, &dim, 0); // create dataspace of memory hid_t id_xfer_plist = H5Pcreate(H5P_DATASET_XFER); - //double d[dim]; - double *d = new double[dim]; + double d[dim]; H5Dread( id_dataset, H5T_NATIVE_DOUBLE, id_memspace, id_dataspace, id_xfer_plist, d); result.resize(dim); @@ -1896,8 +1880,6 @@ bool read_double_dataset_into_vector(const hid_t & h5drm_dataset, std::string da H5Sclose(id_memspace); H5Dclose(id_dataset); - //FMK - delete[]d; return true; } @@ -1909,6 +1891,7 @@ bool read_scalar_double_dataset_into_double(const hid_t & h5drm_dataset, std::st int ndims = H5Sget_simple_extent_ndims( id_dataspace); if (ndims != 0) { + opserr << "failure trying to open dataset: " << dataset_name.c_str() << endln; opserr << "read_scalar_double_dataset_into_double - array dimension should be 0\n"; Vector error(-1); return false; @@ -1936,6 +1919,7 @@ bool read_double_dataset_into_matrix(const hid_t & h5drm_dataset, std::string da int ndims = H5Sget_simple_extent_ndims( id_dataspace); if (ndims != 2) { + opserr << "failure trying to open dataset: " << dataset_name.c_str() << endln; opserr << "read_double_dataset_into_matrix - array dimension should be 2\n"; Vector error(-1); return false; @@ -1947,31 +1931,22 @@ bool read_double_dataset_into_matrix(const hid_t & h5drm_dataset, std::string da hid_t id_memspace = H5Screate_simple(2, dim, 0); // create dataspace of memory hid_t id_xfer_plist = H5Pcreate(H5P_DATASET_XFER); - //FMK double d[dim[0]][dim[1]]; - - std::cerr << dim[0] << " " << dim[1] << "\n"; + double d[dim[0]][dim[1]]; - double *d = new double[dim[0] * dim[1]]; - H5Dread( id_dataset, H5T_NATIVE_DOUBLE, id_memspace, id_dataspace, id_xfer_plist, d); result.resize(dim[0], dim[1]); - //result.setData(d, dim[0], dim[1]); - for (hsize_t i = 0; i < dim[0]; ++i) { for (hsize_t j = 0; j < dim[1]; ++j) { - //FMK result(i, j) = d[i][j]; - result(i, j) = d[i * dim[1] + j]; + result(i, j) = d[i][j]; } } - + H5Sclose(id_dataspace); H5Sclose(id_memspace); H5Dclose(id_dataset); - // FMK - delete[]d; return true; } @@ -1983,7 +1958,8 @@ bool read_int_dataset_into_array(const hid_t & h5drm_dataset, std::string datase int ndims = H5Sget_simple_extent_ndims( id_dataspace); if (ndims != 2) { - opserr << "read_double_dataset_into_matrix - array dimension should be 2\n"; + opserr << "failure trying to open dataset: " << dataset_name.c_str() << endln; + opserr << "read_int_dataset_into_array - array dimension should be 2\n"; Vector error(-1); return false; } @@ -2141,21 +2117,22 @@ void Plane::print(FILE * fptr) const void convert_h5drmcrd_to_ops_crd(Vector & v ) { - static Vector v_tmp(3); - v_tmp = v; - v(0) = v_tmp(1); - v(1) = v_tmp(0); - v(2) = -v_tmp(2); + // static Vector v_tmp(3); + // v_tmp = v; + // v(0) = v_tmp(1); + // v(1) = v_tmp(0); + // v(2) = -v_tmp(2); } + void convert_h5drmcrd_to_ops_crd(Matrix & xyz ) { - int nrows = xyz.noRows(); - Matrix tmp_xyz(xyz); - for (int i = 0; i < nrows; ++i) - { - xyz(i, 0) = tmp_xyz(i, 1); - xyz(i, 1) = tmp_xyz(i, 0); - xyz(i, 2) = -tmp_xyz(i, 2); - } + // int nrows = xyz.noRows(); + // Matrix tmp_xyz(xyz); + // for (int i = 0; i < nrows; ++i) + // { + // xyz(i, 0) = tmp_xyz(i, 1); + // xyz(i, 1) = tmp_xyz(i, 0); + // xyz(i, 2) = -tmp_xyz(i, 2); + // } } diff --git a/SRC/domain/pattern/drm/H5DRM.h b/SRC/domain/pattern/drm/H5DRM.h index 7039c41cf3..ce14f41c41 100644 --- a/SRC/domain/pattern/drm/H5DRM.h +++ b/SRC/domain/pattern/drm/H5DRM.h @@ -119,7 +119,7 @@ class Matrix; class Plane { public: - Plane(const hid_t& id_h5drm_file, int plane_number, double crd_scale = 1000); + Plane(const hid_t& id_h5drm_file, int plane_number, double crd_scale = 1); ~Plane(); bool locate_point(const Vector& x, double& xi1, double& xi2, double& distance) const ; @@ -149,7 +149,7 @@ class H5DRM : public LoadPattern { public: H5DRM(); - H5DRM(int tag, std::string HDF5filename_, double cFactor_ = 1.0, double crd_scale_ = 1000); + H5DRM(int tag, std::string HDF5filename_, double cFactor_ = 1.0, double crd_scale_ = 1, double distance_tolerance_ = 1e-3); ~H5DRM(); void clean_all_data(); // Called by destructor and if domain changes @@ -197,6 +197,7 @@ class H5DRM : public LoadPattern double t1, t2, tstart, tend, dt; // specifies the time increment used in load path vector double cFactor; // additional factor on the returned load factor double crd_scale; // Scaling for the point coordinates of the DRM dataset + double distance_tolerance; // Distance tolerance for node-matching algorithm int step, step1, step2; double drmbox_xmax, drmbox_xmin, drmbox_ymax, drmbox_ymin, drmbox_zmax, drmbox_zmin; diff --git a/SRC/domain/pattern/drm/Makefile b/SRC/domain/pattern/drm/Makefile index 48dd213530..8f348decf8 100644 --- a/SRC/domain/pattern/drm/Makefile +++ b/SRC/domain/pattern/drm/Makefile @@ -1,7 +1,7 @@ include ../../../../Makefile.def ifdef H5DRM_FLAG - H5_FILE = H5DRM.o + H5_FILE = H5DRM.o else H5_FIle = endif @@ -12,7 +12,8 @@ OBJS = Mesh3DSubdomain.o \ DRMLoadPattern.o \ DRMLoadPatternWrapper.o \ DRMInputHandler.o \ - PlaneDRMInputHandler.o $(H5_FILE) + PlaneDRMInputHandler.o \ + $(H5_FILE) all: $(OBJS) diff --git a/SRC/domain/pattern/drm/Mesh3DSubdomain.cpp b/SRC/domain/pattern/drm/Mesh3DSubdomain.cpp index c5d5a9f835..32a9472070 100644 --- a/SRC/domain/pattern/drm/Mesh3DSubdomain.cpp +++ b/SRC/domain/pattern/drm/Mesh3DSubdomain.cpp @@ -1,4 +1,41 @@ #include "Mesh3DSubdomain.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// includes for the domain classes +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "GeometricBrickDecorator.h" +#include +using namespace std; + + #include #include #include diff --git a/SRC/domain/pattern/drm/Mesh3DSubdomain.h b/SRC/domain/pattern/drm/Mesh3DSubdomain.h index 744c54527c..a7efbcf4ea 100644 --- a/SRC/domain/pattern/drm/Mesh3DSubdomain.h +++ b/SRC/domain/pattern/drm/Mesh3DSubdomain.h @@ -1,47 +1,12 @@ #ifndef Mesh3DSubdomain_h #define Mesh3DSubdomain_h -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -// includes for the domain classes -#include -#include -#include -#include #include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include "GeometricBrickDecorator.h" - #include #include -#include -using namespace std; +class Domain; + class Mesh3DSubdomain { @@ -81,9 +46,6 @@ class Mesh3DSubdomain { int myLastStartNodeTag; int myLastEle; int myLastNode; - - - }; #endif diff --git a/SRC/domain/subdomain/ActorSubdomain.h b/SRC/domain/subdomain/ActorSubdomain.h index 78c55df446..6a572de16a 100644 --- a/SRC/domain/subdomain/ActorSubdomain.h +++ b/SRC/domain/subdomain/ActorSubdomain.h @@ -36,7 +36,7 @@ // // What: "@(#) ActorSubdomain.h, revA" -#include +#include "Subdomain.h" #include class ActorSubdomain: public Subdomain, public Actor diff --git a/SRC/domain/subdomain/Subdomain.h b/SRC/domain/subdomain/Subdomain.h index ff3a8e6f0f..84d2bde607 100644 --- a/SRC/domain/subdomain/Subdomain.h +++ b/SRC/domain/subdomain/Subdomain.h @@ -53,7 +53,7 @@ class EigenSOE; class ConvergenceTest; class FE_Element; -#include +#include "SubdomainNodIter.h" class Subdomain: public Element, public Domain { diff --git a/SRC/element/Element.cpp b/SRC/element/Element.cpp index 55b45b50d3..cda7167afd 100644 --- a/SRC/element/Element.cpp +++ b/SRC/element/Element.cpp @@ -58,7 +58,8 @@ int Element::numMatrices(0); Element::Element(int tag, int cTag) :DomainComponent(tag, cTag), alphaM(0.0), betaK(0.0), betaK0(0.0), betaKc(0.0), - Kc(0), previousK(0), numPreviousK(0), index(-1), nodeIndex(-1) + Kc(0), previousK(0), numPreviousK(0), index(-1), nodeIndex(-1), + is_this_element_active(true) { // does nothing ops_TheActiveElement = this; @@ -770,3 +771,52 @@ Element::getGeometricTangentStiff() return *theMatrix; } + +void Element::activate() +{ + // opserr << "Activating element # " << this->getTag() << endln; + is_this_element_active = true; + this->onActivate(); +} + +void Element::deactivate() +{ + // opserr << "Deactivating element # " << this->getTag() << endln; + is_this_element_active = false; + this->onDeactivate(); +} + + +void Element::onActivate() +{ + static bool report_once = true; + if (report_once) + { + opserr << "onActivate not implemented for this element. classTag = " << this->getClassTag() << endln; + report_once = false; + } +} + +void Element::onDeactivate() +{ static bool report_once = true; + if (report_once) + { + opserr << "onDeactivate not implemented for this element. classTag = " << this->getClassTag() << endln; + report_once = false; + } +} + + +bool Element::isActive() +{ + // opserr << "Element::isActive() [tag = " << this->getTag() << "] = "; + // if (is_this_element_active) + // { + // opserr << "TRUE" << endln; + // } + // else + // { + // opserr << "FALSE" << endln; + // } + return is_this_element_active; +} diff --git a/SRC/element/Element.h b/SRC/element/Element.h index d69c99f246..6cd3648ba6 100644 --- a/SRC/element/Element.h +++ b/SRC/element/Element.h @@ -112,9 +112,16 @@ class Element : public DomainComponent virtual int storePreviousK(int numK); virtual const Matrix *getPreviousK(int num); -#if _DLL - const Vector& getRayleighDampingForces(void); -#endif + virtual void onActivate(); + virtual void onDeactivate(); + + void activate(); + void deactivate(); + + bool isActive(); + + + protected: #if !_DLL const Vector& getRayleighDampingForces(void); @@ -132,6 +139,8 @@ class Element : public DomainComponent static Vector ** theVectors2; static int numMatrices; + bool is_this_element_active; + private: }; diff --git a/SRC/element/PFEMElement/BackgroundMesh.cpp b/SRC/element/PFEMElement/BackgroundMesh.cpp index 3094b65317..0a43063bb1 100644 --- a/SRC/element/PFEMElement/BackgroundMesh.cpp +++ b/SRC/element/PFEMElement/BackgroundMesh.cpp @@ -38,7 +38,9 @@ #ifdef _LINUX #include #endif +#ifdef _OPENMP #include +#endif #include #include #include @@ -3016,8 +3018,12 @@ BackgroundMesh::convectParticle(Particle* pt, VInt index, int level, int nums) VDouble pns, dpns; // convect in a cell - double subdt = dt / nums; - for (int n=0; ngetDt() > 0) { + // get subdt + double subdt = dt / nums; + if (pt->getDt() < subdt) { + subdt = pt->getDt(); + } // particle crds const VDouble& pcrds = pt->getCrds(); @@ -3029,7 +3035,7 @@ BackgroundMesh::convectParticle(Particle* pt, VInt index, int level, int nums) int newlevel = getSizeLevel(newIndex); // update corners - if (n==0 || newIndex != index) { + if (indices.empty() || newIndex != index) { index = newIndex; level = newlevel; @@ -3138,7 +3144,7 @@ BackgroundMesh::interpolate(Particle* pt, const VVInt& index, if (fixed.size() != 8) return 0; } - VDouble pcrds = pt->getCrds(); + const VDouble& pcrds = pt->getCrds(); if ((int)pcrds.size() != ndm) { opserr << "WARNING: pcrds.size() != ndm -- BgMesh::interpolate\n"; return -1; @@ -3158,52 +3164,6 @@ BackgroundMesh::interpolate(Particle* pt, const VVInt& index, hx,hy,hz,pcrds[0],pcrds[1],pcrds[2],N); } - // get structural coordinates - VVDouble scoords, scoordsn; - for (int j=0; j<(int)fixed.size(); ++j) { - if (fixed[j] == 1) { - BNode& bnode = bnodes[index[j]]; - for (int i = 0; i < (int) ndtags[j].size(); ++i) { - Node* snode = domain->getNode(ndtags[j][i]); - if (snode != 0) { - VDouble curr(ndm); - const Vector& scrds = snode->getCrds(); - const Vector& sdisp = snode->getTrialDisp(); - for (int k = 0; k < ndm; ++k) { - curr[k] = scrds(k) + sdisp(k); - } - scoords.push_back(curr); - scoordsn.push_back(bnode.crdsn[i]); - } - } - } - } - - // get walls - VVInt walls; - if (ndm == 2) { - for (int i = 0; i < (int) scoords.size(); ++i) { - for (int k = i + 1; k < (int) scoords.size(); ++k) { - VInt boundary(2); - boundary[0] = i; - boundary[1] = k; - walls.push_back(boundary); - } - } - } else if (ndm == 3) { - for (int i = 0; i < (int) scoords.size(); ++i) { - for (int m = i + 1; m < (int) scoords.size(); ++m) { - for (int k = m + 1; k < (int) scoords.size(); ++k) { - VInt boundary(3); - boundary[0] = i; - boundary[1] = m; - boundary[2] = k; - walls.push_back(boundary); - } - } - } - } - // particle velocity VDouble pvel(ndm); VDouble pdvn(ndm), incrpvel(ndm); @@ -3249,80 +3209,48 @@ BackgroundMesh::interpolate(Particle* pt, const VVInt& index, } // particle displacement - VDouble newpdisp = pvel; - newpdisp *= dt; - for (int k = 0; k < (int)walls.size(); ++k) { - - // get current wall - VDouble boundir; - double dist; - VDouble xbnd(ndm), ybnd(ndm), zbnd(ndm); - for (int l = 0; l < ndm; ++l) { - xbnd[l] = scoords[walls[k][l]][0]; - ybnd[l] = scoords[walls[k][l]][1]; - if (ndm == 3) { - zbnd[l] = scoords[walls[k][l]][2]; - } - } - getWall(boundir, dist, xbnd, ybnd, zbnd, pcrds); - - // get previous wall - VDouble boundirn; - double distn; - for (int l = 0; l < ndm; ++l) { - xbnd[l] = scoordsn[walls[k][l]][0]; - ybnd[l] = scoordsn[walls[k][l]][1]; - if (ndm == 3) { - zbnd[l] = scoordsn[walls[k][l]][2]; + // cannot travel more than one cell + VDouble newpcrds; + bool travel_cell = false; + while (newpcrds.empty() || travel_cell) { + newpcrds = pvel; + newpcrds *= dt; + travel_cell = false; + for (int i = 0; i < ndm; ++i) { + if (newpcrds[i] > bsize) { + travel_cell = true; + dt *= 0.5; + break; } } - getWall(boundirn, distn, xbnd, ybnd, zbnd, pcrds); - - // check if particle is between the two walls - if (dotVDouble(boundir, boundirn) < 0) { - - VDouble temp = boundir; - temp *= dist; - - pt->move(temp, 0.0); - - temp = boundir; - temp *= distn; - - pt->move(temp, 0.0); - - boundir *= -1.0; - dist = distn; - - pcrds = pt->getCrds(); - } - - // check if particle is moving toward the current wall - if (dotVDouble(pvel, boundir) > 0) { - - // vertical - VDouble vdisp = boundir, vvel = boundir; - double newdist = dotVDouble(newpdisp, boundir); - double newvel = dotVDouble(pvel, boundir); -// double vmag = normVDouble(pvel); - vdisp *= newdist; - vvel *= newvel; - - double percent = dist / bsize * boundReduceFactor; + } - // horizontal disp - newpdisp -= vdisp; - pvel -= vvel; + // new particle coordinates + newpcrds += pcrds; - // new vertical disp - vdisp *= percent; - vvel *= percent; + // find new cell + VInt newindex; + lowerIndex(newpcrds, newindex); + auto it = bnodes.find(newindex); - // new disp - newpdisp += vdisp; - pvel += vvel; -// pvel /= normVDouble(pvel); -// pvel *= vmag; + // if new cell is structure + if (it != bnodes.end()) { + if (it->second.type == STRUCTURE) { + // check each direction + for (int i = 0; i < ndm; ++i) { + int diff = newindex[i] - index[0][i]; + if (diff == 0) continue; + double out_disp = 0.0; + if (diff > 0) { + out_disp = newpcrds[i] - crds[0][i] - bsize; + newpcrds[i] = crds[0][i] + bsize - out_disp; + pvel[i] = -pvel[i]; + } else { + out_disp = crds[0][i] - newpcrds[i]; + newpcrds[i] = crds[0][i] + out_disp; + pvel[i] = -pvel[i]; + } + } } } @@ -3339,7 +3267,7 @@ BackgroundMesh::interpolate(Particle* pt, const VVInt& index, } // original->dest - pt->move(newpdisp, dt); + pt->moveTo(newpcrds, dt); return 0; } @@ -3497,31 +3425,31 @@ BackgroundMesh::createContact(const VInt& ndtags, const VInt& sids, VInt& elends return 1; } - // get slave node - int slave = 0; + // get secondary node + int secondary = 0; int id = 0; bool find = false; for (std::map::iterator it=grp.begin(); it!=grp.end(); ++it) { VInt& nds = it->second; if (nds.size() == 1) { - // slave node with largest sid + // secondary node with largest sid if (!find || (id < it->first)) { id = it->first; - slave = nds[0]; + secondary = nds[0]; find = true; } } else if (find && id < it->first) { - // if master nodes have larger sid + // if primary nodes have larger sid find = false; } } if (!find) return 1; - // index for slave node + // index for secondary node int index = 0; for (int i = 0; i < (int) ndtags.size(); ++i) { - if (ndtags[i] == slave) { + if (ndtags[i] == secondary) { index = i + 1; if (index >= (int) ndtags.size()) { index -= ndtags.size(); @@ -3530,7 +3458,7 @@ BackgroundMesh::createContact(const VInt& ndtags, const VInt& sids, VInt& elends } } - // get master nodes + // get primary nodes elends.clear(); for (int i = 0; i < (int) ndtags.size() - 1; ++i) { elends.push_back(ndtags[index]); @@ -3539,7 +3467,7 @@ BackgroundMesh::createContact(const VInt& ndtags, const VInt& sids, VInt& elends index -= ndtags.size(); } } - elends.push_back(slave); + elends.push_back(secondary); return 0; } @@ -3591,4 +3519,4 @@ BackgroundMesh::getWall(VDouble& dir, double& dist, const VDouble& xbnd, dist += dir[m] * pcrds[m]; } dist = fabs(dist); -} \ No newline at end of file +} diff --git a/SRC/element/PFEMElement/PFEMElement3DBubble.cpp b/SRC/element/PFEMElement/PFEMElement3DBubble.cpp index f1a406c0bc..fe47a43f3c 100644 --- a/SRC/element/PFEMElement/PFEMElement3DBubble.cpp +++ b/SRC/element/PFEMElement/PFEMElement3DBubble.cpp @@ -295,17 +295,17 @@ int PFEMElement3DBubble::updateMatrix() for(int b=0; b<(int)thePCs.size(); ++b) { // Gt - M(numDOFs(2*a+1), numDOFs(2*b)) = G(3*b,a); // GxT - M(numDOFs(2*a+1), numDOFs(2*b)+1) = G(3*b+1,a); // GyT - M(numDOFs(2*a+1), numDOFs(2*b)+2) = G(3*b+2,a); // GzT + D(numDOFs(2*a+1), numDOFs(2*b)) = G(3*b,a); // GxT + D(numDOFs(2*a+1), numDOFs(2*b)+1) = G(3*b+1,a); // GyT + D(numDOFs(2*a+1), numDOFs(2*b)+2) = G(3*b+2,a); // GzT // G - M(numDOFs(2*a), numDOFs(2*b+1)) = -G(3*a,b); // -Gx - M(numDOFs(2*a)+1, numDOFs(2*b+1)) = -G(3*a+1,b); // -Gy - M(numDOFs(2*a)+2, numDOFs(2*b+1)) = -G(3*a+2,b); // -Gz + D(numDOFs(2*a), numDOFs(2*b+1)) = -G(3*a,b); // -Gx + D(numDOFs(2*a)+1, numDOFs(2*b+1)) = -G(3*a+1,b); // -Gy + D(numDOFs(2*a)+2, numDOFs(2*b+1)) = -G(3*a+2,b); // -Gz // L - M(numDOFs(2*a+1), numDOFs(2*b+1)) = L(a,b); // bubble + D(numDOFs(2*a+1), numDOFs(2*b+1)) = L(a,b); // bubble } } diff --git a/SRC/element/PFEMElement/ParticleGroup.cpp b/SRC/element/PFEMElement/ParticleGroup.cpp index 73089db066..1629a37d6f 100644 --- a/SRC/element/PFEMElement/ParticleGroup.cpp +++ b/SRC/element/PFEMElement/ParticleGroup.cpp @@ -199,7 +199,7 @@ int OPS_ParticleGroup() { } } else if (strcmp(geotype, "pointlist") == 0) { int numdata = OPS_GetNumRemainingInputArgs(); - if (numdata < ndm) { + if (numdata < 1) { group->pointlist(pointdata); numdata = (int) pointdata.size(); if (OPS_SetDoubleOutput(&numdata, &pointdata[0], false) < 0) { @@ -209,6 +209,23 @@ int OPS_ParticleGroup() { return 0; } + // number of points + int num_point = 0; + numdata = 1; + if (OPS_GetIntInput(&numdata, &num_point) < 0) { + opserr << "WARNING: failed to get number of points\n"; + return -1; + } + + // check input + numdata = num_point * (4 * ndm + 1); + if (OPS_GetNumRemainingInputArgs() < numdata) { + opserr << "WARNING: insufficient input for " + << num_point << " points: [x1n, y1, , x1, y1, " + << "vx1, vy1, , ax1, ay1, , p1, x2n, ...]\n"; + return -1; + } + // node coord pointdata.resize(numdata); if (OPS_GetDoubleInput(&numdata, &pointdata[0]) < 0) { diff --git a/SRC/element/TclElementCommands.cpp b/SRC/element/TclElementCommands.cpp index ba260ce982..8ba1183a09 100644 --- a/SRC/element/TclElementCommands.cpp +++ b/SRC/element/TclElementCommands.cpp @@ -124,11 +124,16 @@ extern void *OPS_ShellDKGQ(void); //Added by Lisha Wang, Xinzheng Lu, Linlin extern void *OPS_ShellNLDKGQ(void); //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu extern void *OPS_ShellDKGT(void); //Added by Shuhao Zhang and Xinzheng Lu extern void *OPS_ShellNLDKGT(void); //Added by Shuhao Zhang and Xinzheng Lu +extern void *OPS_ASDShellQ4(void); // Massimo Petracca (ASDEA) extern void *OPS_Quad4FiberOverlay(void); extern void *OPS_Brick8FiberOverlay(void); extern void *OPS_QuadBeamEmbedContact(void); extern void *OPS_TripleFrictionPendulum(void); extern void *OPS_Truss2(void); +#ifdef _HAVE_PML +extern void *OPS_PML3D(void); +extern void *OPS_PML2D(void); +#endif extern void *OPS_CorotTruss2(void); extern void *OPS_ZeroLengthImpact3D(void); extern void *OPS_HDR(void); @@ -213,6 +218,18 @@ extern int TclModelBuilder_addNineNodeMixedQuad(ClientData, Tcl_Interp *, int, TCL_Char **, Domain*, TclModelBuilder *); +extern int +TclModelBuilder_addNineNodeQuad(ClientData, Tcl_Interp *, int, TCL_Char **, + Domain*, TclModelBuilder *); + +extern int +TclModelBuilder_addEightNodeQuad(ClientData, Tcl_Interp *, int, TCL_Char **, + Domain*, TclModelBuilder *); + +extern int +TclModelBuilder_addSixNodeTri(ClientData, Tcl_Interp *, int, TCL_Char **, + Domain*, TclModelBuilder *); + // GLF extern int @@ -486,9 +503,25 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, return TCL_ERROR; } - } +#ifdef _HAVE_PML + } else if ((strcmp(argv[1],"PML") == 0) || (strcmp(argv[1],"pml")) == 0) { + Element *theEle = 0; + ID info; + if (OPS_GetNDM() == 2) + theEle = (Element *)OPS_PML2D(); + else + theEle = (Element *)OPS_PML3D(); + if (theEle != 0) + theElement = theEle; + else { + opserr << "TclElementCommand -- unable to create element of type : " << argv[1] << endln; + return TCL_ERROR; + } + +#endif + + /* } else if (strcmp(argv[1], "gradientInelasticBeamColumn") == 0) { - /*else if (strcmp(argv[1], "gradientInelasticBeamColumn") == 0) { Element *theEle = 0; if (OPS_GetNDM() == 2) theEle = (Element *)OPS_GradientInelasticBeamColumn2d(); @@ -503,8 +536,8 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, } }*/ - #ifdef _HAVE_LHNMYS - else if (strcmp(argv[1],"beamColumn2DwLHNMYS") == 0) { +#ifdef _HAVE_LHNMYS + } else if (strcmp(argv[1],"beamColumn2DwLHNMYS") == 0) { Element *theEle = 0; ID info; theEle = (Element *)OPS_BeamColumn2DwLHNMYS(); @@ -514,8 +547,8 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, opserr << "TclElementCommand -- unable to create element of type : " << argv[1] << endln; return TCL_ERROR; } - } - else if (strcmp(argv[1],"beamColumn3DwLHNMYS") == 0) { + + } else if (strcmp(argv[1],"beamColumn3DwLHNMYS") == 0) { Element *theEle = 0; ID info; theEle = (Element *)OPS_BeamColumn3DwLHNMYS(); @@ -525,21 +558,21 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, opserr << "TclElementCommand -- unable to create element of type : " << argv[1] << endln; return TCL_ERROR; } - } - #endif + +#endif // Beginning of WheelRail element TCL command //Added by Quan Gu and Yongdou Liu, et al. on 2018/10/31 - else if((strcmp(argv[1], "WheelRail") == 0)) { - // ------------------------------add------------------------------------------ - int eleArgStart = 1; - int result = TclModelBuilder_addWheelRail(clientData, interp, argc, argv, - theTclDomain, theTclBuilder, eleArgStart); - return result; - -}//End of WheelRail element TCL command*/ + } else if((strcmp(argv[1], "WheelRail") == 0)) { + // ------------------------------add------------------------------------------ + int eleArgStart = 1; + int result = TclModelBuilder_addWheelRail(clientData, interp, argc, argv, + theTclDomain, theTclBuilder, eleArgStart); + return result; + + //End of WheelRail element TCL command*/ - else if ((strcmp(argv[1],"ElasticTimoshenkoBeam") == 0) || (strcmp(argv[1],"elasticTimoshenkoBeam")) == 0) { + } else if ((strcmp(argv[1],"ElasticTimoshenkoBeam") == 0) || (strcmp(argv[1],"elasticTimoshenkoBeam")) == 0) { Element *theEle = 0; if (OPS_GetNDM() == 2) theEle = (Element *)OPS_ElasticTimoshenkoBeam2d(); @@ -808,6 +841,15 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, return TCL_ERROR; } + } else if (strcmp(argv[1],"ASDShellQ4") == 0) { + + void *theEle = OPS_ASDShellQ4(); + if (theEle != 0) + theElement = (Element *)theEle; + else { + opserr << "TclElementCommand -- unable to create element of type : " << argv[1] << endln; + return TCL_ERROR; + } } else if ((strcmp(argv[1],"CoupledZeroLength") == 0) || (strcmp(argv[1],"ZeroLengthCoupled") == 0)) { @@ -1417,6 +1459,18 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, theTclDomain, theTclBuilder); return result; + } else if (strcmp(argv[1],"quad9n") == 0) { + int result = TclModelBuilder_addNineNodeQuad(clientData, interp, argc, argv, + theTclDomain, theTclBuilder); + return result; + } else if (strcmp(argv[1],"quad8n") == 0) { + int result = TclModelBuilder_addEightNodeQuad(clientData, interp, argc, argv, + theTclDomain, theTclBuilder); + return result; + } else if (strcmp(argv[1],"tri6n") == 0) { + int result = TclModelBuilder_addSixNodeTri(clientData, interp, argc, argv, + theTclDomain, theTclBuilder); + return result; } else if (strcmp(argv[1],"quadUP") == 0) { int result = TclModelBuilder_addFourNodeQuadUP(clientData, interp, argc, argv, theTclDomain, theTclBuilder); diff --git a/SRC/element/UWelements/BeamContact2D.cpp b/SRC/element/UWelements/BeamContact2D.cpp index 7f0a4aaee3..3c09e0cd88 100644 --- a/SRC/element/UWelements/BeamContact2D.cpp +++ b/SRC/element/UWelements/BeamContact2D.cpp @@ -62,7 +62,7 @@ OPS_BeamContact2D(void) int numRemainingInputArgs = OPS_GetNumRemainingInputArgs(); if (numRemainingInputArgs < 9) { - opserr << "Invalid #args, want: element BeamContact2D eleTag? iNode? jNode? slaveNode? lambdaNode? matTag? width? gapTol? forceTol? ?\n"; + opserr << "Invalid #args, want: element BeamContact2D eleTag? iNode? jNode? secondaryNode? lambdaNode? matTag? width? gapTol? forceTol? ?\n"; return 0; } @@ -282,7 +282,7 @@ BeamContact2D::setDomain(Domain *theDomain) ma_1 = (mDcrd_b - mDcrd_a)/mLength; mb_1 = ma_1; - // perform projection of slave node to beam centerline + // perform projection of secondary node to beam centerline mXi = ((mDcrd_b - mDcrd_s)^(mDcrd_b - mDcrd_a))/mLength; // initial assumption mXi = Project(mXi); // actual location @@ -398,7 +398,7 @@ BeamContact2D::update(void) double rot_b; Vector x_c(BC2D_NUM_DIM); - // update slave node coordinates + // update secondary node coordinates mDcrd_s = mIcrd_s + theNodes[2]->getTrialDisp(); // update Lagrange multiplier value @@ -998,7 +998,7 @@ Response* BeamContact2D::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) { if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) { - // forces on slave node + // forces on secondary node return new ElementResponse(this, 1, Vector(2)); } else if (strcmp(argv[0],"frictionforce") == 0 || strcmp(argv[0],"frictionforces") == 0) { @@ -1009,8 +1009,9 @@ BeamContact2D::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) // scalar contact forces return new ElementResponse(this, 3, Vector(2)); - } else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0) { - // reactions (forces and moments) on master nodes + } else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0 || + strcmp(argv[0],"primaryforce") == 0 || strcmp(argv[0],"primaryforces") == 0) { + // reactions (forces and moments) on primary nodes return new ElementResponse(this, 4, Vector(6)); } else { @@ -1027,18 +1028,18 @@ BeamContact2D::getResponse(int responseID, Information &eleInfo) // initialize variables Vector force(2); Vector frictForce(2); - Vector slaveForce(2); - Vector masterForce(6); + Vector secondaryForce(2); + Vector primaryForce(6); // get contact "stress" vector Vector stress = theMaterial->getStress(); if (responseID == 1) { - // forces on slave node - slaveForce(0) = -mInternalForces(6); - slaveForce(1) = -mInternalForces(7); - return eleInfo.setVector(slaveForce); + // forces on secondary node + secondaryForce(0) = -mInternalForces(6); + secondaryForce(1) = -mInternalForces(7); + return eleInfo.setVector(secondaryForce); } else if (responseID == 2) { @@ -1055,13 +1056,13 @@ BeamContact2D::getResponse(int responseID, Information &eleInfo) } else if (responseID == 4) { - // reactions (forces and moments) on master nodes + // reactions (forces and moments) on primary nodes for (int i = 0; i < 3; i++) { - masterForce(i) = -mInternalForces(i); - masterForce(i+3) = -mInternalForces(i+3); + primaryForce(i) = -mInternalForces(i); + primaryForce(i+3) = -mInternalForces(i+3); } - return eleInfo.setVector(masterForce); + return eleInfo.setVector(primaryForce); } else // otherwise response quantity is unknown for the BeamContact2D class diff --git a/SRC/element/UWelements/BeamContact2D.h b/SRC/element/UWelements/BeamContact2D.h index 8e544c197d..23e2e9899f 100644 --- a/SRC/element/UWelements/BeamContact2D.h +++ b/SRC/element/UWelements/BeamContact2D.h @@ -150,10 +150,10 @@ class BeamContact2D : public Element Vector mIcrd_a; // initial coordinates of node a Vector mIcrd_b; // initial coordinates of node a - Vector mIcrd_s; // initial coordinates of slave node + Vector mIcrd_s; // initial coordinates of secondary node Vector mDcrd_a; // initial coordinates of node a Vector mDcrd_b; // initial coordinates of node a - Vector mDcrd_s; // initial coordinates of slave node + Vector mDcrd_s; // initial coordinates of secondary node Vector mDisp_a_n; // total disp & rotation of node a @ step n Vector mDisp_b_n; // total disp & rotation of node b @ step n }; diff --git a/SRC/element/UWelements/BeamContact2Dp.cpp b/SRC/element/UWelements/BeamContact2Dp.cpp index e598fcfd29..08dd346146 100644 --- a/SRC/element/UWelements/BeamContact2Dp.cpp +++ b/SRC/element/UWelements/BeamContact2Dp.cpp @@ -62,7 +62,7 @@ OPS_BeamContact2Dp(void) int numRemainingInputArgs = OPS_GetNumRemainingInputArgs(); if (numRemainingInputArgs < 7) { - opserr << "Invalid #args, want: element BeamContact2Dp eleTag? iNode? jNode? slaveNode? matTag? width? penalty? ?\n"; + opserr << "Invalid #args, want: element BeamContact2Dp eleTag? iNode? jNode? secondaryNode? matTag? width? penalty? ?\n"; return 0; } @@ -275,7 +275,7 @@ BeamContact2Dp::setDomain(Domain *theDomain) ma_1 = (mDcrd_b - mDcrd_a)/mLength; mb_1 = ma_1; - // perform projection of slave node to beam centerline + // perform projection of secondary node to beam centerline mXi = ((mDcrd_b - mDcrd_s)^(mDcrd_b - mDcrd_a))/mLength; // initial assumption mXi = Project(mXi); // actual location @@ -387,7 +387,7 @@ BeamContact2Dp::update(void) double rot_b; Vector x_c(BC2Dp_NUM_DIM); - // update slave node coordinates + // update secondary node coordinates mDcrd_s = mIcrd_s + theNodes[2]->getTrialDisp(); // update nodal coordinates @@ -972,7 +972,7 @@ Response* BeamContact2Dp::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) { if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) { - // forces on slave node + // forces on secondary node return new ElementResponse(this, 1, Vector(2)); } else if (strcmp(argv[0],"frictionforce") == 0 || strcmp(argv[0],"frictionforces") == 0) { @@ -983,8 +983,9 @@ BeamContact2Dp::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) // scalar contact forces return new ElementResponse(this, 3, Vector(2)); - } else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0) { - // reactions (forces and moments) on master nodes + } else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0 || + strcmp(argv[0],"primaryforce") == 0 || strcmp(argv[0],"primaryforces") == 0) { + // reactions (forces and moments) on primary nodes return new ElementResponse(this, 4, Vector(6)); } else if (strcmp(argv[0],"gap") == 0) { @@ -1005,8 +1006,8 @@ BeamContact2Dp::getResponse(int responseID, Information &eleInfo) // initialize variables Vector force(2); Vector frictForce(2); - Vector slaveForce(2); - Vector masterForce(6); + Vector secondaryForce(2); + Vector primaryForce(6); Vector theGap(1); // get contact "stress" vector @@ -1014,10 +1015,10 @@ BeamContact2Dp::getResponse(int responseID, Information &eleInfo) if (responseID == 1) { - // forces on slave node - slaveForce(0) = -mInternalForces(6); - slaveForce(1) = -mInternalForces(7); - return eleInfo.setVector(slaveForce); + // forces on secondar node + secondaryForce(0) = -mInternalForces(6); + secondaryForce(1) = -mInternalForces(7); + return eleInfo.setVector(secondaryForce); } else if (responseID == 2) { @@ -1034,13 +1035,13 @@ BeamContact2Dp::getResponse(int responseID, Information &eleInfo) } else if (responseID == 4) { - // reactions (forces and moments) on master nodes + // reactions (forces and moments) on primary nodes for (int i = 0; i < 3; i++) { - masterForce(i) = -mInternalForces(i); - masterForce(i+3) = -mInternalForces(i+3); + primaryForce(i) = -mInternalForces(i); + primaryForce(i+3) = -mInternalForces(i+3); } - return eleInfo.setVector(masterForce); + return eleInfo.setVector(primaryForce); } else if (responseID == 5) { theGap(0) = mGap; diff --git a/SRC/element/UWelements/BeamContact2Dp.h b/SRC/element/UWelements/BeamContact2Dp.h index df97bd9a18..15e9d48f55 100644 --- a/SRC/element/UWelements/BeamContact2Dp.h +++ b/SRC/element/UWelements/BeamContact2Dp.h @@ -146,10 +146,10 @@ class BeamContact2Dp : public Element Vector mIcrd_a; // initial coordinates of node a Vector mIcrd_b; // initial coordinates of node a - Vector mIcrd_s; // initial coordinates of slave node + Vector mIcrd_s; // initial coordinates of secondary node Vector mDcrd_a; // initial coordinates of node a Vector mDcrd_b; // initial coordinates of node a - Vector mDcrd_s; // initial coordinates of slave node + Vector mDcrd_s; // initial coordinates of secondary node Vector mDisp_a_n; // total disp & rotation of node a @ step n Vector mDisp_b_n; // total disp & rotation of node b @ step n }; diff --git a/SRC/element/UWelements/BeamContact3D.cpp b/SRC/element/UWelements/BeamContact3D.cpp index 035e9879bd..ea0c63d10f 100644 --- a/SRC/element/UWelements/BeamContact3D.cpp +++ b/SRC/element/UWelements/BeamContact3D.cpp @@ -71,7 +71,7 @@ OPS_BeamContact3D(void) int numRemainingInputArgs = OPS_GetNumRemainingInputArgs(); if (numRemainingInputArgs < 10) { - opserr << "Invalid #args, want: element BeamContact3D eleTag? iNode? jNode? slaveNode? lambdaNode? radius? crdTransf? matTag? tolGap? tolF? ?\n"; + opserr << "Invalid #args, want: element BeamContact3D eleTag? iNode? jNode? secondaryNode? lambdaNode? radius? crdTransf? matTag? tolGap? tolF? ?\n"; return 0; } @@ -408,11 +408,11 @@ BeamContact3D::setDomain(Domain *theDomain) mQb = mQa; mchi = 0; - // length of master segment L + // length of primary segment L mL = (mDcrd_b - mDcrd_a).Norm(); // perform projection to update local coordinate along centerline - // of master segment. projection function also sets mn, mc1 + // of primary segment. projection function also sets mn, mc1 mxi = ((mDcrd_b - mDcrd_s)^(mDcrd_b - mDcrd_a)) / ((mDcrd_b - mDcrd_a)^(mDcrd_b - mDcrd_a)) ; // initial approx // initial basis function values for use in projection mxi = project(mxi); @@ -597,7 +597,7 @@ BeamContact3D::update(void) Vector x_c(BC3D_NUM_NDM); Vector d(BC3D_NUM_NDM); - // update slave node coordinate + // update secondary node coordinate mDcrd_s = mIcrd_s + theNodes[2]->getTrialDisp(); // update Lagrange Multiplier Value @@ -730,7 +730,7 @@ BeamContact3D::project(double xi) Vector a1(BC3D_NUM_NDM); // tangent at end a Vector b1(BC3D_NUM_NDM); // tangent at end b Vector x_c_P(BC3D_NUM_NDM); // current centerline porjection coordinate - Vector d(BC3D_NUM_NDM); // distance from slave node to centerline coord + Vector d(BC3D_NUM_NDM); // distance from secondary node to centerline coord Vector tc(BC3D_NUM_NDM); // tangent at projection point = 1st deriv of x_c Vector ddx_c(BC3D_NUM_NDM); // 2nd derivative of x_c @@ -2097,13 +2097,16 @@ BeamContact3D::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) else if (strcmp(argv[0],"forcescalar") == 0 || strcmp(argv[0],"forcescalars") == 0) return new ElementResponse(this, 3, Vector(3)); - else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0) + else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0 || + strcmp(argv[0],"primaryforce") == 0 || strcmp(argv[0],"primaryforces") == 0) return new ElementResponse(this, 4, Vector(6)); - else if (strcmp(argv[0],"mastermoment") == 0 || strcmp(argv[0],"mastermoments") == 0) + else if (strcmp(argv[0],"mastermoment") == 0 || strcmp(argv[0],"mastermoments") == 0 || + strcmp(argv[0],"primarymoment") == 0 || strcmp(argv[0],"primarymoments") == 0) return new ElementResponse(this, 5, Vector(6)); - else if (strcmp(argv[0],"masterreaction") == 0 || strcmp(argv[0],"masterreactions") == 0) + else if (strcmp(argv[0],"masterreaction") == 0 || strcmp(argv[0],"masterreactions") == 0 || + strcmp(argv[0],"primaryreaction") == 0 || strcmp(argv[0],"primaryreactions") == 0) return new ElementResponse(this, 6, Vector(12)); else if (strcmp(argv[0],"slip") == 0) @@ -2136,7 +2139,7 @@ BeamContact3D::getResponse(int responseID, Information &eleInfo) // force = stress(0)*mn + stress(1)*mg1 + stress(2)*mg2; - // forces on slave node + // forces on secondary node for (int ii=0; ii<3; ii++) { sForce(ii) = -mInternalForces(BC3D_NUM_DOF - 6 + ii); /* @@ -2170,7 +2173,7 @@ BeamContact3D::getResponse(int responseID, Information &eleInfo) } else if (responseID == 4) { - // forces on master nodes + // forces on primary nodes for (int ii=0; ii<3; ii++) { mForces(ii) = -mInternalForces(ii); mForces(ii+3) = -mInternalForces(ii+6); @@ -2180,7 +2183,7 @@ BeamContact3D::getResponse(int responseID, Information &eleInfo) } else if (responseID == 5) { - // moments on master nodes + // moments on primary nodes for (int ii=0; ii<3; ii++) { mMoments(ii) = -mInternalForces(ii+3); mMoments(ii+3) = -mInternalForces(ii+9); @@ -2190,7 +2193,7 @@ BeamContact3D::getResponse(int responseID, Information &eleInfo) } else if (responseID == 6) { - // full reactions on master nodes + // full reactions on primary nodes for (int ii=0; ii<6; ii++) { mReactions(ii) = -mInternalForces(ii); mReactions(ii+6) = -mInternalForces(ii+6); diff --git a/SRC/element/UWelements/BeamContact3Dp.cpp b/SRC/element/UWelements/BeamContact3Dp.cpp index 219026ca6f..c9f54c9ed6 100644 --- a/SRC/element/UWelements/BeamContact3Dp.cpp +++ b/SRC/element/UWelements/BeamContact3Dp.cpp @@ -62,7 +62,7 @@ OPS_BeamContact3Dp(void) int numRemainingInputArgs = OPS_GetNumRemainingInputArgs(); if (numRemainingInputArgs < 8) { - opserr << "Invalid #args, want: element BeamContact3Dp eleTag? iNode? jNode? slaveNode? radius? crdTransf? matTag? penalty? ?\n"; + opserr << "Invalid #args, want: element BeamContact3Dp eleTag? iNode? jNode? secondaryNode? radius? crdTransf? matTag? penalty? ?\n"; return 0; } @@ -351,10 +351,10 @@ BeamContact3Dp::setDomain(Domain *theDomain) mQb = mQa; mchi = 0; - // length of master segment L + // length of primary segment L mL = (mDcrd_b - mDcrd_a).Norm(); - // perform projection to update local coordinate along centerline of master segment + // perform projection to update local coordinate along centerline of primary segment mxi = ((mDcrd_b - mDcrd_s)^(mDcrd_b - mDcrd_a)) / ((mDcrd_b - mDcrd_a)^(mDcrd_b - mDcrd_a)) ; // initial approx // adjust cohesion force @@ -468,7 +468,7 @@ BeamContact3Dp::update(void) Vector x_c(BC3Dp_NUM_NDM); Vector d(BC3Dp_NUM_NDM); - // update slave node coordinate + // update secondary node coordinate mDcrd_s = mIcrd_s + theNodes[2]->getTrialDisp(); // update nodes a, b coordinates & rotations @@ -595,7 +595,7 @@ BeamContact3Dp::project(double xi) Vector a1(BC3Dp_NUM_NDM); // tangent at end a Vector b1(BC3Dp_NUM_NDM); // tangent at end b Vector x_c_P(BC3Dp_NUM_NDM); // current centerline porjection coordinate - Vector d(BC3Dp_NUM_NDM); // distance from slave node to centerline coord + Vector d(BC3Dp_NUM_NDM); // distance from secondary node to centerline coord Vector tc(BC3Dp_NUM_NDM); // tangent at projection point = 1st deriv of x_c Vector ddx_c(BC3Dp_NUM_NDM); // 2nd derivative of x_c @@ -1722,13 +1722,16 @@ BeamContact3Dp::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) } else if (strcmp(argv[0],"forcescalar") == 0 || strcmp(argv[0],"forcescalars") == 0) { return new ElementResponse(this, 3, Vector(3)); - } else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0) { + } else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0 || + strcmp(argv[0],"primaryforce") == 0 || strcmp(argv[0],"primaryforces") == 0) { return new ElementResponse(this, 4, Vector(6)); - } else if (strcmp(argv[0],"mastermoment") == 0 || strcmp(argv[0],"mastermoments") == 0) { + } else if (strcmp(argv[0],"mastermoment") == 0 || strcmp(argv[0],"mastermoments") == 0 || + strcmp(argv[0],"primarymoment") == 0 || strcmp(argv[0],"primarymoments") == 0) { return new ElementResponse(this, 5, Vector(6)); - } else if (strcmp(argv[0],"masterreaction") == 0 || strcmp(argv[0],"masterreactions") == 0) { + } else if (strcmp(argv[0],"masterreaction") == 0 || strcmp(argv[0],"masterreactions") == 0 || + strcmp(argv[0],"primaryreaction") == 0 || strcmp(argv[0],"primaryreactions") == 0) { return new ElementResponse(this, 6, Vector(12)); } else if (strcmp(argv[0],"slip") == 0) { @@ -1756,7 +1759,7 @@ BeamContact3Dp::getResponse(int responseID, Information &eleInfo) if (responseID == 1) { - // forces on slave node + // forces on secondary node for (int ii=0; ii<3; ii++) { sForce(ii) = -mInternalForces(BC3Dp_NUM_DOF - 6 + ii); } @@ -1776,7 +1779,7 @@ BeamContact3Dp::getResponse(int responseID, Information &eleInfo) } else if (responseID == 4) { - // forces on master nodes + // forces on primary nodes for (int ii=0; ii<3; ii++) { mForces(ii) = -mInternalForces(ii); mForces(ii+3) = -mInternalForces(ii+6); @@ -1785,7 +1788,7 @@ BeamContact3Dp::getResponse(int responseID, Information &eleInfo) } else if (responseID == 5) { - // moments on master nodes + // moments on primary nodes for (int ii=0; ii<3; ii++) { mMoments(ii) = -mInternalForces(ii+3); mMoments(ii+3) = -mInternalForces(ii+9); @@ -1794,7 +1797,7 @@ BeamContact3Dp::getResponse(int responseID, Information &eleInfo) } else if (responseID == 6) { - // full reactions on master nodes + // full reactions on primary nodes for (int ii=0; ii<6; ii++) { mReactions(ii) = -mInternalForces(ii); mReactions(ii+6) = -mInternalForces(ii+6); diff --git a/SRC/element/UWelements/BeamEndContact3D.cpp b/SRC/element/UWelements/BeamEndContact3D.cpp index 5169f412c7..95003bcfd1 100644 --- a/SRC/element/UWelements/BeamEndContact3D.cpp +++ b/SRC/element/UWelements/BeamEndContact3D.cpp @@ -60,7 +60,7 @@ OPS_BeamEndContact3D(void) int numRemainingInputArgs = OPS_GetNumRemainingInputArgs(); if (numRemainingInputArgs < 8) { - opserr << "Invalid #args, want: element BeamEndContact3D eleTag? iNode? jNode? slaveNode? lambdaNode? radius? gapTol? forceTol ?\n"; + opserr << "Invalid #args, want: element BeamEndContact3D eleTag? iNode? jNode? secondaryNode? lambdaNode? radius? gapTol? forceTol ?\n"; return 0; } @@ -295,7 +295,7 @@ BeamEndContact3D::update(void) rot_a(i) = disp_a(i+3); } - // update slave node coordinates + // update secondary node coordinates mDcrd_s = mIcrd_s + theNodes[1]->getTrialDisp(); // update Lagrange multiplier value @@ -567,11 +567,12 @@ Response* BeamEndContact3D::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) { if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) { - // forces on slave node + // forces on secondary node return new ElementResponse(this, 1, Vector(3)); - } else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0) { - // reactions (forces and moments) on master node + } else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0 || + strcmp(argv[0],"primaryforce") == 0 || strcmp(argv[0],"primaryforces") == 0) { + // reactions (forces and moments) on primary node return new ElementResponse(this, 2, Vector(6)); } else { @@ -586,26 +587,26 @@ int BeamEndContact3D::getResponse(int responseID, Information &eleInfo) { // initialize variables - Vector slaveForce(3); - Vector masterForce(6); + Vector secondaryForce(3); + Vector primaryForce(6); if (responseID == 1) { - // forces on slave node - slaveForce(0) = -mInternalForces(6); - slaveForce(1) = -mInternalForces(7); - slaveForce(2) = -mInternalForces(8); - return eleInfo.setVector(slaveForce); + // forces on secondary node + secondaryForce(0) = -mInternalForces(6); + secondaryForce(1) = -mInternalForces(7); + secondaryForce(2) = -mInternalForces(8); + return eleInfo.setVector(secondaryForce); } else if (responseID == 2) { - // reactions (forces and moments) on master node + // reactions (forces and moments) on primary node for (int i = 0; i < 3; i++) { - masterForce(i) = -mInternalForces(i); - masterForce(i+3) = -mInternalForces(i+3); + primaryForce(i) = -mInternalForces(i); + primaryForce(i+3) = -mInternalForces(i+3); } - return eleInfo.setVector(masterForce); + return eleInfo.setVector(primaryForce); } else { // otherwise response quantity is unknown for the BeamEndContact3D class diff --git a/SRC/element/UWelements/BeamEndContact3D.h b/SRC/element/UWelements/BeamEndContact3D.h index 1bf68ea58b..ddadef6642 100644 --- a/SRC/element/UWelements/BeamEndContact3D.h +++ b/SRC/element/UWelements/BeamEndContact3D.h @@ -130,9 +130,9 @@ class BeamEndContact3D : public Element Vector mIcrd_a; // initial coordinates of node a Vector mIcrd_b; // initial coordinates of node b - Vector mIcrd_s; // initial coordinates of slave node + Vector mIcrd_s; // initial coordinates of secondary node Vector mDcrd_a; // initial coordinates of node a - Vector mDcrd_s; // initial coordinates of slave node + Vector mDcrd_s; // initial coordinates of secondary node }; #endif diff --git a/SRC/element/UWelements/BeamEndContact3Dp.cpp b/SRC/element/UWelements/BeamEndContact3Dp.cpp index 829e358a2b..528e2b83ca 100644 --- a/SRC/element/UWelements/BeamEndContact3Dp.cpp +++ b/SRC/element/UWelements/BeamEndContact3Dp.cpp @@ -282,7 +282,7 @@ BeamEndContact3Dp::update(void) rot_a(i) = disp_a(i+3); } - // update slave node coordinates + // update secondary node coordinates mDcrd_s = mIcrd_s + theNodes[1]->getTrialDisp(); // update the normal vector @@ -544,11 +544,12 @@ Response* BeamEndContact3Dp::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) { if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) { - // forces on slave node + // forces on secondary node return new ElementResponse(this, 1, Vector(3)); - } else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0) { - // reactions (forces and moments) on master node + } else if (strcmp(argv[0],"masterforce") == 0 || strcmp(argv[0],"masterforces") == 0 || + strcmp(argv[0],"primaryforce") == 0 || strcmp(argv[0],"primaryforces") == 0) { + // reactions (forces and moments) on primary node return new ElementResponse(this, 2, Vector(6)); } else { @@ -563,26 +564,26 @@ int BeamEndContact3Dp::getResponse(int responseID, Information &eleInfo) { // initialize variables - Vector slaveForce(3); - Vector masterForce(6); + Vector secondaryForce(3); + Vector primaryForce(6); if (responseID == 1) { - // forces on slave node - slaveForce(0) = -mInternalForces(6); - slaveForce(1) = -mInternalForces(7); - slaveForce(2) = -mInternalForces(8); - return eleInfo.setVector(slaveForce); + // forces on secondary node + secondaryForce(0) = -mInternalForces(6); + secondaryForce(1) = -mInternalForces(7); + secondaryForce(2) = -mInternalForces(8); + return eleInfo.setVector(secondaryForce); } else if (responseID == 2) { - // reactions (forces and moments) on master node + // reactions (forces and moments) on primary node for (int i = 0; i < 3; i++) { - masterForce(i) = -mInternalForces(i); - masterForce(i+3) = -mInternalForces(i+3); + primaryForce(i) = -mInternalForces(i); + primaryForce(i+3) = -mInternalForces(i+3); } - return eleInfo.setVector(masterForce); + return eleInfo.setVector(primaryForce); } else { // otherwise response quantity is unknown for the BeamEndContact3Dp class diff --git a/SRC/element/UWelements/BeamEndContact3Dp.h b/SRC/element/UWelements/BeamEndContact3Dp.h index 680958d156..a4d231e6c8 100644 --- a/SRC/element/UWelements/BeamEndContact3Dp.h +++ b/SRC/element/UWelements/BeamEndContact3Dp.h @@ -126,9 +126,9 @@ class BeamEndContact3Dp : public Element Vector mIcrd_a; // initial coordinates of node a Vector mIcrd_b; // initial coordinates of node b - Vector mIcrd_s; // initial coordinates of slave node + Vector mIcrd_s; // initial coordinates of secondary node Vector mDcrd_a; // initial coordinates of node a - Vector mDcrd_s; // initial coordinates of slave node + Vector mDcrd_s; // initial coordinates of secondary node }; #endif diff --git a/SRC/element/UWelements/PileToe3D.cpp b/SRC/element/UWelements/PileToe3D.cpp index 3559bf42d4..cd63e4e925 100644 --- a/SRC/element/UWelements/PileToe3D.cpp +++ b/SRC/element/UWelements/PileToe3D.cpp @@ -542,7 +542,7 @@ PileToe3D::getResponse(int responseID, Information &eleInfo) Vector mReactions(6); if (responseID == 1) { - // full reactions on master nodes + // full reactions on primary nodes for (int ii=0; ii<6; ii++) { mReactions(ii) = -mInternalForces(ii); } diff --git a/SRC/element/UWelements/SimpleContact2D.cpp b/SRC/element/UWelements/SimpleContact2D.cpp index e0bb735060..facf3f760b 100644 --- a/SRC/element/UWelements/SimpleContact2D.cpp +++ b/SRC/element/UWelements/SimpleContact2D.cpp @@ -70,7 +70,7 @@ OPS_SimpleContact2D(void) Element *theElement = 0; if (OPS_GetNumRemainingInputArgs() != 8) { - opserr << "Invalid #args, want: element SimpleContact2D eleTag? iNode? jNode? slaveNode? lambdaNode? matTag? tolGap? tolForce?\n"; + opserr << "Invalid #args, want: element SimpleContact2D eleTag? iNode? jNode? secondaryNode? lambdaNode? matTag? tolGap? tolForce?\n"; return 0; } @@ -271,17 +271,17 @@ SimpleContact2D::setDomain(Domain *theDomain) dcrdS = theNodes[2]->getCrds(); dispL.Zero(); - // length of master segment + // length of primary segment Vector L = (dcrd2 - dcrd1); - Lmaster = L.Norm(); + Lprimary = L.Norm(); Lsquare = L^L; // adjust cohesion force - theMaterial->ScaleCohesion(Lmaster); - theMaterial->ScaleTensileStrength(Lmaster); + theMaterial->ScaleCohesion(Lprimary); + theMaterial->ScaleTensileStrength(Lprimary); // error check that node 1 and node 2 are not in same location - if (Lmaster < tolGap ) { + if (Lprimary < tolGap ) { opserr << "SimpleContact2D::SimpleContact2D - node 1 and node 2 share same coordinates\n"; opserr << "Program Terminated\n"; exit(-1); @@ -289,15 +289,15 @@ SimpleContact2D::setDomain(Domain *theDomain) // tangent vector - T = L/Lmaster; + T = L/Lprimary; - // normal vector to master surface + // normal vector to primary surface n(0) = -T(1); n(1) = T(0); // n(2) = 0.0; // initialize xsi_n - xsi_n = (2*dcrdS - dcrd1 - dcrd2 )^T / Lmaster; + xsi_n = (2*dcrdS - dcrd1 - dcrd2 )^T / Lprimary; // call the base class method @@ -386,7 +386,7 @@ SimpleContact2D::update(void) gap = n ^ ( dcrdS - N1*dcrd1 - N2*dcrd2 ); - xsi_nplus1 = (2*dcrdS - dcrd1 - dcrd2)^T / Lmaster; + xsi_nplus1 = (2*dcrdS - dcrd1 - dcrd2)^T / Lprimary; Bn(0) = -N1*n(0); Bn(1) = -N1*n(1); @@ -421,7 +421,7 @@ SimpleContact2D::update(void) if (inContact) { - slip = 0.5 * (xsi_nplus1 - xsi_n) * Lmaster; + slip = 0.5 * (xsi_nplus1 - xsi_n) * Lprimary; Vector strain(3); diff --git a/SRC/element/UWelements/SimpleContact2D.h b/SRC/element/UWelements/SimpleContact2D.h index 0184aef4a2..33fdf4aac7 100644 --- a/SRC/element/UWelements/SimpleContact2D.h +++ b/SRC/element/UWelements/SimpleContact2D.h @@ -134,8 +134,8 @@ class SimpleContact2D : public Element Vector n; // normal Vector - // perpendicular to line between nodes 1 & 2 Vector T; // unit tangent vector (reference state) - double Lmaster; // Length of master segment - double Lsquare; // square of Lmaster + double Lprimary; // Length of primary segment + double Lsquare; // square of Lprimary double N1; // value of shape function 1 double N2; // value of shape function 2 diff --git a/SRC/element/UWelements/SimpleContact3D.cpp b/SRC/element/UWelements/SimpleContact3D.cpp index 96fdc2ba79..df3ddf4981 100644 --- a/SRC/element/UWelements/SimpleContact3D.cpp +++ b/SRC/element/UWelements/SimpleContact3D.cpp @@ -70,7 +70,7 @@ OPS_SimpleContact3D(void) Element *theElement = 0; if (OPS_GetNumRemainingInputArgs() != 10) { - opserr << "Invalid #args, want: element SimpleContact3D eleTag? iNode? jNode? kNode? lNode? slaveNode? lambdaNode? matTag? tolGap? tolForce?\n"; + opserr << "Invalid #args, want: element SimpleContact3D eleTag? iNode? jNode? kNode? lNode? secondaryNode? lambdaNode? matTag? tolGap? tolForce?\n"; return 0; } @@ -293,15 +293,15 @@ SimpleContact3D::setDomain(Domain *theDomain) dcrdS = theNodes[4]->getCrds(); dispL.Zero(); - // length of master segments + // length of primary segments Vector L1 = (dcrd2 - dcrd1); - // double L1master = L1.Norm(); + // double L1primary = L1.Norm(); Vector L2 = (dcrd3 - dcrd2); - // double L2master = L2.Norm(); + // double L2primary = L2.Norm(); Vector L3 = (dcrd4 - dcrd3); - // double L3master = L3.Norm(); + // double L3primary = L3.Norm(); Vector L4 = (dcrd1 - dcrd4); - // double L4master = L4.Norm(); + // double L4primary = L4.Norm(); // error check that nodes are not in same location if (fabs(L1(0)) < tolGap && fabs(L1(1)) < tolGap && fabs(L1(2)) < tolGap ) { @@ -348,7 +348,7 @@ SimpleContact3D::setDomain(Domain *theDomain) KinvLin(0,1) = -g_metric(0,1)/detKLin; KinvLin(1,1) = g_metric(0,0)/detKLin; - // normal vector to master surface + // normal vector to primary surface n(0) = g1(1)*g2(2) - g1(2)*g2(1); n(1) = g1(2)*g2(0) - g1(0)*g2(2); n(2) = g1(0)*g2(1) - g1(1)*g2(0); @@ -409,7 +409,7 @@ SimpleContact3D::commitState() KinvLin(1,1) = g_metric(0,0)/detKLin; - // normal vector to master surface + // normal vector to primary surface n(0) = g1(1)*g2(2) - g1(2)*g2(1); n(1) = g1(2)*g2(0) - g1(0)*g2(2); n(2) = g1(0)*g2(1) - g1(1)*g2(0); diff --git a/SRC/element/UWelements/SimpleContact3D.h b/SRC/element/UWelements/SimpleContact3D.h index ab7f3ed73e..1749f762ba 100644 --- a/SRC/element/UWelements/SimpleContact3D.h +++ b/SRC/element/UWelements/SimpleContact3D.h @@ -109,7 +109,7 @@ class SimpleContact3D : public Element Vector project(Vector XiEta0); - // method to obtain projection point on master surface + // method to obtain projection point on primary surface Vector GetPoint(Vector XiEta); // method to update base vectors g1 & g2 int UpdateBase(Vector XiEta); @@ -140,7 +140,7 @@ class SimpleContact3D : public Element Vector d; - Matrix x; // matrix of cartesian coords of nodes 1-4, slave + Matrix x; // matrix of cartesian coords of nodes 1-4, secondary Matrix g_metric; // metric tensor Matrix G_metric; // contravariant metric tensor diff --git a/SRC/element/absorbentBoundaries/LysmerTriangle.cpp b/SRC/element/absorbentBoundaries/LysmerTriangle.cpp index 42a718830d..7be7c9dc1e 100644 --- a/SRC/element/absorbentBoundaries/LysmerTriangle.cpp +++ b/SRC/element/absorbentBoundaries/LysmerTriangle.cpp @@ -273,7 +273,7 @@ LysmerTriangle::UpdateBase(double Xi, double Eta) myNI(2) = 0.5; - // normal vector to master surface as cross product of g1 and g2 + // normal vector to primary surface as cross product of g1 and g2 myNhat(0) = g1(1)*g2(2) - g1(2)*g2(1); myNhat(1) = g1(2)*g2(0) - g1(0)*g2(2); myNhat(2) = g1(0)*g2(1) - g1(1)*g2(0); diff --git a/SRC/element/dispBeamColumn/DispBeamColumn3d.cpp b/SRC/element/dispBeamColumn/DispBeamColumn3d.cpp index 63802a194a..ccdbe6d9f6 100644 --- a/SRC/element/dispBeamColumn/DispBeamColumn3d.cpp +++ b/SRC/element/dispBeamColumn/DispBeamColumn3d.cpp @@ -1399,6 +1399,15 @@ DispBeamColumn3d::setResponse(const char **argv, int argc, OPS_Stream &output) else if (strcmp(argv[0],"integrationWeights") == 0) theResponse = new ElementResponse(this, 11, Vector(numSections)); + + else if (strcmp(argv[0],"xaxis") == 0 || strcmp(argv[0],"xlocal") == 0) + theResponse = new ElementResponse(this, 201, Vector(3)); + + else if (strcmp(argv[0],"yaxis") == 0 || strcmp(argv[0],"ylocal") == 0) + theResponse = new ElementResponse(this, 202, Vector(3)); + + else if (strcmp(argv[0],"zaxis") == 0 || strcmp(argv[0],"zlocal") == 0) + theResponse = new ElementResponse(this, 203, Vector(3)); // section response - else if (strstr(argv[0],"sectionX") != 0) { @@ -1565,6 +1574,22 @@ DispBeamColumn3d::getResponse(int responseID, Information &eleInfo) weights(i) = wts[i]*L; return eleInfo.setVector(weights); } + + else if (responseID >= 201 && responseID <= 203) { + static Vector xlocal(3); + static Vector ylocal(3); + static Vector zlocal(3); + + crdTransf->getLocalAxes(xlocal,ylocal,zlocal); + + if (responseID == 201) + return eleInfo.setVector(xlocal); + if (responseID == 202) + return eleInfo.setVector(ylocal); + if (responseID == 203) + return eleInfo.setVector(zlocal); + } + //by SAJalali else if (responseID == 13) { double xi[maxNumSections]; diff --git a/SRC/element/dispBeamColumn/DispBeamColumn3dID.cpp b/SRC/element/dispBeamColumn/DispBeamColumn3dID.cpp new file mode 100644 index 0000000000..0e2bad389c --- /dev/null +++ b/SRC/element/dispBeamColumn/DispBeamColumn3dID.cpp @@ -0,0 +1,2047 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// Written: Jose Abell +// Created: Aug 2019 +// +// Description: Extends DispBeamColumn3d so that it can take into +// account initial nodal displacements. This is needed in staged construction +// analysis. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Matrix DispBeamColumn3dID::K(12, 12); +Vector DispBeamColumn3dID::P(12); +double DispBeamColumn3dID::workArea[200]; + +void* OPS_DispBeamColumn3dID() +{ + if (OPS_GetNumRemainingInputArgs() < 5) { + opserr << "insufficient arguments:eleTag,iNode,jNode,transfTag,integrationTag <-mass mass> <-cmass>\n"; + return 0; + } + + // inputs: + int iData[5]; + int numData = 5; + if (OPS_GetIntInput(&numData, &iData[0]) < 0) { + opserr << "WARNING: invalid integer inputs\n"; + return 0; + } + + // options + double mass = 0.0; + int cmass = 0; + numData = 1; + while (OPS_GetNumRemainingInputArgs() > 0) { + const char* type = OPS_GetString(); + if (strcmp(type, "-cMass") == 0) { + cmass = 1; + } else if (strcmp(type, "-mass") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + if (OPS_GetDoubleInput(&numData, &mass) < 0) { + opserr << "WARNING: invalid mass\n"; + return 0; + } + } + } + } + + // check transf + CrdTransf* theTransf = OPS_getCrdTransf(iData[3]); + if (theTransf == 0) { + opserr << "coord transfomration not found\n"; + return 0; + } + + // check beam integrataion + BeamIntegrationRule* theRule = OPS_getBeamIntegrationRule(iData[4]); + if (theRule == 0) { + opserr << "beam integration not found\n"; + return 0; + } + BeamIntegration* bi = theRule->getBeamIntegration(); + if (bi == 0) { + opserr << "beam integration is null\n"; + return 0; + } + + // check sections + const ID& secTags = theRule->getSectionTags(); + SectionForceDeformation** sections = new SectionForceDeformation *[secTags.Size()]; + for (int i = 0; i < secTags.Size(); i++) { + sections[i] = OPS_getSectionForceDeformation(secTags(i)); + if (sections[i] == 0) { + opserr << "section " << secTags(i) << "not found\n"; + delete [] sections; + return 0; + } + } + + Element *theEle = new DispBeamColumn3dID(iData[0], iData[1], iData[2], secTags.Size(), sections, + *bi, *theTransf, mass, cmass); + delete [] sections; + return theEle; +} + + +DispBeamColumn3dID::DispBeamColumn3dID(int tag, int nd1, int nd2, + int numSec, SectionForceDeformation **s, + BeamIntegration &bi, + CrdTransf &coordTransf, double r, int cm) + : Element (tag, ELE_TAG_DispBeamColumn3dID), + numSections(numSec), theSections(0), crdTransf(0), beamInt(0), + connectedExternalNodes(2), + Q(12), q(6), rho(r), cMass(cm), parameterID(0) +{ + // Allocate arrays of pointers to SectionForceDeformations + theSections = new SectionForceDeformation *[numSections]; + + if (theSections == 0) { + opserr << "DispBeamColumn3dID::DispBeamColumn3dID - failed to allocate section model pointer\n"; + exit(-1); + } + + for (int i = 0; i < numSections; i++) { + + // Get copies of the material model for each integration point + theSections[i] = s[i]->getCopy(); + + // Check allocation + if (theSections[i] == 0) { + opserr << "DispBeamColumn3dID::DispBeamColumn3dID -- failed to get a copy of section model\n"; + exit(-1); + } + } + + beamInt = bi.getCopy(); + + if (beamInt == 0) { + opserr << "DispBeamColumn3dID::DispBeamColumn3dID - failed to copy beam integration\n"; + exit(-1); + } + + crdTransf = coordTransf.getCopy3d(); + + if (crdTransf == 0) { + opserr << "DispBeamColumn3dID::DispBeamColumn3dID - failed to copy coordinate transformation\n"; + exit(-1); + } + + // Set connected external node IDs + connectedExternalNodes(0) = nd1; + connectedExternalNodes(1) = nd2; + + + theNodes[0] = 0; + theNodes[1] = 0; + + q0[0] = 0.0; + q0[1] = 0.0; + q0[2] = 0.0; + q0[3] = 0.0; + q0[4] = 0.0; + + p0[0] = 0.0; + p0[1] = 0.0; + p0[2] = 0.0; + p0[3] = 0.0; + p0[4] = 0.0; +} + +DispBeamColumn3dID::DispBeamColumn3dID() + : Element (0, ELE_TAG_DispBeamColumn3dID), + numSections(0), theSections(0), crdTransf(0), beamInt(0), + connectedExternalNodes(2), + Q(12), q(6), rho(0.0), cMass(0), parameterID(0) +{ + q0[0] = 0.0; + q0[1] = 0.0; + q0[2] = 0.0; + q0[3] = 0.0; + q0[4] = 0.0; + + p0[0] = 0.0; + p0[1] = 0.0; + p0[2] = 0.0; + p0[3] = 0.0; + p0[4] = 0.0; + + theNodes[0] = 0; + theNodes[1] = 0; +} + +DispBeamColumn3dID::~DispBeamColumn3dID() +{ + for (int i = 0; i < numSections; i++) { + if (theSections[i]) + delete theSections[i]; + } + + // Delete the array of pointers to SectionForceDeformation pointer arrays + if (theSections) + delete [] theSections; + + if (crdTransf) + delete crdTransf; + + if (beamInt != 0) + delete beamInt; +} + +int +DispBeamColumn3dID::getNumExternalNodes() const +{ + return 2; +} + +const ID& +DispBeamColumn3dID::getExternalNodes() +{ + return connectedExternalNodes; +} + +Node ** +DispBeamColumn3dID::getNodePtrs() +{ + + return theNodes; +} + +int +DispBeamColumn3dID::getNumDOF() +{ + return 12; +} + +void +DispBeamColumn3dID::setDomain(Domain *theDomain) +{ + // Check Domain is not null - invoked when object removed from a domain + if (theDomain == 0) { + theNodes[0] = 0; + theNodes[1] = 0; + return; + } + + int Nd1 = connectedExternalNodes(0); + int Nd2 = connectedExternalNodes(1); + + theNodes[0] = theDomain->getNode(Nd1); + theNodes[1] = theDomain->getNode(Nd2); + + if (theNodes[0] == 0 || theNodes[1] == 0) { + //opserr << "FATAL ERROR DispBeamColumn3dID (tag: %d), node not found in domain", + // this->getTag()); + + return; + } + + int dofNd1 = theNodes[0]->getNumberDOF(); + int dofNd2 = theNodes[1]->getNumberDOF(); + + if (dofNd1 != 6 || dofNd2 != 6) { + //opserr << "FATAL ERROR DispBeamColumn3dID (tag: %d), has differing number of DOFs at its nodes", + // this->getTag()); + + return; + } + + // Initialize initial disps + const Vector &d1 = theNodes[0]->getTrialDisp(); + const Vector &d2 = theNodes[1]->getTrialDisp(); + init_disp[0] = d1(0); + init_disp[1] = d1(1); + init_disp[2] = d1(2); + init_disp[3] = d2(0); + init_disp[4] = d2(1); + init_disp[5] = d2(2); + + if (crdTransf->initialize(theNodes[0], theNodes[1])) { + // Add some error check + } + + double L = crdTransf->getInitialLength(); + + if (L == 0.0) { + // Add some error check + } + + this->DomainComponent::setDomain(theDomain); + + this->update(); +} + +int +DispBeamColumn3dID::commitState() +{ + int retVal = 0; + + // call element commitState to do any base class stuff + if ((retVal = this->Element::commitState()) != 0) { + opserr << "DispBeamColumn3dID::commitState () - failed in base class"; + } + + // Loop over the integration points and commit the material states + for (int i = 0; i < numSections; i++) + retVal += theSections[i]->commitState(); + + retVal += crdTransf->commitState(); + + return retVal; +} + +int +DispBeamColumn3dID::revertToLastCommit() +{ + int retVal = 0; + + // Loop over the integration points and revert to last committed state + for (int i = 0; i < numSections; i++) + retVal += theSections[i]->revertToLastCommit(); + + retVal += crdTransf->revertToLastCommit(); + + return retVal; +} + +int +DispBeamColumn3dID::revertToStart() +{ + int retVal = 0; + + // Loop over the integration points and revert states to start + for (int i = 0; i < numSections; i++) + retVal += theSections[i]->revertToStart(); + + retVal += crdTransf->revertToStart(); + + return retVal; +} + +int +DispBeamColumn3dID::update(void) +{ + int err = 0; + + // Update the transformation + crdTransf->update(); + + // Get basic deformations + const Vector &v0 = crdTransf->getBasicTrialDisp(); + + static Vector v(6); v.Zero(); + + v(0) = v0(0) - init_disp[0]; + v(1) = v0(1) - init_disp[1]; + v(2) = v0(2) - init_disp[2]; + v(3) = v0(3) - init_disp[3]; + v(4) = v0(4) - init_disp[4]; + v(5) = v0(5) - init_disp[5]; + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0 / L; + + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + Vector e(workArea, order); + + double xi6 = 6.0 * xi[i]; + + int j; + for (j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_P: + e(j) = oneOverL * v(0); + break; + case SECTION_RESPONSE_MZ: + e(j) = oneOverL * ((xi6 - 4.0) * v(1) + (xi6 - 2.0) * v(2)); + break; + case SECTION_RESPONSE_MY: + e(j) = oneOverL * ((xi6 - 4.0) * v(3) + (xi6 - 2.0) * v(4)); + break; + case SECTION_RESPONSE_T: + e(j) = oneOverL * v(5); + break; + default: + e(j) = 0.0; + break; + } + } + + // Set the section deformations + err += theSections[i]->setTrialSectionDeformation(e); + } + + if (err != 0) { + opserr << "DispBeamColumn3dID::update() - failed setTrialSectionDeformations()\n"; + return err; + } + return 0; +} + +const Matrix& +DispBeamColumn3dID::getTangentStiff() +{ + static Matrix kb(6, 6); + + // Zero for integral + kb.Zero(); + q.Zero(); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0 / L; + + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + //const Vector &wts = quadRule.getIntegrPointWeights(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + double wt[maxNumSections]; + beamInt->getSectionWeights(numSections, L, wt); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + Matrix ka(workArea, order, 6); + ka.Zero(); + + double xi6 = 6.0 * xi[i]; + + // Get the section tangent stiffness and stress resultant + const Matrix &ks = theSections[i]->getSectionTangent(); + const Vector &s = theSections[i]->getStressResultant(); + + // Perform numerical integration + //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L); + double wti = wt[i] * oneOverL; + double tmp; + int j, k; + for (j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_P: + for (k = 0; k < order; k++) + ka(k, 0) += ks(k, j) * wti; + break; + case SECTION_RESPONSE_MZ: + for (k = 0; k < order; k++) { + tmp = ks(k, j) * wti; + ka(k, 1) += (xi6 - 4.0) * tmp; + ka(k, 2) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_MY: + for (k = 0; k < order; k++) { + tmp = ks(k, j) * wti; + ka(k, 3) += (xi6 - 4.0) * tmp; + ka(k, 4) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_T: + for (k = 0; k < order; k++) + ka(k, 5) += ks(k, j) * wti; + break; + default: + break; + } + } + for (j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_P: + for (k = 0; k < 6; k++) + kb(0, k) += ka(j, k); + break; + case SECTION_RESPONSE_MZ: + for (k = 0; k < 6; k++) { + tmp = ka(j, k); + kb(1, k) += (xi6 - 4.0) * tmp; + kb(2, k) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_MY: + for (k = 0; k < 6; k++) { + tmp = ka(j, k); + kb(3, k) += (xi6 - 4.0) * tmp; + kb(4, k) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_T: + for (k = 0; k < 6; k++) + kb(5, k) += ka(j, k); + break; + default: + break; + } + } + + //q.addMatrixTransposeVector(1.0, *B, s, wts(i)); + double si; + for (j = 0; j < order; j++) { + si = s(j) * wt[i]; + switch (code(j)) { + case SECTION_RESPONSE_P: + q(0) += si; + break; + case SECTION_RESPONSE_MZ: + q(1) += (xi6 - 4.0) * si; q(2) += (xi6 - 2.0) * si; + break; + case SECTION_RESPONSE_MY: + q(3) += (xi6 - 4.0) * si; q(4) += (xi6 - 2.0) * si; + break; + case SECTION_RESPONSE_T: + q(5) += si; + break; + default: + break; + } + } + + } + + q(0) += q0[0]; + q(1) += q0[1]; + q(2) += q0[2]; + q(3) += q0[3]; + q(4) += q0[4]; + + // Transform to global stiffness + K = crdTransf->getGlobalStiffMatrix(kb, q); + // opserr << this->getTag() << " " << K; + return K; +} + +const Matrix& +DispBeamColumn3dID::getInitialBasicStiff() +{ + static Matrix kb(6, 6); + + // Zero for integral + kb.Zero(); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0 / L; + + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + //const Vector &wts = quadRule.getIntegrPointWeights(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + double wt[maxNumSections]; + beamInt->getSectionWeights(numSections, L, wt); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + Matrix ka(workArea, order, 6); + ka.Zero(); + + double xi6 = 6.0 * xi[i]; + + // Get the section tangent stiffness and stress resultant + const Matrix &ks = theSections[i]->getInitialTangent(); + + // Perform numerical integration + //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L); + double wti = wt[i] * oneOverL; + double tmp; + int j, k; + for (j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_P: + for (k = 0; k < order; k++) + ka(k, 0) += ks(k, j) * wti; + break; + case SECTION_RESPONSE_MZ: + for (k = 0; k < order; k++) { + tmp = ks(k, j) * wti; + ka(k, 1) += (xi6 - 4.0) * tmp; + ka(k, 2) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_MY: + for (k = 0; k < order; k++) { + tmp = ks(k, j) * wti; + ka(k, 3) += (xi6 - 4.0) * tmp; + ka(k, 4) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_T: + for (k = 0; k < order; k++) + ka(k, 5) += ks(k, j) * wti; + break; + default: + break; + } + } + for (j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_P: + for (k = 0; k < 6; k++) + kb(0, k) += ka(j, k); + break; + case SECTION_RESPONSE_MZ: + for (k = 0; k < 6; k++) { + tmp = ka(j, k); + kb(1, k) += (xi6 - 4.0) * tmp; + kb(2, k) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_MY: + for (k = 0; k < 6; k++) { + tmp = ka(j, k); + kb(3, k) += (xi6 - 4.0) * tmp; + kb(4, k) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_T: + for (k = 0; k < 6; k++) + kb(5, k) += ka(j, k); + break; + default: + break; + } + } + + } + + return kb; +} + +const Matrix& +DispBeamColumn3dID::getInitialStiff() +{ + const Matrix &kb = this->getInitialBasicStiff(); + + // Transform to global stiffness + K = crdTransf->getInitialGlobalStiffMatrix(kb); + + return K; +} + +const Matrix& +DispBeamColumn3dID::getMass() +{ + K.Zero(); + + if (rho == 0.0) + return K; + + double L = crdTransf->getInitialLength(); + if (cMass == 0) { + // lumped mass matrix + double m = 0.5 * rho * L; + K(0, 0) = K(1, 1) = K(2, 2) = K(6, 6) = K(7, 7) = K(8, 8) = m; + } else { + // consistent mass matrix + static Matrix ml(12, 12); + double m = rho * L / 420.0; + ml(0, 0) = ml(6, 6) = m * 140.0; + ml(0, 6) = ml(6, 0) = m * 70.0; + //ml(3,3) = ml(9,9) = m*(Jx/A)*140.0; // CURRENTLY NO TORSIONAL MASS + //ml(3,9) = ml(9,3) = m*(Jx/A)*70.0; // CURRENTLY NO TORSIONAL MASS + + ml(2, 2) = ml(8, 8) = m * 156.0; + ml(2, 8) = ml(8, 2) = m * 54.0; + ml(4, 4) = ml(10, 10) = m * 4.0 * L * L; + ml(4, 10) = ml(10, 4) = -m * 3.0 * L * L; + ml(2, 4) = ml(4, 2) = -m * 22.0 * L; + ml(8, 10) = ml(10, 8) = -ml(2, 4); + ml(2, 10) = ml(10, 2) = m * 13.0 * L; + ml(4, 8) = ml(8, 4) = -ml(2, 10); + + ml(1, 1) = ml(7, 7) = m * 156.0; + ml(1, 7) = ml(7, 1) = m * 54.0; + ml(5, 5) = ml(11, 11) = m * 4.0 * L * L; + ml(5, 11) = ml(11, 5) = -m * 3.0 * L * L; + ml(1, 5) = ml(5, 1) = m * 22.0 * L; + ml(7, 11) = ml(11, 7) = -ml(1, 5); + ml(1, 11) = ml(11, 1) = -m * 13.0 * L; + ml(5, 7) = ml(7, 5) = -ml(1, 11); + + // transform local mass matrix to global system + K = crdTransf->getGlobalMatrixFromLocal(ml); + } + + return K; +} + +void +DispBeamColumn3dID::zeroLoad(void) +{ + Q.Zero(); + + q0[0] = 0.0; + q0[1] = 0.0; + q0[2] = 0.0; + q0[3] = 0.0; + q0[4] = 0.0; + + p0[0] = 0.0; + p0[1] = 0.0; + p0[2] = 0.0; + p0[3] = 0.0; + p0[4] = 0.0; + + return; +} + +int +DispBeamColumn3dID::addLoad(ElementalLoad *theLoad, double loadFactor) +{ + int type; + const Vector &data = theLoad->getData(type, loadFactor); + double L = crdTransf->getInitialLength(); + + if (type == LOAD_TAG_Beam3dUniformLoad) { + double wy = data(0) * loadFactor; // Transverse + double wz = data(1) * loadFactor; // Transverse + double wx = data(2) * loadFactor; // Axial (+ve from node I to J) + + double Vy = 0.5 * wy * L; + double Mz = Vy * L / 6.0; // wy*L*L/12 + double Vz = 0.5 * wz * L; + double My = Vz * L / 6.0; // wz*L*L/12 + double P = wx * L; + + // Reactions in basic system + p0[0] -= P; + p0[1] -= Vy; + p0[2] -= Vy; + p0[3] -= Vz; + p0[4] -= Vz; + + // Fixed end forces in basic system + q0[0] -= 0.5 * P; + q0[1] -= Mz; + q0[2] += Mz; + q0[3] += My; + q0[4] -= My; + } + else if (type == LOAD_TAG_Beam3dPointLoad) { + double Py = data(0) * loadFactor; + double Pz = data(1) * loadFactor; + double N = data(2) * loadFactor; + double aOverL = data(3); + + if (aOverL < 0.0 || aOverL > 1.0) + return 0; + + double a = aOverL * L; + double b = L - a; + + // Reactions in basic system + p0[0] -= N; + double V1, V2; + V1 = Py * (1.0 - aOverL); + V2 = Py * aOverL; + p0[1] -= V1; + p0[2] -= V2; + V1 = Pz * (1.0 - aOverL); + V2 = Pz * aOverL; + p0[3] -= V1; + p0[4] -= V2; + + double L2 = 1.0 / (L * L); + double a2 = a * a; + double b2 = b * b; + + // Fixed end forces in basic system + q0[0] -= N * aOverL; + double M1, M2; + M1 = -a * b2 * Py * L2; + M2 = a2 * b * Py * L2; + q0[1] += M1; + q0[2] += M2; + M1 = -a * b2 * Pz * L2; + M2 = a2 * b * Pz * L2; + q0[3] -= M1; + q0[4] -= M2; + } + else { + opserr << "DispBeamColumn3dID::addLoad() -- load type unknown for element with tag: " << + this->getTag() << endln; + return -1; + } + + return 0; +} + +int +DispBeamColumn3dID::addInertiaLoadToUnbalance(const Vector &accel) +{ + // Check for a quick return + if (rho == 0.0) + return 0; + + // Get R * accel from the nodes + const Vector &Raccel1 = theNodes[0]->getRV(accel); + const Vector &Raccel2 = theNodes[1]->getRV(accel); + + if (6 != Raccel1.Size() || 6 != Raccel2.Size()) { + opserr << "DispBeamColumn3dID::addInertiaLoadToUnbalance matrix and vector sizes are incompatible\n"; + return -1; + } + + // want to add ( - fact * M R * accel ) to unbalance + if (cMass == 0) { + // take advantage of lumped mass matrix + double L = crdTransf->getInitialLength(); + double m = 0.5 * rho * L; + + Q(0) -= m * Raccel1(0); + Q(1) -= m * Raccel1(1); + Q(2) -= m * Raccel1(2); + Q(6) -= m * Raccel2(0); + Q(7) -= m * Raccel2(1); + Q(8) -= m * Raccel2(2); + + } else { + // use matrix vector multip. for consistent mass matrix + static Vector Raccel(12); + for (int i = 0; i < 6; i++) { + Raccel(i) = Raccel1(i); + Raccel(i + 6) = Raccel2(i); + } + Q.addMatrixVector(1.0, this->getMass(), Raccel, -1.0); + } + + return 0; +} + +const Vector& +DispBeamColumn3dID::getResistingForce() +{ + double L = crdTransf->getInitialLength(); + + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + //const Vector &wts = quadRule.getIntegrPointWeights(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + double wt[maxNumSections]; + beamInt->getSectionWeights(numSections, L, wt); + + // Zero for integration + q.Zero(); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + double xi6 = 6.0 * xi[i]; + + // Get section stress resultant + const Vector &s = theSections[i]->getStressResultant(); + + // Perform numerical integration on internal force + //q.addMatrixTransposeVector(1.0, *B, s, wts(i)); + + double si; + for (int j = 0; j < order; j++) { + si = s(j) * wt[i]; + switch (code(j)) { + case SECTION_RESPONSE_P: + q(0) += si; + break; + case SECTION_RESPONSE_MZ: + q(1) += (xi6 - 4.0) * si; q(2) += (xi6 - 2.0) * si; + break; + case SECTION_RESPONSE_MY: + q(3) += (xi6 - 4.0) * si; q(4) += (xi6 - 2.0) * si; + break; + case SECTION_RESPONSE_T: + q(5) += si; + break; + default: + break; + } + } + + } + + q(0) += q0[0]; + q(1) += q0[1]; + q(2) += q0[2]; + q(3) += q0[3]; + q(4) += q0[4]; + + // Transform forces + Vector p0Vec(p0, 5); + P = crdTransf->getGlobalResistingForce(q, p0Vec); + + // Subtract other external nodal loads ... P_res = P_int - P_ext + if (rho != 0) + P.addVector(1.0, Q, -1.0); + + return P; +} + +const Vector& +DispBeamColumn3dID::getResistingForceIncInertia() +{ + P = this->getResistingForce(); + + if (rho != 0.0) { + const Vector &accel1 = theNodes[0]->getTrialAccel(); + const Vector &accel2 = theNodes[1]->getTrialAccel(); + + if (cMass == 0) { + // take advantage of lumped mass matrix + double L = crdTransf->getInitialLength(); + double m = 0.5 * rho * L; + + P(0) += m * accel1(0); + P(1) += m * accel1(1); + P(2) += m * accel1(2); + P(6) += m * accel2(0); + P(7) += m * accel2(1); + P(8) += m * accel2(2); + } else { + // use matrix vector multip. for consistent mass matrix + static Vector accel(12); + for (int i = 0; i < 6; i++) { + accel(i) = accel1(i); + accel(i + 6) = accel2(i); + } + P.addMatrixVector(1.0, this->getMass(), accel, 1.0); + } + + // add the damping forces if rayleigh damping + if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P.addVector(1.0, this->getRayleighDampingForces(), 1.0); + + } else { + + // add the damping forces if rayleigh damping + if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P.addVector(1.0, this->getRayleighDampingForces(), 1.0); + } + + return P; +} + +int +DispBeamColumn3dID::sendSelf(int commitTag, Channel &theChannel) +{ + // place the integer data into an ID + + int dbTag = this->getDbTag(); + int i, j; + int loc = 0; + + static Vector data(14+6); + data(0) = this->getTag(); + data(1) = connectedExternalNodes(0); + data(2) = connectedExternalNodes(1); + data(3) = numSections; + data(4) = crdTransf->getClassTag(); + int crdTransfDbTag = crdTransf->getDbTag(); + if (crdTransfDbTag == 0) { + crdTransfDbTag = theChannel.getDbTag(); + if (crdTransfDbTag != 0) + crdTransf->setDbTag(crdTransfDbTag); + } + data(5) = crdTransfDbTag; + data(6) = beamInt->getClassTag(); + int beamIntDbTag = beamInt->getDbTag(); + if (beamIntDbTag == 0) { + beamIntDbTag = theChannel.getDbTag(); + if (beamIntDbTag != 0) + beamInt->setDbTag(beamIntDbTag); + } + data(7) = beamIntDbTag; + data(8) = rho; + data(9) = cMass; + data(10) = alphaM; + data(11) = betaK; + data(12) = betaK0; + data(13) = betaKc; + data(14) = init_disp[0]; + data(15) = init_disp[1]; + data(16) = init_disp[2]; + data(17) = init_disp[3]; + data(18) = init_disp[4]; + data(19) = init_disp[5]; + + if (theChannel.sendVector(dbTag, commitTag, data) < 0) { + opserr << "DispBeamColumn3dID::sendSelf() - failed to send data Vector\n"; + return -1; + } + + // send the coordinate transformation + if (crdTransf->sendSelf(commitTag, theChannel) < 0) { + opserr << "DispBeamColumn3dID::sendSelf() - failed to send crdTranf\n"; + return -1; + } + + // send the beam integration + if (beamInt->sendSelf(commitTag, theChannel) < 0) { + opserr << "DispBeamColumn3dID::sendSelf() - failed to send beamInt\n"; + return -1; + } + + // + // send an ID for the sections containing each sections dbTag and classTag + // if section ha no dbTag get one and assign it + // + + ID idSections(2 * numSections); + loc = 0; + for (i = 0; i < numSections; i++) { + int sectClassTag = theSections[i]->getClassTag(); + int sectDbTag = theSections[i]->getDbTag(); + if (sectDbTag == 0) { + sectDbTag = theChannel.getDbTag(); + theSections[i]->setDbTag(sectDbTag); + } + + idSections(loc) = sectClassTag; + idSections(loc + 1) = sectDbTag; + loc += 2; + } + + if (theChannel.sendID(dbTag, commitTag, idSections) < 0) { + opserr << "DispBeamColumn3dID::sendSelf() - failed to send ID data\n"; + return -1; + } + + // + // send the sections + // + + for (j = 0; j < numSections; j++) { + if (theSections[j]->sendSelf(commitTag, theChannel) < 0) { + opserr << "DispBeamColumn3dID::sendSelf() - section " << j << "failed to send itself\n"; + return -1; + } + } + + return 0; +} + +int +DispBeamColumn3dID::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + // + // receive the integer data containing tag, numSections and coord transformation info + // + int dbTag = this->getDbTag(); + int i; + + static Vector data(14+6); + + if (theChannel.recvVector(dbTag, commitTag, data) < 0) { + opserr << "DispBeamColumn3dID::recvSelf() - failed to recv data Vector\n"; + return -1; + } + + this->setTag((int)data(0)); + connectedExternalNodes(0) = (int)data(1); + connectedExternalNodes(1) = (int)data(2); + int nSect = (int)data(3); + int crdTransfClassTag = (int)data(4); + int crdTransfDbTag = (int)data(5); + + int beamIntClassTag = (int)data(6); + int beamIntDbTag = (int)data(7); + + rho = data(8); + cMass = (int)data(9); + + alphaM = data(10); + betaK = data(11); + betaK0 = data(12); + betaKc = data(13); + + init_disp[0] = data(14); + init_disp[1] = data(15); + init_disp[2] = data(16); + init_disp[3] = data(17); + init_disp[4] = data(18); + init_disp[5] = data(19); + + // create a new crdTransf object if one needed + if (crdTransf == 0 || crdTransf->getClassTag() != crdTransfClassTag) { + if (crdTransf != 0) + delete crdTransf; + + crdTransf = theBroker.getNewCrdTransf(crdTransfClassTag); + + if (crdTransf == 0) { + opserr << "DispBeamColumn3dID::recvSelf() - " << + "failed to obtain a CrdTrans object with classTag" << + crdTransfClassTag << endln; + return -2; + } + } + + crdTransf->setDbTag(crdTransfDbTag); + + // invoke recvSelf on the crdTransf object + if (crdTransf->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "DispBeamColumn3dID::sendSelf() - failed to recv crdTranf\n"; + return -3; + } + + // create a new beamInt object if one needed + if (beamInt == 0 || beamInt->getClassTag() != beamIntClassTag) { + if (beamInt != 0) + delete beamInt; + + beamInt = theBroker.getNewBeamIntegration(beamIntClassTag); + + if (beamInt == 0) { + opserr << "DispBeamColumn3dID::recvSelf() - failed to obtain the beam integration object with classTag" << + beamIntClassTag << endln; + exit(-1); + } + } + + beamInt->setDbTag(beamIntDbTag); + + // invoke recvSelf on the beamInt object + if (beamInt->recvSelf(commitTag, theChannel, theBroker) < 0) + { + opserr << "DispBeamColumn3dID::sendSelf() - failed to recv beam integration\n"; + return -3; + } + + // + // recv an ID for the sections containing each sections dbTag and classTag + // + + ID idSections(2 * nSect); + int loc = 0; + + if (theChannel.recvID(dbTag, commitTag, idSections) < 0) { + opserr << "DispBeamColumn3dID::recvSelf() - failed to recv ID data\n"; + return -1; + } + + // + // now receive the sections + // + + if (numSections != nSect) { + + // + // we do not have correct number of sections, must delete the old and create + // new ones before can recvSelf on the sections + // + + // delete the old + if (numSections != 0) { + for (int i = 0; i < numSections; i++) + delete theSections[i]; + delete [] theSections; + } + + // create a new array to hold pointers + theSections = new SectionForceDeformation *[nSect]; + if (theSections == 0) { + opserr << "DispBeamColumn3dID::recvSelf() - out of memory creating sections array of size" << + nSect << endln; + exit(-1); + } + + // create a section and recvSelf on it + numSections = nSect; + loc = 0; + + for (i = 0; i < numSections; i++) { + int sectClassTag = idSections(loc); + int sectDbTag = idSections(loc + 1); + loc += 2; + theSections[i] = theBroker.getNewSection(sectClassTag); + if (theSections[i] == 0) { + opserr << "DispBeamColumn3dID::recvSelf() - Broker could not create Section of class type" << + sectClassTag << endln; + exit(-1); + } + theSections[i]->setDbTag(sectDbTag); + if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "DispBeamColumn3dID::recvSelf() - section " << + i << "failed to recv itself\n"; + return -1; + } + } + + } else { + + // + // for each existing section, check it is of correct type + // (if not delete old & create a new one) then recvSelf on it + // + + loc = 0; + for (i = 0; i < numSections; i++) { + int sectClassTag = idSections(loc); + int sectDbTag = idSections(loc + 1); + loc += 2; + + // check of correct type + if (theSections[i]->getClassTag() != sectClassTag) { + // delete the old section[i] and create a new one + delete theSections[i]; + theSections[i] = theBroker.getNewSection(sectClassTag); + if (theSections[i] == 0) { + opserr << "DispBeamColumn3dID::recvSelf() - Broker could not create Section of class type" << + sectClassTag << endln; + exit(-1); + } + } + + // recvSelf on it + theSections[i]->setDbTag(sectDbTag); + if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "DispBeamColumn3dID::recvSelf() - section " << + i << "failed to recv itself\n"; + return -1; + } + } + } + + return 0; +} + +void +DispBeamColumn3dID::Print(OPS_Stream &s, int flag) +{ + if (flag == OPS_PRINT_CURRENTSTATE) { + s << "\nDispBeamColumn3dID, element id: " << this->getTag() << endln; + s << "\tConnected external nodes: " << connectedExternalNodes; + s << "\tCoordTransf: " << crdTransf->getTag() << endln; + s << "\tmass density: " << rho << ", cMass: " << cMass << endln; + s << "\tinit_disp: " << init_disp[0] << " " << + init_disp[1] << " " << + init_disp[2] << " " << + init_disp[3] << " " << + init_disp[4] << " " << + init_disp[5] << endln; + + double N, Mz1, Mz2, Vy, My1, My2, Vz, T; + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0 / L; + + N = q(0); + Mz1 = q(1); + Mz2 = q(2); + Vy = (Mz1 + Mz2) * oneOverL; + My1 = q(3); + My2 = q(4); + Vz = -(My1 + My2) * oneOverL; + T = q(5); + + s << "\tEnd 1 Forces (P Mz Vy My Vz T): " + << -N + p0[0] << ' ' << Mz1 << ' ' << Vy + p0[1] << ' ' << My1 << ' ' << Vz + p0[3] << ' ' << -T << endln; + s << "\tEnd 2 Forces (P Mz Vy My Vz T): " + << N << ' ' << Mz2 << ' ' << -Vy + p0[2] << ' ' << My2 << ' ' << -Vz + p0[4] << ' ' << T << endln; + s << "Number of sections: " << numSections << endln; + beamInt->Print(s, flag); + + for (int i = 0; i < numSections; i++) { + //opserr << "Section Type: " << theSections[i]->getClassTag() << endln; + theSections[i]->Print(s, flag); + } + // if (rho != 0) + // opserr << "Mass: \n" << this->getMass(); + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << "\t\t\t{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"DispBeamColumn3dID\", "; + s << "\"nodes\": [" << connectedExternalNodes(0) << ", " << connectedExternalNodes(1) << "], "; + s << "\"init_disp\": [" << init_disp[0] << ", " << init_disp[1] << ", " << init_disp[2] << ", " <getTag() << "\", "; + s << "\"" << theSections[numSections - 1]->getTag() << "\"], "; + s << "\"integration\": "; + beamInt->Print(s, flag); + s << ", \"massperlength\": " << rho << ", "; + s << "\"crdTransformation\": \"" << crdTransf->getTag() << "\"}"; + } +} + + +int +DispBeamColumn3dID::displaySelf(Renderer &theViewer, int displayMode, float fact, const char **modes, int numModes) +{ + static Vector v1(3); + static Vector v2(3); + + if (displayMode >= 0) { + + theNodes[0]->getDisplayCrds(v1, fact); + theNodes[1]->getDisplayCrds(v2, fact); + + } else { + + theNodes[0]->getDisplayCrds(v1, 0.); + theNodes[1]->getDisplayCrds(v2, 0.); + + // add eigenvector values + int mode = displayMode * -1; + const Matrix &eigen1 = theNodes[0]->getEigenvectors(); + const Matrix &eigen2 = theNodes[1]->getEigenvectors(); + if (eigen1.noCols() >= mode) { + for (int i = 0; i < 3; i++) { + v1(i) += eigen1(i, mode - 1) * fact; + v2(i) += eigen2(i, mode - 1) * fact; + } + } + } + return theViewer.drawLine (v1, v2, 1.0, 1.0, this->getTag()); +} + +Response* +DispBeamColumn3dID::setResponse(const char **argv, int argc, OPS_Stream &output) +{ + + Response *theResponse = 0; + + output.tag("ElementOutput"); + output.attr("eleType", "DispBeamColumn3dID"); + output.attr("eleTag", this->getTag()); + output.attr("node1", connectedExternalNodes[0]); + output.attr("node2", connectedExternalNodes[1]); + + // + // we compare argv[0] for known response types + // + + // global force - + if (strcmp(argv[0], "forces") == 0 || strcmp(argv[0], "force") == 0 + || strcmp(argv[0], "globalForce") == 0 || strcmp(argv[0], "globalForces") == 0) { + + output.tag("ResponseType", "Px_1"); + output.tag("ResponseType", "Py_1"); + output.tag("ResponseType", "Pz_1"); + output.tag("ResponseType", "Mx_1"); + output.tag("ResponseType", "My_1"); + output.tag("ResponseType", "Mz_1"); + output.tag("ResponseType", "Px_2"); + output.tag("ResponseType", "Py_2"); + output.tag("ResponseType", "Pz_2"); + output.tag("ResponseType", "Mx_2"); + output.tag("ResponseType", "My_2"); + output.tag("ResponseType", "Mz_2"); + + + theResponse = new ElementResponse(this, 1, P); + + // local force - + } else if (strcmp(argv[0], "localForce") == 0 || strcmp(argv[0], "localForces") == 0) { + + output.tag("ResponseType", "N_1"); + output.tag("ResponseType", "Vy_1"); + output.tag("ResponseType", "Vz_1"); + output.tag("ResponseType", "T_1"); + output.tag("ResponseType", "My_1"); + output.tag("ResponseType", "Mz_1"); + output.tag("ResponseType", "N_2"); + output.tag("ResponseType", "Vy_2"); + output.tag("ResponseType", "Vz_2"); + output.tag("ResponseType", "T_2"); + output.tag("ResponseType", "My_2"); + output.tag("ResponseType", "Mz_2"); + + theResponse = new ElementResponse(this, 2, P); + + // chord rotation - + } else if (strcmp(argv[0], "chordRotation") == 0 || strcmp(argv[0], "chordDeformation") == 0 + || strcmp(argv[0], "basicDeformation") == 0) { + + output.tag("ResponseType", "eps"); + output.tag("ResponseType", "thetaZ_1"); + output.tag("ResponseType", "thetaZ_2"); + output.tag("ResponseType", "thetaY_1"); + output.tag("ResponseType", "thetaY_2"); + output.tag("ResponseType", "thetaX"); + + theResponse = new ElementResponse(this, 3, Vector(6)); + + // plastic rotation - + } else if (strcmp(argv[0], "plasticRotation") == 0 || strcmp(argv[0], "plasticDeformation") == 0) { + + output.tag("ResponseType", "epsP"); + output.tag("ResponseType", "thetaZP_1"); + output.tag("ResponseType", "thetaZP_2"); + output.tag("ResponseType", "thetaYP_1"); + output.tag("ResponseType", "thetaYP_2"); + output.tag("ResponseType", "thetaXP"); + + theResponse = new ElementResponse(this, 4, Vector(6)); + + + } else if (strcmp(argv[0], "RayleighForces") == 0 || strcmp(argv[0], "rayleighForces") == 0) { + + theResponse = new ElementResponse(this, 12, P); + + } + else if (strcmp(argv[0], "integrationPoints") == 0) + theResponse = new ElementResponse(this, 10, Vector(numSections)); + + else if (strcmp(argv[0], "integrationWeights") == 0) + theResponse = new ElementResponse(this, 11, Vector(numSections)); + + // section response - + else if (strstr(argv[0], "sectionX") != 0) { + if (argc > 2) { + float sectionLoc = atof(argv[1]); + + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamInt->getSectionLocations(numSections, L, xi); + + sectionLoc /= L; + + float minDistance = fabs(xi[0] - sectionLoc); + int sectionNum = 0; + for (int i = 1; i < numSections; i++) { + if (fabs(xi[i] - sectionLoc) < minDistance) { + minDistance = fabs(xi[i] - sectionLoc); + sectionNum = i; + } + } + + output.tag("GaussPointOutput"); + output.attr("number", sectionNum + 1); + output.attr("eta", xi[sectionNum]*L); + + theResponse = theSections[sectionNum]->setResponse(&argv[2], argc - 2, output); + } + } + + else if (strcmp(argv[0], "section") == 0) { + if (argc > 1) { + + int sectionNum = atoi(argv[1]); + + if (sectionNum > 0 && sectionNum <= numSections && argc > 2) { + + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamInt->getSectionLocations(numSections, L, xi); + + output.tag("GaussPointOutput"); + output.attr("number", sectionNum); + output.attr("eta", xi[sectionNum - 1]*L); + + theResponse = theSections[sectionNum - 1]->setResponse(&argv[2], argc - 2, output); + + output.endTag(); + } else if (sectionNum == 0) { // argv[1] was not an int, we want all sections, + + CompositeResponse *theCResponse = new CompositeResponse(); + int numResponse = 0; + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamInt->getSectionLocations(numSections, L, xi); + + for (int i = 0; i < numSections; i++) { + + output.tag("GaussPointOutput"); + output.attr("number", i + 1); + output.attr("eta", xi[i]*L); + + Response *theSectionResponse = theSections[i]->setResponse(&argv[1], argc - 1, output); + + output.endTag(); + + if (theSectionResponse != 0) { + numResponse = theCResponse->addResponse(theSectionResponse); + } + } + + if (numResponse == 0) // no valid responses found + delete theCResponse; + else + theResponse = theCResponse; + } + } + } + // by SAJalali + else if (strcmp(argv[0], "energy") == 0) + { + return new ElementResponse(this, 13, 0.0); + } + + output.endTag(); + return theResponse; +} + +int +DispBeamColumn3dID::getResponse(int responseID, Information &eleInfo) +{ + double N, V, M1, M2, T; + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0 / L; + + if (responseID == 1) + return eleInfo.setVector(this->getResistingForce()); + + else if (responseID == 12) + return eleInfo.setVector(this->getRayleighDampingForces()); + + else if (responseID == 2) { + // Axial + N = q(0); + P(6) = N; + P(0) = -N + p0[0]; + + // Torsion + T = q(5); + P(9) = T; + P(3) = -T; + + // Moments about z and shears along y + M1 = q(1); + M2 = q(2); + P(5) = M1; + P(11) = M2; + V = (M1 + M2) * oneOverL; + P(1) = V + p0[1]; + P(7) = -V + p0[2]; + + // Moments about y and shears along z + M1 = q(3); + M2 = q(4); + P(4) = M1; + P(10) = M2; + V = (M1 + M2) * oneOverL; + P(2) = -V + p0[3]; + P(8) = V + p0[4]; + + return eleInfo.setVector(P); + } + + // Chord rotation + else if (responseID == 3) + return eleInfo.setVector(crdTransf->getBasicTrialDisp()); + + // Plastic rotation + else if (responseID == 4) { + static Vector vp(6); + static Vector ve(6); + const Matrix &kb = this->getInitialBasicStiff(); + kb.Solve(q, ve); + vp = crdTransf->getBasicTrialDisp(); + vp -= ve; + return eleInfo.setVector(vp); + } + + else if (responseID == 10) { + double L = crdTransf->getInitialLength(); + double pts[maxNumSections]; + beamInt->getSectionLocations(numSections, L, pts); + Vector locs(numSections); + for (int i = 0; i < numSections; i++) + locs(i) = pts[i] * L; + return eleInfo.setVector(locs); + } + + else if (responseID == 11) { + double L = crdTransf->getInitialLength(); + double wts[maxNumSections]; + beamInt->getSectionWeights(numSections, L, wts); + Vector weights(numSections); + for (int i = 0; i < numSections; i++) + weights(i) = wts[i] * L; + return eleInfo.setVector(weights); + } + //by SAJalali + else if (responseID == 13) { + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamInt->getSectionWeights(numSections, L, xi); + double energy = 0; + for (int i = 0; i < numSections; i++) { + energy += theSections[i]->getEnergy() * xi[i] * L; + } + return eleInfo.setDouble(energy); + } + + else + return -1; +} + +// AddingSensitivity:BEGIN /////////////////////////////////// +int +DispBeamColumn3dID::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc < 1) + return -1; + + // don't do anything if MaterialStageParameter calls this element + if (strcmp(argv[0], "updateMaterialStage") == 0) { + return -1; + } + + // If the parameter belongs to the element itself + if (strcmp(argv[0], "rho") == 0) { + param.setValue(rho); + return param.addObject(1, this); + } + + if (strstr(argv[0], "sectionX") != 0) { + if (argc < 3) + return -1; + + float sectionLoc = atof(argv[1]); + + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamInt->getSectionLocations(numSections, L, xi); + + sectionLoc /= L; + + float minDistance = fabs(xi[0] - sectionLoc); + int sectionNum = 0; + for (int i = 1; i < numSections; i++) { + if (fabs(xi[i] - sectionLoc) < minDistance) { + minDistance = fabs(xi[i] - sectionLoc); + sectionNum = i; + } + } + return theSections[sectionNum]->setParameter(&argv[2], argc - 2, param); + } + // If the parameter belongs to a section or lower + if (strstr(argv[0], "section") != 0) { + + if (argc < 3) + return -1; + + // Get section number + int sectionNum = atoi(argv[1]); + + if (sectionNum > 0 && sectionNum <= numSections) + return theSections[sectionNum - 1]->setParameter(&argv[2], argc - 2, param); + else + return -1; + } + + else if (strstr(argv[0], "integration") != 0) { + + if (argc < 2) + return -1; + + return beamInt->setParameter(&argv[1], argc - 1, param); + } + + // Default, send to every object + int ok = 0; + int result = 0; + + for (int i = 0; i < numSections; i++) { + ok = theSections[i]->setParameter(argv, argc, param); + if (ok != -1) + result = ok; + } + + ok = beamInt->setParameter(argv, argc, param); + if (ok != -1) + result = ok; + + return result; +} + +int +DispBeamColumn3dID::updateParameter (int parameterID, Information &info) +{ + if (parameterID == 1) { + rho = info.theDouble; + return 0; + } + else + return -1; +} + + + + +int +DispBeamColumn3dID::activateParameter(int passedParameterID) +{ + parameterID = passedParameterID; + + return 0; +} + +const Matrix & +DispBeamColumn3dID::getKiSensitivity(int gradNumber) +{ + K.Zero(); + return K; +} + +const Matrix & +DispBeamColumn3dID::getMassSensitivity(int gradNumber) +{ + K.Zero(); + + if (rho == 0.0 || parameterID != 1) + return K; + + double L = crdTransf->getInitialLength(); + if (cMass == 0) { + // lumped mass matrix + //double m = 0.5*rho*L; + double m = 0.5 * L; + K(0, 0) = K(1, 1) = K(2, 2) = K(6, 6) = K(7, 7) = K(8, 8) = m; + } else { + // consistent mass matrix + static Matrix ml(12, 12); + //double m = rho*L/420.0; + double m = L / 420.0; + ml(0, 0) = ml(6, 6) = m * 140.0; + ml(0, 6) = ml(6, 0) = m * 70.0; + //ml(3,3) = ml(9,9) = m*(Jx/A)*140.0; // CURRENTLY NO TORSIONAL MASS + //ml(3,9) = ml(9,3) = m*(Jx/A)*70.0; // CURRENTLY NO TORSIONAL MASS + + ml(2, 2) = ml(8, 8) = m * 156.0; + ml(2, 8) = ml(8, 2) = m * 54.0; + ml(4, 4) = ml(10, 10) = m * 4.0 * L * L; + ml(4, 10) = ml(10, 4) = -m * 3.0 * L * L; + ml(2, 4) = ml(4, 2) = -m * 22.0 * L; + ml(8, 10) = ml(10, 8) = -ml(2, 4); + ml(2, 10) = ml(10, 2) = m * 13.0 * L; + ml(4, 8) = ml(8, 4) = -ml(2, 10); + + ml(1, 1) = ml(7, 7) = m * 156.0; + ml(1, 7) = ml(7, 1) = m * 54.0; + ml(5, 5) = ml(11, 11) = m * 4.0 * L * L; + ml(5, 11) = ml(11, 5) = -m * 3.0 * L * L; + ml(1, 5) = ml(5, 1) = m * 22.0 * L; + ml(7, 11) = ml(11, 7) = -ml(1, 5); + ml(1, 11) = ml(11, 1) = -m * 13.0 * L; + ml(5, 7) = ml(7, 5) = -ml(1, 11); + + // transform local mass matrix to global system + K = crdTransf->getGlobalMatrixFromLocal(ml); + } + + return K; +} + + + +const Vector & +DispBeamColumn3dID::getResistingForceSensitivity(int gradNumber) +{ + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0 / L; + + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + //const Vector &wts = quadRule.getIntegrPointWeights(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + double wt[maxNumSections]; + beamInt->getSectionWeights(numSections, L, wt); + + // Zero for integration + static Vector dqdh(6); + dqdh.Zero(); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + //double xi6 = 6.0*pts(i,0); + double xi6 = 6.0 * xi[i]; + //double wti = wts(i); + double wti = wt[i]; + + // Get section stress resultant gradient + const Vector &dsdh = theSections[i]->getStressResultantSensitivity(gradNumber, true); + + // Perform numerical integration on internal force gradient + double sensi; + for (int j = 0; j < order; j++) { + sensi = dsdh(j) * wti; + switch (code(j)) { + case SECTION_RESPONSE_P: + dqdh(0) += sensi; + break; + case SECTION_RESPONSE_MZ: + dqdh(1) += (xi6 - 4.0) * sensi; + dqdh(2) += (xi6 - 2.0) * sensi; + break; + case SECTION_RESPONSE_MY: + dqdh(3) += (xi6 - 4.0) * sensi; + dqdh(4) += (xi6 - 2.0) * sensi; + break; + case SECTION_RESPONSE_T: + dqdh(5) += sensi; + break; + default: + break; + } + } + } + + // Transform forces + static Vector dp0dh(6); // No distributed loads + + P.Zero(); + + ////////////////////////////////////////////////////////////// + + if (crdTransf->isShapeSensitivity()) { + + // Perform numerical integration to obtain basic stiffness matrix + // Some extra declarations + static Matrix kbmine(6, 6); + kbmine.Zero(); + q.Zero(); + + double tmp; + + int j, k; + + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + //double xi6 = 6.0*pts(i,0); + double xi6 = 6.0 * xi[i]; + //double wti = wts(i); + double wti = wt[i]; + + const Vector &s = theSections[i]->getStressResultant(); + const Matrix &ks = theSections[i]->getSectionTangent(); + + Matrix ka(workArea, order, 6); + ka.Zero(); + + double si; + for (j = 0; j < order; j++) { + si = s(j) * wti; + switch (code(j)) { + case SECTION_RESPONSE_P: + q(0) += si; + for (k = 0; k < order; k++) { + ka(k, 0) += ks(k, j) * wti; + } + break; + case SECTION_RESPONSE_MZ: + q(1) += (xi6 - 4.0) * si; + q(2) += (xi6 - 2.0) * si; + for (k = 0; k < order; k++) { + tmp = ks(k, j) * wti; + ka(k, 1) += (xi6 - 4.0) * tmp; + ka(k, 2) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_MY: + q(3) += (xi6 - 4.0) * si; + q(4) += (xi6 - 2.0) * si; + for (k = 0; k < order; k++) { + tmp = ks(k, j) * wti; + ka(k, 3) += (xi6 - 4.0) * tmp; + ka(k, 4) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_T: + q(5) += si; + for (k = 0; k < order; k++) { + ka(k, 5) += ks(k, j) * wti; + } + break; + default: + break; + } + } + for (j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_P: + for (k = 0; k < 6; k++) { + kbmine(0, k) += ka(j, k); + } + break; + case SECTION_RESPONSE_MZ: + for (k = 0; k < 6; k++) { + tmp = ka(j, k); + kbmine(1, k) += (xi6 - 4.0) * tmp; + kbmine(2, k) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_MY: + for (k = 0; k < 6; k++) { + tmp = ka(j, k); + kbmine(3, k) += (xi6 - 4.0) * tmp; + kbmine(4, k) += (xi6 - 2.0) * tmp; + } + break; + case SECTION_RESPONSE_T: + for (k = 0; k < 6; k++) { + kbmine(5, k) += ka(j, k); + } + break; + default: + break; + } + } + } + + const Vector &A_u = crdTransf->getBasicTrialDisp(); + double dLdh = crdTransf->getdLdh(); + double d1overLdh = -dLdh / (L * L); + // a^T k_s dadh v + dqdh.addMatrixVector(1.0, kbmine, A_u, d1overLdh); + + // k dAdh u + const Vector &dAdh_u = crdTransf->getBasicTrialDispShapeSensitivity(); + dqdh.addMatrixVector(1.0, kbmine, dAdh_u, oneOverL); + + // dAdh^T q + P += crdTransf->getGlobalResistingForceShapeSensitivity(q, dp0dh, gradNumber); + } + + // A^T (dqdh + k dAdh u) + P += crdTransf->getGlobalResistingForce(dqdh, dp0dh); + + return P; +} + + + +// NEW METHOD +int +DispBeamColumn3dID::commitSensitivity(int gradNumber, int numGrads) +{ + // Get basic deformation and sensitivities + const Vector &v = crdTransf->getBasicTrialDisp(); + + static Vector dvdh(6); + dvdh = crdTransf->getBasicDisplSensitivity(gradNumber); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0 / L; + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + + // Some extra declarations + double d1oLdh = crdTransf->getd1overLdh(); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + Vector e(workArea, order); + + //double xi6 = 6.0*pts(i,0); + double xi6 = 6.0 * xi[i]; + + for (int j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_P: + e(j) = oneOverL * dvdh(0) + + d1oLdh * v(0); + break; + case SECTION_RESPONSE_MZ: + e(j) = oneOverL * ((xi6 - 4.0) * dvdh(1) + (xi6 - 2.0) * dvdh(2)) + + d1oLdh * ((xi6 - 4.0) * v(1) + (xi6 - 2.0) * v(2)); + break; + case SECTION_RESPONSE_MY: + e(j) = oneOverL * ((xi6 - 4.0) * dvdh(3) + (xi6 - 2.0) * dvdh(4)) + + d1oLdh * ((xi6 - 4.0) * v(3) + (xi6 - 2.0) * v(4)); + break; + case SECTION_RESPONSE_T: + e(j) = oneOverL * dvdh(5) + + d1oLdh * v(5); + break; + default: + e(j) = 0.0; + break; + } + } + + // Set the section deformations + theSections[i]->commitSensitivity(e, gradNumber, numGrads); + } + + return 0; +} + + +// AddingSensitivity:END ///////////////////////////////////////////// + + +void +DispBeamColumn3dID::onActivate() +{ + const Vector &d1 = theNodes[0]->getTrialDisp(); + const Vector &d2 = theNodes[1]->getTrialDisp(); + init_disp[0] = d1(0); + init_disp[1] = d1(1); + init_disp[2] = d1(2); + init_disp[3] = d2(0); + init_disp[4] = d2(1); + init_disp[5] = d2(2); + this->update(); +} + +void +DispBeamColumn3dID::onDeactivate() +{ + +} diff --git a/SRC/element/dispBeamColumn/DispBeamColumn3dID.h b/SRC/element/dispBeamColumn/DispBeamColumn3dID.h new file mode 100644 index 0000000000..b5d47029f5 --- /dev/null +++ b/SRC/element/dispBeamColumn/DispBeamColumn3dID.h @@ -0,0 +1,141 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// Written: Jose Abell +// Created: Aug 2019 +// +// Description: Extends DispBeamColumn3d so that it can take into +// account initial nodal displacements. This is needed in staged construction +// analysis. + +#ifndef DispBeamColumn3dID_h +#define DispBeamColumn3dID_h + +#ifndef _bool_h +#include "bool.h" +#endif + +#include +#include +#include +#include + +class Node; +class SectionForceDeformation; +class CrdTransf; +class BeamIntegration; +class Response; + +class DispBeamColumn3dID : public Element +{ +public: + DispBeamColumn3dID(int tag, int nd1, int nd2, + int numSections, SectionForceDeformation **s, + BeamIntegration &bi, CrdTransf &coordTransf, + double rho = 0.0, int cMass = 0); + DispBeamColumn3dID(); + ~DispBeamColumn3dID(); + + const char *getClassType(void) const {return "DispBeamColumn3dID";}; + + int getNumExternalNodes(void) const; + const ID &getExternalNodes(void); + Node **getNodePtrs(void); + + int getNumDOF(void); + void setDomain(Domain *theDomain); + + // public methods to set the state of the element + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + // public methods to obtain stiffness, mass, damping and residual information + int update(void); + const Matrix &getTangentStiff(void); + const Matrix &getInitialStiff(void); + const Matrix &getMass(void); + + void zeroLoad(); + int addLoad(ElementalLoad *theLoad, double loadFactor); + int addInertiaLoadToUnbalance(const Vector &accel); + + const Vector &getResistingForce(void); + const Vector &getResistingForceIncInertia(void); + + // public methods for element output + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker + &theBroker); + int displaySelf(Renderer &theViewer, int displayMode, float fact, const char **displayModes = 0, int numModes = 0); + void Print(OPS_Stream &s, int flag = 0); + + Response *setResponse(const char **argv, int argc, OPS_Stream &s); + int getResponse(int responseID, Information &eleInfo); + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int setParameter(const char **argv, int argc, Parameter ¶m); + int updateParameter(int parameterID, Information &info); + int activateParameter(int parameterID); + const Vector & getResistingForceSensitivity(int gradNumber); + const Matrix & getKiSensitivity(int gradNumber); + const Matrix & getMassSensitivity(int gradNumber); + int commitSensitivity(int gradNumber, int numGrads); + // AddingSensitivity:END /////////////////////////////////////////// + virtual void onActivate(); + virtual void onDeactivate(); + +protected: + +private: + const Matrix &getInitialBasicStiff(void); + + int numSections; + SectionForceDeformation **theSections; // pointer to the ND material objects + CrdTransf *crdTransf; // pointer to coordinate transformation object + + BeamIntegration *beamInt; + + ID connectedExternalNodes; // Tags of quad nodes + + Node *theNodes[2]; + + static Matrix K; // Element stiffness, damping, and mass Matrix + static Vector P; // Element resisting force vector + + Vector Q; // Applied nodal loads + Vector q; // Basic force + double q0[5]; // Fixed end forces in basic system (no torsion) + double p0[5]; // Reactions in basic system (no torsion) + + double init_disp[5]; // Initial displacements (from nodes at initialization) + + double rho; // Mass density per unit length + int cMass; // consistent mass flag + + int parameterID; + + enum {maxNumSections = 20}; + + static double workArea[]; +}; + +#endif + diff --git a/SRC/element/dispBeamColumn/Makefile b/SRC/element/dispBeamColumn/Makefile index 8162cdd8d7..9154ddf2bb 100644 --- a/SRC/element/dispBeamColumn/Makefile +++ b/SRC/element/dispBeamColumn/Makefile @@ -8,7 +8,8 @@ OBJS = DispBeamColumn2d.o \ DispBeamColumn2dWithSensitivity.o \ DispBeamColumn3dWithSensitivity.o \ AxEqDispBeamColumn2d.o \ - TimoshenkoBeamColumn2d.o + TimoshenkoBeamColumn2d.o \ + DispBeamColumn3dID.o all: $(OBJS) diff --git a/SRC/element/dispBeamColumnInt/LinearCrdTransf2dInt.cpp b/SRC/element/dispBeamColumnInt/LinearCrdTransf2dInt.cpp index 3bd11b42af..6b821692fc 100644 --- a/SRC/element/dispBeamColumnInt/LinearCrdTransf2dInt.cpp +++ b/SRC/element/dispBeamColumnInt/LinearCrdTransf2dInt.cpp @@ -2419,6 +2419,102 @@ LinearCrdTransf2dInt::getPointGlobalDisplFromBasic(double xi, const Vector &uxb) } +const Vector & + +LinearCrdTransf2dInt::getPointLocalDisplFromBasic(double xi, const Vector &uxb) + +{ + + // determine global displacements + + const Vector &disp1 = nodeIPtr->getTrialDisp(); + + const Vector &disp2 = nodeJPtr->getTrialDisp(); + + + + static Vector ug(6); + + for (int i = 0; i < 3; i++) + + { + + ug(i) = disp1(i); + + ug(i+3) = disp2(i); + + } + + + + // transform global end displacements to local coordinates + + static Vector ul(6); // total displacements + + + + ul(0) = cosTheta*ug(0) + sinTheta*ug(1); + + ul(1) = -sinTheta*ug(0) + cosTheta*ug(1); + + ul(2) = ug(2); + + ul(3) = cosTheta*ug(3) + sinTheta*ug(4); + + ul(4) = -sinTheta*ug(3) + cosTheta*ug(4); + + ul(5) = ug(5); + + + + if (nodeIOffset != 0) { + + double t02 = -cosTheta*nodeIOffset[1] + sinTheta*nodeIOffset[0]; + + double t12 = sinTheta*nodeIOffset[1] + cosTheta*nodeIOffset[0]; + + + + ul(0) += t02*ug(2); + + ul(1) += t12*ug(2); + + } + + + + if (nodeJOffset != 0) { + + double t35 = -cosTheta*nodeJOffset[1] + sinTheta*nodeJOffset[0]; + + double t45 = sinTheta*nodeJOffset[1] + cosTheta*nodeJOffset[0]; + + + + ul(3) += t35*ug(5); + + ul(4) += t45*ug(5); + + } + + + + // compute displacements at point xi, in local coordinates + + static Vector uxl(2); + + + + uxl(0) = uxb(0) + ul(0); + + uxl(1) = uxb(1) + (1-xi)*ul(1) + xi*ul(4); + + + + return uxl; + +} + void diff --git a/SRC/element/dispBeamColumnInt/LinearCrdTransf2dInt.h b/SRC/element/dispBeamColumnInt/LinearCrdTransf2dInt.h index d41c746c44..35e1e58389 100644 --- a/SRC/element/dispBeamColumnInt/LinearCrdTransf2dInt.h +++ b/SRC/element/dispBeamColumnInt/LinearCrdTransf2dInt.h @@ -98,6 +98,7 @@ class LinearCrdTransf2dInt: public CrdTransf // methods used in post-processing only const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); + const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps); private: int computeElemtLengthAndOrient(void); diff --git a/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp b/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp index 0d9dbc1ba7..6dc9677bb3 100644 --- a/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp +++ b/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp @@ -548,6 +548,7 @@ ElasticBeam2d::getTangentStiff(void) // determine q = kv + q0 q(0) = EAoverL*v(0); + kb.Zero(); kb(0,0) = EAoverL; if (release == 0) { double EIoverL2 = 2.0*I*EoverL; // 2EI/L @@ -587,7 +588,8 @@ ElasticBeam2d::getInitialStiff(void) double EoverL = E/L; double EAoverL = A*EoverL; // EA/L - + + kb.Zero(); kb(0,0) = EAoverL; if (release == 0) { double EIoverL2 = 2.0*I*EoverL; // 2EI/L diff --git a/SRC/element/elasticBeamColumn/ElasticBeam3d.cpp b/SRC/element/elasticBeamColumn/ElasticBeam3d.cpp index 62dc37a872..a99a96c096 100644 --- a/SRC/element/elasticBeamColumn/ElasticBeam3d.cpp +++ b/SRC/element/elasticBeamColumn/ElasticBeam3d.cpp @@ -58,7 +58,7 @@ void* OPS_ElasticBeam3d(void) { int numArgs = OPS_GetNumRemainingInputArgs(); if(numArgs < 10 && numArgs != 5) { - opserr<<"insufficient arguments:eleTag,iNode,jNode,A,E,G,J,Iy,Iz,transfTag\n"; + opserr<<"insufficient arguments:eleTag,iNode,jNode,or,transfTag\n"; return 0; } @@ -78,7 +78,9 @@ void* OPS_ElasticBeam3d(void) CrdTransf* theTrans = 0; double data[6]; int transfTag, secTag; - + int releasez = 0; + int releasey = 0; + if(numArgs == 5) { numData = 1; if(OPS_GetIntInput(&numData,&secTag) < 0) return 0; @@ -117,14 +119,28 @@ void* OPS_ElasticBeam3d(void) } } else if (theType == "-cMass") { cMass = 1; - } + } else if (theType == "-releasez") { + if (OPS_GetNumRemainingInputArgs() > 0) { + if (OPS_GetIntInput(&numData, &releasez) < 0) { + opserr << "WARNING: failed to get releasez"; + return 0; + } + } + } else if (theType == "-releasey") { + if (OPS_GetNumRemainingInputArgs() > 0) { + if (OPS_GetIntInput(&numData, &releasey) < 0) { + opserr << "WARNING: failed to get releasey"; + return 0; + } + } + } } if (theSection != 0) { - return new ElasticBeam3d(iData[0],iData[1],iData[2],theSection,*theTrans,mass,cMass); + return new ElasticBeam3d(iData[0],iData[1],iData[2],theSection,*theTrans,mass,cMass,releasez, releasey); } else { return new ElasticBeam3d(iData[0],data[0],data[1],data[2],data[3],data[4], - data[5],iData[1],iData[2],*theTrans, mass,cMass); + data[5],iData[1],iData[2],*theTrans, mass,cMass,releasez,releasey); } } @@ -132,7 +148,7 @@ void* OPS_ElasticBeam3d(void) ElasticBeam3d::ElasticBeam3d() :Element(0,ELE_TAG_ElasticBeam3d), A(0.0), E(0.0), G(0.0), Jx(0.0), Iy(0.0), Iz(0.0), rho(0.0), cMass(0), - Q(12), q(6), connectedExternalNodes(2), theCoordTransf(0) + Q(12), q(6), connectedExternalNodes(2), theCoordTransf(0), releasez(0), releasey(0) { // does nothing q0[0] = 0.0; @@ -154,10 +170,11 @@ ElasticBeam3d::ElasticBeam3d() ElasticBeam3d::ElasticBeam3d(int tag, double a, double e, double g, double jx, double iy, double iz, int Nd1, int Nd2, - CrdTransf &coordTransf, double r, int cm, int sectTag) + CrdTransf &coordTransf, double r, int cm, int relz, int rely) :Element(tag,ELE_TAG_ElasticBeam3d), - A(a), E(e), G(g), Jx(jx), Iy(iy), Iz(iz), rho(r), cMass(cm), sectionTag(sectTag), - Q(12), q(6), connectedExternalNodes(2), theCoordTransf(0) + A(a), E(e), G(g), Jx(jx), Iy(iy), Iz(iz), rho(r), cMass(cm), + Q(12), q(6), connectedExternalNodes(2), theCoordTransf(0), + releasez(relz), releasey(rely) { connectedExternalNodes(0) = Nd1; connectedExternalNodes(1) = Nd2; @@ -169,6 +186,12 @@ ElasticBeam3d::ElasticBeam3d(int tag, double a, double e, double g, exit(-1); } + // Make no release if input not 0, 1, 2, or 3 + if (releasez < 0 || releasez > 3) + releasez = 0; + if (releasey < 0 || releasey > 3) + releasey = 0; + q0[0] = 0.0; q0[1] = 0.0; q0[2] = 0.0; @@ -187,12 +210,12 @@ ElasticBeam3d::ElasticBeam3d(int tag, double a, double e, double g, } ElasticBeam3d::ElasticBeam3d(int tag, int Nd1, int Nd2, SectionForceDeformation *section, - CrdTransf &coordTransf, double r, int cm) + CrdTransf &coordTransf, double r, int cm, int relz, int rely) :Element(tag,ELE_TAG_ElasticBeam3d), - Q(12), q(6), connectedExternalNodes(2), theCoordTransf(0) + Q(12), q(6), connectedExternalNodes(2), theCoordTransf(0), + releasez(relz), releasey(rely) { if (section != 0) { - sectionTag = section->getTag(); E = 1.0; G = 1.0; Jx = 0.0; @@ -237,6 +260,12 @@ ElasticBeam3d::ElasticBeam3d(int tag, int Nd1, int Nd2, SectionForceDeformation exit(-1); } + // Make no release if input not 0, 1, 2, or 3 + if (releasez < 0 || releasez > 3) + releasez = 0; + if (releasey < 0 || releasey > 3) + releasey = 0; + q0[0] = 0.0; q0[1] = 0.0; q0[2] = 0.0; @@ -375,32 +404,69 @@ ElasticBeam3d::getTangentStiff(void) double oneOverL = 1.0/L; double EoverL = E*oneOverL; double EAoverL = A*EoverL; // EA/L - double EIzoverL2 = 2.0*Iz*EoverL; // 2EIz/L - double EIzoverL4 = 2.0*EIzoverL2; // 4EIz/L - double EIyoverL2 = 2.0*Iy*EoverL; // 2EIy/L - double EIyoverL4 = 2.0*EIyoverL2; // 4EIy/L - double GJoverL = G*Jx*oneOverL; // GJ/L + double GJoverL = G*Jx*oneOverL; // GJ/L q(0) = EAoverL*v(0); - q(1) = EIzoverL4*v(1) + EIzoverL2*v(2); - q(2) = EIzoverL2*v(1) + EIzoverL4*v(2); - q(3) = EIyoverL4*v(3) + EIyoverL2*v(4); - q(4) = EIyoverL2*v(3) + EIyoverL4*v(4); - q(5) = GJoverL*v(5); + q(5) = GJoverL*v(5); + kb.Zero(); + kb(0,0) = EAoverL; + kb(5,5) = GJoverL; + if (releasez == 0) { + double EIzoverL2 = 2.0*Iz*EoverL; // 2EIz/L + double EIzoverL4 = 2.0*EIzoverL2; // 4EIz/L + q(1) = EIzoverL4*v(1) + EIzoverL2*v(2); + q(2) = EIzoverL2*v(1) + EIzoverL4*v(2); + kb(1,1) = kb(2,2) = EIzoverL4; + kb(2,1) = kb(1,2) = EIzoverL2; + } + if (releasez == 1) { // release I + q(1) = 0.0; + double EIoverL3 = 3.0*Iz*EoverL; + q(2) = EIoverL3*v(2); + kb(2,2) = EIoverL3; + } + if (releasez == 2) { // release J + q(2) = 0.0; + double EIoverL3 = 3.0*Iz*EoverL; + q(1) = EIoverL3*v(1); + kb(1,1) = EIoverL3; + } + if (releasez == 3) { // release I and J + q(1) = 0.0; + q(2) = 0.0; + } + if (releasey == 0) { + double EIyoverL2 = 2.0*Iy*EoverL; // 2EIy/L + double EIyoverL4 = 2.0*EIyoverL2; // 4EIy/L + q(3) = EIyoverL4*v(3) + EIyoverL2*v(4); + q(4) = EIyoverL2*v(3) + EIyoverL4*v(4); + kb(3,3) = kb(4,4) = EIyoverL4; + kb(4,3) = kb(3,4) = EIyoverL2; + } + if (releasey == 1) { // release I + q(3) = 0.0; + double EIoverL3 = 3.0*Iy*EoverL; + q(4) = EIoverL3*v(4); + kb(4,4) = EIoverL3; + } + if (releasey == 2) { // release J + q(4) = 0.0; + double EIoverL3 = 3.0*Iy*EoverL; + q(3) = EIoverL3*v(3); + kb(3,3) = EIoverL3; + } + if (releasey == 3) { // release I and J + q(3) = 0.0; + q(4) = 0.0; + } + q(0) += q0[0]; q(1) += q0[1]; q(2) += q0[2]; q(3) += q0[3]; q(4) += q0[4]; - kb(0,0) = EAoverL; - kb(1,1) = kb(2,2) = EIzoverL4; - kb(2,1) = kb(1,2) = EIzoverL2; - kb(3,3) = kb(4,4) = EIyoverL4; - kb(4,3) = kb(3,4) = EIyoverL2; - kb(5,5) = GJoverL; - return theCoordTransf->getGlobalStiffMatrix(kb,q); } @@ -414,19 +480,37 @@ ElasticBeam3d::getInitialStiff(void) double oneOverL = 1.0/L; double EoverL = E*oneOverL; double EAoverL = A*EoverL; // EA/L - double EIzoverL2 = 2.0*Iz*EoverL; // 2EIz/L - double EIzoverL4 = 2.0*EIzoverL2; // 4EIz/L - double EIyoverL2 = 2.0*Iy*EoverL; // 2EIy/L - double EIyoverL4 = 2.0*EIyoverL2; // 4EIy/L - double GJoverL = G*Jx*oneOverL; // GJ/L - + double GJoverL = G*Jx*oneOverL; // GJ/L + + kb.Zero(); kb(0,0) = EAoverL; - kb(1,1) = kb(2,2) = EIzoverL4; - kb(2,1) = kb(1,2) = EIzoverL2; - kb(3,3) = kb(4,4) = EIyoverL4; - kb(4,3) = kb(3,4) = EIyoverL2; kb(5,5) = GJoverL; - + if (releasez == 0) { + double EIzoverL2 = 2.0*Iz*EoverL; // 2EIz/L + double EIzoverL4 = 2.0*EIzoverL2; // 4EIz/L + kb(1,1) = kb(2,2) = EIzoverL4; + kb(2,1) = kb(1,2) = EIzoverL2; + } + if (releasez == 1) { // release I + kb(2,2) = 3.0*Iz*EoverL; + } + if (releasez == 2) { // release J + kb(1,1) = 3.0*Iz*EoverL; + } + + if (releasey == 0) { + double EIyoverL2 = 2.0*Iy*EoverL; // 2EIy/L + double EIyoverL4 = 2.0*EIyoverL2; // 4EIy/L + kb(3,3) = kb(4,4) = EIyoverL4; + kb(4,3) = kb(3,4) = EIyoverL2; + } + if (releasey == 1) { // release I + kb(4,4) = 3.0*Iy*EoverL; + } + if (releasey == 2) { // release J + kb(3,3) = 3.0*Iy*EoverL; + } + return theCoordTransf->getInitialGlobalStiffMatrix(kb); } @@ -529,10 +613,28 @@ ElasticBeam3d::addLoad(ElementalLoad *theLoad, double loadFactor) // Fixed end forces in basic system q0[0] -= 0.5*P; - q0[1] -= Mz; - q0[2] += Mz; - q0[3] += My; - q0[4] -= My; + if (releasez == 0) { + q0[1] -= Mz; + q0[2] += Mz; + } + if (releasez == 1) { + q0[2] += wy*L*L/8; + } + if (releasez == 2) { + q0[1] -= wy*L*L/8; + } + + if (releasey == 0) { + q0[3] += My; + q0[4] -= My; + } + if (releasey == 1) { + q[4] -= wz*L*L/8; + } + if (releasey == 2) { + q[3] += wz*L*L/8; + } + } else if (type == LOAD_TAG_Beam3dPartialUniformLoad) { double wa = data(2) * loadFactor; // Axial @@ -719,18 +821,50 @@ ElasticBeam3d::getResistingForce() double oneOverL = 1.0/L; double EoverL = E*oneOverL; double EAoverL = A*EoverL; // EA/L - double EIzoverL2 = 2.0*Iz*EoverL; // 2EIz/L - double EIzoverL4 = 2.0*EIzoverL2; // 4EIz/L double EIyoverL2 = 2.0*Iy*EoverL; // 2EIy/L double EIyoverL4 = 2.0*EIyoverL2; // 4EIy/L double GJoverL = G*Jx*oneOverL; // GJ/L q(0) = EAoverL*v(0); - q(1) = EIzoverL4*v(1) + EIzoverL2*v(2); - q(2) = EIzoverL2*v(1) + EIzoverL4*v(2); - q(3) = EIyoverL4*v(3) + EIyoverL2*v(4); - q(4) = EIyoverL2*v(3) + EIyoverL4*v(4); q(5) = GJoverL*v(5); + + if (releasez == 0) { + double EIzoverL2 = 2.0*Iz*EoverL; // 2EIz/L + double EIzoverL4 = 2.0*EIzoverL2; // 4EIz/L + q(1) = EIzoverL4*v(1) + EIzoverL2*v(2); + q(2) = EIzoverL2*v(1) + EIzoverL4*v(2); + } + if (releasez == 1) { + q(1) = 0.0; + q(2) = 3.0*Iz*EoverL*v(2); + } + if (releasez == 2) { + q(1) = 3.0*Iz*EoverL*v(1); + q(2) = 0.0; + } + if (releasez == 3) { + q(1) = 0.0; + q(2) = 0.0; + } + + if (releasey == 0) { + double EIyoverL2 = 2.0*Iy*EoverL; // 2EIy/L + double EIyoverL4 = 2.0*EIyoverL2; // 4EIy/L + q(3) = EIyoverL4*v(3) + EIyoverL2*v(4); + q(4) = EIyoverL2*v(3) + EIyoverL4*v(4); + } + if (releasey == 1) { + q(3) = 0.0; + q(4) = 3.0*Iy*EoverL*v(4); + } + if (releasey == 2) { + q(3) = 3.0*Iy*EoverL*v(3); + q(4) = 0.0; + } + if (releasey == 3) { + q(3) = 0.0; + q(4) = 0.0; + } q(0) += q0[0]; q(1) += q0[1]; @@ -756,7 +890,7 @@ ElasticBeam3d::sendSelf(int cTag, Channel &theChannel) { int res = 0; - static Vector data(17); + static Vector data(19); data(0) = A; data(1) = E; @@ -785,6 +919,8 @@ ElasticBeam3d::sendSelf(int cTag, Channel &theChannel) data(14) = betaK; data(15) = betaK0; data(16) = betaKc; + data(17) = releasez; + data(18) = releasey; // Send the data vector res += theChannel.sendVector(this->getDbTag(), cTag, data); @@ -807,7 +943,7 @@ int ElasticBeam3d::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker) { int res = 0; - static Vector data(17); + static Vector data(19); res += theChannel.recvVector(this->getDbTag(), cTag, data); if (res < 0) { @@ -831,6 +967,8 @@ ElasticBeam3d::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBrok betaK = data(14); betaK0 = data(15); betaKc = data(16); + releasez = (int)data(17); + releasey = (int)data(18); // Check if the CoordTransf is null; if so, get a new one int crdTag = (int)data(11); @@ -872,7 +1010,6 @@ ElasticBeam3d::Print(OPS_Stream &s, int flag) if (flag == -1) { int eleTag = this->getTag(); s << "EL_BEAM\t" << eleTag << "\t"; - s << sectionTag << "\t" << sectionTag; s << "\t" << connectedExternalNodes(0) << "\t" << connectedExternalNodes(1); s << "\t0\t0.0000000\n"; } @@ -959,7 +1096,8 @@ ElasticBeam3d::Print(OPS_Stream &s, int flag) s << "\tConnected Nodes: " << connectedExternalNodes; s << "\tCoordTransf: " << theCoordTransf->getTag() << endln; s << "\tmass density: " << rho << ", cMass: " << cMass << endln; - + s << "\trelease about z: " << releasez << endln; + s << "\trelease about y: " << releasey << endln; double N, Mz1, Mz2, Vy, My1, My2, Vz, T; double L = theCoordTransf->getInitialLength(); double oneOverL = 1.0 / L; @@ -991,6 +1129,8 @@ ElasticBeam3d::Print(OPS_Stream &s, int flag) s << "\"Iy\": " << Iy << ", "; s << "\"Iz\": " << Iz << ", "; s << "\"massperlength\": " << rho << ", "; + s << "\"releasez\": "<< releasez << ", "; + s << "\"releasey\": "<< releasey << ", "; s << "\"crdTransformation\": \"" << theCoordTransf->getTag() << "\"}"; } } @@ -1128,7 +1268,17 @@ ElasticBeam3d::setResponse(const char **argv, int argc, OPS_Stream &output) output.tag("ResponseType","theta22"); output.tag("ResponseType","phi"); theResponse = new ElementResponse(this, 5, Vector(6)); - } + } + + else if (strcmp(argv[0],"xaxis") == 0 || strcmp(argv[0],"xlocal") == 0) + theResponse = new ElementResponse(this, 201, Vector(3)); + + else if (strcmp(argv[0],"yaxis") == 0 || strcmp(argv[0],"ylocal") == 0) + theResponse = new ElementResponse(this, 202, Vector(3)); + + else if (strcmp(argv[0],"zaxis") == 0 || strcmp(argv[0],"zlocal") == 0) + theResponse = new ElementResponse(this, 203, Vector(3)); + output.endTag(); // ElementOutput return theResponse; @@ -1189,8 +1339,25 @@ ElasticBeam3d::getResponse (int responseID, Information &eleInfo) return eleInfo.setVector(theCoordTransf->getBasicTrialDisp()); default: - return -1; + break; } + + if (responseID >= 201 && responseID <= 203) { + static Vector xlocal(3); + static Vector ylocal(3); + static Vector zlocal(3); + + theCoordTransf->getLocalAxes(xlocal,ylocal,zlocal); + + if (responseID == 201) + return eleInfo.setVector(xlocal); + if (responseID == 202) + return eleInfo.setVector(ylocal); + if (responseID == 203) + return eleInfo.setVector(zlocal); + } + + return -1; } @@ -1201,29 +1368,45 @@ ElasticBeam3d::setParameter(const char **argv, int argc, Parameter ¶m) return -1; // E of the beam interior - if (strcmp(argv[0],"E") == 0) + if (strcmp(argv[0],"E") == 0) { + param.setValue(E); return param.addObject(1, this); - + } // A of the beam interior - if (strcmp(argv[0],"A") == 0) + if (strcmp(argv[0],"A") == 0) { + param.setValue(A); return param.addObject(2, this); - + } // Iz of the beam interior - if (strcmp(argv[0],"Iz") == 0) + if (strcmp(argv[0],"Iz") == 0) { + param.setValue(Iz); return param.addObject(3, this); - + } // Iy of the beam interior - if (strcmp(argv[0],"Iy") == 0) + if (strcmp(argv[0],"Iy") == 0) { + param.setValue(Iy); return param.addObject(4, this); - + } // G of the beam interior - if (strcmp(argv[0],"G") == 0) + if (strcmp(argv[0],"G") == 0) { + param.setValue(G); return param.addObject(5, this); - + } // J of the beam interior - if (strcmp(argv[0],"J") == 0) + if (strcmp(argv[0],"J") == 0) { + param.setValue(Jx); return param.addObject(6, this); - + } + // moment release + if (strcmp(argv[0],"releasez") == 0) { + param.setValue(releasez); + return param.addObject(7, this); + } + if (strcmp(argv[0],"releasey") == 0) { + param.setValue(releasey); + return param.addObject(8, this); + } + return -1; } @@ -1251,6 +1434,16 @@ ElasticBeam3d::updateParameter (int parameterID, Information &info) case 6: Jx = info.theDouble; return 0; + case 7: + releasez = (int)info.theDouble; + if (releasez < 0 || releasez > 3) + releasez = 0; + return 0; + case 8: + releasey = (int)info.theDouble; + if (releasey < 0 || releasey > 3) + releasey = 0; + return 0; default: return -1; } diff --git a/SRC/element/elasticBeamColumn/ElasticBeam3d.h b/SRC/element/elasticBeamColumn/ElasticBeam3d.h index f903b71039..eb7ddf6183 100644 --- a/SRC/element/elasticBeamColumn/ElasticBeam3d.h +++ b/SRC/element/elasticBeamColumn/ElasticBeam3d.h @@ -52,10 +52,11 @@ class ElasticBeam3d : public Element double Jx, double Iy, double Iz, int Nd1, int Nd2, CrdTransf &theTransf, double rho = 0.0, int cMass = 0, - int sectionTag = 0); + int releasez = 0, int releasey = 0); ElasticBeam3d(int tag, int Nd1, int Nd2, SectionForceDeformation *section, - CrdTransf &theTransf, double rho = 0.0, int cMass = 0); + CrdTransf &theTransf, double rho = 0.0, int cMass = 0, + int releasez = 0, int releasey = 0); ~ElasticBeam3d(); @@ -101,8 +102,10 @@ class ElasticBeam3d : public Element double rho; int cMass; - int sectionTag; + int releasez; // moment release for bending about z-axis 0=none, 1=I, 2=J, 3=I,J + int releasey; // same for y-axis + static Matrix K; static Vector P; Vector Q; diff --git a/SRC/element/elasticBeamColumn/WheelRail.cpp b/SRC/element/elasticBeamColumn/WheelRail.cpp index d6ab9c8859..4d5d5c200a 100644 --- a/SRC/element/elasticBeamColumn/WheelRail.cpp +++ b/SRC/element/elasticBeamColumn/WheelRail.cpp @@ -1,4 +1,4 @@ -/*/ +/* Written by: Quan Gu_1, Yongdou Liu_1, Wei Guo_23, Weiquan Li_1, Zhiwu Yu_23, Lizhong Jiang_23 and Hanyun Liu_2 (1.School of Architecture and Civil Engineering, Xiamen University, 361005, China; 2.School of Civil Engineering, Central South University, 410075, China; @@ -41,60 +41,78 @@ Vector WheelRail::contactData(7); Vector WheelRail::localActiveForce(5); Vector WheelRail::activeData(7); -WheelRail::WheelRail(int pTag, double pDeltT, double pVel, double pInitLocation, int pNd1, - double pRWheel,double pI,double pE,double pA,CrdTransf *pCoordTransf,int pnLoad, - Vector * pNodeList, Vector * pDeltaYList,Vector * pDeltaYLocationList) - :Element(pTag,ELE_TAG_WheelRail),P(0), - theTangent(0),connectedExternalNodes(0),activeDof(5), - rearRailNode(2),frontRailNode(2),railDisp(3), shapFun1(2),shapFun2(4) +WheelRail::WheelRail(int pTag, + double pDeltT, + double pVel, + double pInitLocation, + int pNd1, + double pRWheel, + double pI, + double pE, + double pA, + CrdTransf *pCoordTransf, + int pnLoad, + Vector *pNodeList, + Vector *pDeltaYList, + Vector *pDeltaYLocationList) + :Element(pTag,ELE_TAG_WheelRail), + P(0), + theTangent(0), + activeDof(5), + shapFun1(2), + shapFun2(4), + rearRailNode(2), + frontRailNode(2), + railDisp(3) { -//-----------members in the construtor list----------------------- - deltT = pDeltT; - vel = pVel; - initLocation = pInitLocation; - wheelNodeNum = pNd1; // ÂÖ½Úµã±àºÅ - - rollingRadiusWheel=pRWheel; - I=pI; - E=pE; - A=pA;// useless and should be deleted. - - theCoordTransf= pCoordTransf; - //theCoordTransf = theCoordTransf.getCopy2d(); - nLoad=pnLoad; - - if (pNodeList !=0){ - theNodeList = new Vector(*pNodeList); - } - if ((pDeltaYList !=0)&&((pDeltaYLocationList !=0))){ - theDeltaYList = new Vector(*pDeltaYList); - theDeltaYLocationList=new Vector(*pDeltaYLocationList); - } - - numRailNodeList=pNodeList->Size(); - theNumOfDeltaYList=(*theDeltaYList).Size(); - - this->connectedExternalNodes.resize(numRailNodeList+1); - connectedExternalNodes(0) = pNd1; - for(int i=1;iP=new Vector((numRailNodeList+1)*3); - P->Zero(); + // + //-----------members in the construtor list----------------------- - this->theTangent = new Matrix( (numRailNodeList+1)*3,(numRailNodeList+1)*3); - theTangent->Zero(); - - currentLocation = initLocation; - this->getDeltaY(); - - Fhz = 0.0; - G=4.57*1.0e-8*pow(rollingRadiusWheel,-0.149); - - deltaU = 0; - uF = 0; + deltT = pDeltT; + vel = pVel; + initLocation = pInitLocation; + wheelNodeNum = pNd1; + + rollingRadiusWheel=pRWheel; + I=pI; + E=pE; + A=pA;// useless and should be deleted. + + theCoordTransf= pCoordTransf; + //theCoordTransf = theCoordTransf.getCopy2d(); + nLoad=pnLoad; + + if (pNodeList !=0){ + theNodeList = new Vector(*pNodeList); + } + if ((pDeltaYList !=0)&&((pDeltaYLocationList !=0))){ + theDeltaYList = new Vector(*pDeltaYList); + theDeltaYLocationList=new Vector(*pDeltaYLocationList); + } - loadStep = 1; + numRailNodeList=pNodeList->Size(); + theNumOfDeltaYList=(*theDeltaYList).Size(); + + this->connectedExternalNodes.resize(numRailNodeList+1); + connectedExternalNodes(0) = pNd1; + for(int i=1;iP=new Vector((numRailNodeList+1)*3); + P->Zero(); + + this->theTangent = new Matrix( (numRailNodeList+1)*3,(numRailNodeList+1)*3); + theTangent->Zero(); + + currentLocation = initLocation; + this->getDeltaY(); + + Fhz = 0.0; + G=4.57*1.0e-8*pow(rollingRadiusWheel,-0.149); + + deltaU = 0; + uF = 0; + loadStep = 1; } WheelRail::~WheelRail() @@ -541,7 +559,6 @@ void WheelRail::NewtonBisection(Vector limits,double uWheel){ double FHzi=0.5*(FHL+FHH); double dDeltaUi=0,dDeltaU=0; double R = pow(a*b,3.0)/3/E/I/theEleLength/theEleLength/theEleLength; - double dUbaldFH=0; int i=0; bool converge=false; while (isetSectionPointers(numSec, sec); - - if (vsSubdivide == 0) - vsSubdivide = new Vector [maxNumSections]; - if (fsSubdivide == 0) - fsSubdivide = new Matrix [maxNumSections]; - if (SsrSubdivide == 0) - SsrSubdivide = new Vector [maxNumSections]; - if (!vsSubdivide || !fsSubdivide || !SsrSubdivide) { - opserr << "ForceBeamColumn2d::ForceBeamColumn2d() -- failed to allocate Subdivide arrays"; - exit(-1); - } } // ~ForceBeamColumn2d(): @@ -2649,6 +2627,12 @@ ForceBeamColumn2d::setResponse(const char **argv, int argc, OPS_Stream &output) else if (strcmp(argv[0],"integrationWeights") == 0) theResponse = new ElementResponse(this, 11, Vector(numSections)); + else if (strcmp(argv[0],"sectionDisplacements") == 0) + theResponse = new ElementResponse(this, 111, Matrix(numSections,3)); + + else if (strcmp(argv[0],"cbdiDisplacements") == 0) + theResponse = new ElementResponse(this, 112, Matrix(20,3)); + else if (strcmp(argv[0],"RayleighForces") == 0 || strcmp(argv[0],"rayleighForces") ==0 || strcmp(argv[0],"dampingForces") == 0) { output.tag("ResponseType","Px_1"); @@ -2923,6 +2907,81 @@ ForceBeamColumn2d::getResponse(int responseID, Information &eleInfo) weights(i) = wts[i]*L; return eleInfo.setVector(weights); } + + else if (responseID == 111) { + double L = crdTransf->getInitialLength(); + double pts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, pts); + // CBDI influence matrix + Matrix ls(numSections, numSections); + getCBDIinfluenceMatrix(numSections, pts, L, ls); + // Curvature vector + Vector kappa(numSections); + for (int i = 0; i < numSections; i++) { + const ID &code = sections[i]->getType(); + const Vector &e = sections[i]->getSectionDeformation(); + int order = sections[i]->getOrder(); + for (int j = 0; j < order; j++) + if (code(j) == SECTION_RESPONSE_MZ) + kappa(i) += e(j); + } + // Displacement vector + Vector dispsy(numSections); + dispsy.addMatrixVector(0.0, ls, kappa, 1.0); + beamIntegr->getSectionLocations(numSections, L, pts); + static Vector uxb(2); + static Vector uxg(2); + Matrix disps(numSections,3); + vp = crdTransf->getBasicTrialDisp(); + for (int i = 0; i < numSections; i++) { + uxb(0) = pts[i]*vp(0); // linear shape function + uxb(1) = dispsy(i); + uxg = crdTransf->getPointGlobalDisplFromBasic(pts[i],uxb); + disps(i,0) = uxg(0); + disps(i,1) = uxg(1); + disps(i,2) = 0.0; + } + return eleInfo.setMatrix(disps); + } + + else if (responseID == 112) { + double L = crdTransf->getInitialLength(); + double ipts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, ipts); + // CBDI influence matrix + double pts[20]; + for (int i = 0; i < 20; i++) + pts[i] = 1.0/(20-1)*i; + Matrix ls(20, numSections); + getCBDIinfluenceMatrix(20, pts, numSections, ipts, L, ls); + // Curvature vector + Vector kappa(numSections); + for (int i = 0; i < numSections; i++) { + const ID &code = sections[i]->getType(); + const Vector &e = sections[i]->getSectionDeformation(); + int order = sections[i]->getOrder(); + for (int j = 0; j < order; j++) + if (code(j) == SECTION_RESPONSE_MZ) + kappa(i) += e(j); + } + // Displacement vector + Vector dispsy(20); + dispsy.addMatrixVector(0.0, ls, kappa, 1.0); + static Vector uxb(2); + static Vector uxg(2); + Matrix disps(20,3); + vp = crdTransf->getBasicTrialDisp(); + for (int i = 0; i < 20; i++) { + uxb(0) = pts[i]*vp(0); // linear shape function + uxb(1) = dispsy(i); + uxg = crdTransf->getPointGlobalDisplFromBasic(pts[i],uxb); + disps(i,0) = uxg(0); + disps(i,1) = uxg(1); + disps(i,2) = 0.0; + } + return eleInfo.setMatrix(disps); + } + //by SAJalali else if (responseID == 14) { double xi[maxNumSections]; diff --git a/SRC/element/forceBeamColumn/ForceBeamColumn2d.h b/SRC/element/forceBeamColumn/ForceBeamColumn2d.h index 9a185fd32e..6b276c1100 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumn2d.h +++ b/SRC/element/forceBeamColumn/ForceBeamColumn2d.h @@ -208,9 +208,9 @@ class ForceBeamColumn2d: public Element // following are added for subdivision of displacement increment int maxSubdivisions; // maximum number of subdivisons of dv for local iterations - static Vector *vsSubdivide; - static Vector *SsrSubdivide; - static Matrix *fsSubdivide; + static Vector vsSubdivide[]; + static Vector SsrSubdivide[]; + static Matrix fsSubdivide[]; //static int maxNumSections; // AddingSensitivity:BEGIN ////////////////////////////////////////// diff --git a/SRC/element/forceBeamColumn/ForceBeamColumn2dThermal.cpp b/SRC/element/forceBeamColumn/ForceBeamColumn2dThermal.cpp index 4cf1681535..c31b0a9753 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumn2dThermal.cpp +++ b/SRC/element/forceBeamColumn/ForceBeamColumn2dThermal.cpp @@ -87,9 +87,9 @@ Matrix ForceBeamColumn2dThermal::theMatrix(6,6); Vector ForceBeamColumn2dThermal::theVector(6); double ForceBeamColumn2dThermal::workArea[200]; -Vector *ForceBeamColumn2dThermal::vsSubdivide = 0; -Matrix *ForceBeamColumn2dThermal::fsSubdivide = 0; -Vector *ForceBeamColumn2dThermal::SsrSubdivide = 0; +Vector ForceBeamColumn2dThermal::vsSubdivide[maxNumSections]; +Matrix ForceBeamColumn2dThermal::fsSubdivide[maxNumSections]; +Vector ForceBeamColumn2dThermal::SsrSubdivide[maxNumSections]; void* OPS_ForceBeamColumn2dThermal() { @@ -173,17 +173,6 @@ ForceBeamColumn2dThermal::ForceBeamColumn2dThermal(): { theNodes[0] = 0; theNodes[1] = 0; - - if (vsSubdivide == 0) - vsSubdivide = new Vector [maxNumSections]; - if (fsSubdivide == 0) - fsSubdivide = new Matrix [maxNumSections]; - if (SsrSubdivide == 0) - SsrSubdivide = new Vector [maxNumSections]; - if (!vsSubdivide || !fsSubdivide || !SsrSubdivide) { - opserr << "ForceBeamColumn2dThermal::ForceBeamColumn2dThermal() -- failed to allocate Subdivide arrays"; - exit(-1); - } } // constructor which takes the unique element tag, sections, @@ -228,17 +217,6 @@ ForceBeamColumn2dThermal::ForceBeamColumn2dThermal (int tag, int nodeI, int node if(Vsth0==0) Vsth0 = new Vector[maxNumSections]; - if (vsSubdivide == 0) - vsSubdivide = new Vector [maxNumSections]; - if (fsSubdivide == 0) - fsSubdivide = new Matrix [maxNumSections]; - if (SsrSubdivide == 0) - SsrSubdivide = new Vector [maxNumSections]; - if (!vsSubdivide || !fsSubdivide || !SsrSubdivide) { - opserr << "ForceBeamColumn2dThermal::ForceBeamColumn2dThermal() -- failed to allocate Subdivide arrays"; - exit(-1); - } - for (int m=0; msetSectionPointers(numSec, sec); - - if (vsSubdivide == 0) - vsSubdivide = new Vector [maxNumSections]; - if (fsSubdivide == 0) - fsSubdivide = new Matrix [maxNumSections]; - if (SsrSubdivide == 0) - SsrSubdivide = new Vector [maxNumSections]; - if (!vsSubdivide || !fsSubdivide || !SsrSubdivide) { - opserr << "ForceBeamColumn3d::ForceBeamColumn3d() -- failed to allocate Subdivide arrays"; - exit(-1); - } } // ~ForceBeamColumn3d(): @@ -2701,7 +2679,7 @@ ForceBeamColumn3d::getInitialDeformations(Vector &v0) // tangent drift } else if (strcmp(argv[0],"tangentDrift") == 0) { theResponse = new ElementResponse(this, 6, Vector(4)); - + } else if (strcmp(argv[0],"getRemCriteria1") == 0) { theResponse = new ElementResponse(this, 7, Vector(2)); @@ -2744,8 +2722,27 @@ ForceBeamColumn3d::getInitialDeformations(Vector &v0) else if (strcmp(argv[0],"integrationWeights") == 0) theResponse = new ElementResponse(this, 11, Vector(numSections)); + + else if (strcmp(argv[0],"sectionDisplacements") == 0) { + if (argc > 1 && strcmp(argv[1],"local") == 0) + theResponse = new ElementResponse(this, 1111, Matrix(numSections,3)); + else + theResponse = new ElementResponse(this, 111, Matrix(numSections,3)); + } - else if (strcmp(argv[0],"section") ==0) { + else if (strcmp(argv[0],"cbdiDisplacements") == 0) + theResponse = new ElementResponse(this, 112, Matrix(20,3)); + + else if (strcmp(argv[0],"xaxis") == 0 || strcmp(argv[0],"xlocal") == 0) + theResponse = new ElementResponse(this, 201, Vector(3)); + + else if (strcmp(argv[0],"yaxis") == 0 || strcmp(argv[0],"ylocal") == 0) + theResponse = new ElementResponse(this, 202, Vector(3)); + + else if (strcmp(argv[0],"zaxis") == 0 || strcmp(argv[0],"zlocal") == 0) + theResponse = new ElementResponse(this, 203, Vector(3)); + + else if (strstr(argv[0],"section") != 0) { if (argc > 1) { @@ -2893,6 +2890,112 @@ ForceBeamColumn3d::getResponse(int responseID, Information &eleInfo) return eleInfo.setVector(weights); } + else if (responseID == 111 || responseID == 1111) { + double L = crdTransf->getInitialLength(); + double pts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, pts); + // CBDI influence matrix + Matrix ls(numSections, numSections); + getCBDIinfluenceMatrix(numSections, pts, L, ls); + // Curvature vector + Vector kappaz(numSections); // about section z + Vector kappay(numSections); // about section y + for (int i = 0; i < numSections; i++) { + const ID &code = sections[i]->getType(); + const Vector &e = sections[i]->getSectionDeformation(); + int order = sections[i]->getOrder(); + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + kappaz(i) += e(j); + if (code(j) == SECTION_RESPONSE_MY) + kappay(i) += e(j); + } + } + // Displacement vector + Vector dispsy(numSections); // along local y + Vector dispsz(numSections); // along local z + dispsy.addMatrixVector(0.0, ls, kappaz, 1.0); + dispsz.addMatrixVector(0.0, ls, kappay, -1.0); + beamIntegr->getSectionLocations(numSections, L, pts); + static Vector uxb(3); + static Vector uxg(3); + Matrix disps(numSections,3); + vp = crdTransf->getBasicTrialDisp(); + for (int i = 0; i < numSections; i++) { + uxb(0) = pts[i]*vp(0); // linear shape function + uxb(1) = dispsy(i); + uxb(2) = dispsz(i); + if (responseID == 111) + uxg = crdTransf->getPointGlobalDisplFromBasic(pts[i],uxb); + else + uxg = crdTransf->getPointLocalDisplFromBasic(pts[i],uxb); + disps(i,0) = uxg(0); + disps(i,1) = uxg(1); + disps(i,2) = uxg(2); + } + return eleInfo.setMatrix(disps); + } + + else if (responseID == 112) { + double L = crdTransf->getInitialLength(); + double ipts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, ipts); + // CBDI influence matrix + double pts[20]; + for (int i = 0; i < 20; i++) + pts[i] = 1.0/(20-1)*i; + Matrix ls(20, numSections); + getCBDIinfluenceMatrix(20, pts, numSections, ipts, L, ls); + // Curvature vector + Vector kappaz(numSections); // about section z + Vector kappay(numSections); // about section y + for (int i = 0; i < numSections; i++) { + const ID &code = sections[i]->getType(); + const Vector &e = sections[i]->getSectionDeformation(); + int order = sections[i]->getOrder(); + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + kappaz(i) += e(j); + if (code(j) == SECTION_RESPONSE_MY) + kappay(i) += e(j); + } + } + // Displacement vector + Vector dispsy(20); // along local y + Vector dispsz(20); // along local z + dispsy.addMatrixVector(0.0, ls, kappaz, 1.0); + dispsz.addMatrixVector(0.0, ls, kappay, -1.0); + static Vector uxb(3); + static Vector uxg(3); + Matrix disps(20,3); + vp = crdTransf->getBasicTrialDisp(); + for (int i = 0; i < 20; i++) { + uxb(0) = pts[i]*vp(0); // linear shape function + uxb(1) = dispsy(i); + uxb(2) = dispsz(i); + uxg = crdTransf->getPointGlobalDisplFromBasic(pts[i],uxb); + disps(i,0) = uxg(0); + disps(i,1) = uxg(1); + disps(i,2) = uxg(2); + } + return eleInfo.setMatrix(disps); + } + + else if (responseID >= 201 && responseID <= 203) { + static Vector xlocal(3); + static Vector ylocal(3); + static Vector zlocal(3); + + crdTransf->getLocalAxes(xlocal,ylocal,zlocal); + + if (responseID == 201) + return eleInfo.setVector(xlocal); + if (responseID == 202) + return eleInfo.setVector(ylocal); + if (responseID == 203) + return eleInfo.setVector(zlocal); + } + else if (responseID == 12) return eleInfo.setVector(this->getRayleighDampingForces()); diff --git a/SRC/element/forceBeamColumn/ForceBeamColumn3d.h b/SRC/element/forceBeamColumn/ForceBeamColumn3d.h index 2351ac4414..70631f2b25 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumn3d.h +++ b/SRC/element/forceBeamColumn/ForceBeamColumn3d.h @@ -209,9 +209,9 @@ class ForceBeamColumn3d: public Element // following are added for subdivision of displacement increment int maxSubdivisions; // maximum number of subdivisons of dv for local iterations - static Vector *vsSubdivide; - static Vector *SsrSubdivide; - static Matrix *fsSubdivide; + static Vector vsSubdivide[]; + static Vector SsrSubdivide[]; + static Matrix fsSubdivide[]; //static int maxNumSections; // AddingSensitivity:BEGIN ////////////////////////////////////////// diff --git a/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.cpp b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.cpp index 2e630b1033..b99155d6f2 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.cpp +++ b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.cpp @@ -83,9 +83,9 @@ Matrix ForceBeamColumnCBDI2d::theMatrix(6,6); Vector ForceBeamColumnCBDI2d::theVector(6); double ForceBeamColumnCBDI2d::workArea[200]; -Vector *ForceBeamColumnCBDI2d::vsSubdivide = 0; -Matrix *ForceBeamColumnCBDI2d::fsSubdivide = 0; -Vector *ForceBeamColumnCBDI2d::SsrSubdivide = 0; +Vector ForceBeamColumnCBDI2d::vsSubdivide[maxNumSections]; +Matrix ForceBeamColumnCBDI2d::fsSubdivide[maxNumSections]; +Vector ForceBeamColumnCBDI2d::SsrSubdivide[maxNumSections]; void* OPS_ForceBeamColumnCBDI2d() { @@ -278,17 +278,6 @@ ForceBeamColumnCBDI2d::ForceBeamColumnCBDI2d(): { theNodes[0] = 0; theNodes[1] = 0; - - if (vsSubdivide == 0) - vsSubdivide = new Vector [maxNumSections]; - if (fsSubdivide == 0) - fsSubdivide = new Matrix [maxNumSections]; - if (SsrSubdivide == 0) - SsrSubdivide = new Vector [maxNumSections]; - if (!vsSubdivide || !fsSubdivide || !SsrSubdivide) { - opserr << "ForceBeamColumnCBDI2d::ForceBeamColumnCBDI2d() -- failed to allocate Subdivide arrays"; - exit(-1); - } } // constructor which takes the unique element tag, sections, @@ -330,17 +319,6 @@ ForceBeamColumnCBDI2d::ForceBeamColumnCBDI2d (int tag, int nodeI, int nodeJ, } this->setSectionPointers(numSec, sec); - - if (vsSubdivide == 0) - vsSubdivide = new Vector [maxNumSections]; - if (fsSubdivide == 0) - fsSubdivide = new Matrix [maxNumSections]; - if (SsrSubdivide == 0) - SsrSubdivide = new Vector [maxNumSections]; - if (!vsSubdivide || !fsSubdivide || !SsrSubdivide) { - opserr << "ForceBeamColumnCBDI2d::ForceBeamColumnCBDI2d() -- failed to allocate Subdivide arrays"; - exit(-1); - } } // ~ForceBeamColumnCBDI2d(): @@ -3016,6 +2994,12 @@ ForceBeamColumnCBDI2d::setResponse(const char **argv, int argc, OPS_Stream &outp else if (strcmp(argv[0],"integrationWeights") == 0) theResponse = new ElementResponse(this, 11, Vector(numSections)); + else if (strcmp(argv[0],"sectionDisplacements") == 0) + theResponse = new ElementResponse(this, 111, Matrix(numSections,3)); + + else if (strcmp(argv[0],"cbdiDisplacements") == 0) + theResponse = new ElementResponse(this, 112, Matrix(20,3)); + // section response - else if (strstr(argv[0],"sectionX") != 0) { if (argc > 2) { @@ -3273,6 +3257,80 @@ ForceBeamColumnCBDI2d::getResponse(int responseID, Information &eleInfo) return eleInfo.setVector(weights); } + else if (responseID == 111) { + double L = crdTransf->getInitialLength(); + double pts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, pts); + // CBDI influence matrix + Matrix ls(numSections, numSections); + getCBDIinfluenceMatrix(numSections, pts, L, ls); + // Curvature vector + Vector kappa(numSections); + for (int i = 0; i < numSections; i++) { + const ID &code = sections[i]->getType(); + const Vector &e = sections[i]->getSectionDeformation(); + int order = sections[i]->getOrder(); + for (int j = 0; j < order; j++) + if (code(j) == SECTION_RESPONSE_MZ) + kappa(i) += e(j); + } + // Displacement vector + Vector dispsy(numSections); + dispsy.addMatrixVector(0.0, ls, kappa, 1.0); + beamIntegr->getSectionLocations(numSections, L, pts); + static Vector uxb(2); + static Vector uxg(2); + Matrix disps(numSections,3); + vp = crdTransf->getBasicTrialDisp(); + for (int i = 0; i < numSections; i++) { + uxb(0) = pts[i]*vp(0); // linear shape function + uxb(1) = dispsy(i); + uxg = crdTransf->getPointGlobalDisplFromBasic(pts[i],uxb); + disps(i,0) = uxg(0); + disps(i,1) = uxg(1); + disps(i,2) = 0.0; + } + return eleInfo.setMatrix(disps); + } + + else if (responseID == 112) { + double L = crdTransf->getInitialLength(); + double ipts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, ipts); + // CBDI influence matrix + double pts[20]; + for (int i = 0; i < 20; i++) + pts[i] = 1.0/(20-1)*i; + Matrix ls(20, numSections); + getCBDIinfluenceMatrix(20, pts, numSections, ipts, L, ls); + // Curvature vector + Vector kappa(numSections); + for (int i = 0; i < numSections; i++) { + const ID &code = sections[i]->getType(); + const Vector &e = sections[i]->getSectionDeformation(); + int order = sections[i]->getOrder(); + for (int j = 0; j < order; j++) + if (code(j) == SECTION_RESPONSE_MZ) + kappa(i) += e(j); + } + // Displacement vector + Vector dispsy(20); + dispsy.addMatrixVector(0.0, ls, kappa, 1.0); + static Vector uxb(2); + static Vector uxg(2); + Matrix disps(20,3); + vp = crdTransf->getBasicTrialDisp(); + for (int i = 0; i < 20; i++) { + uxb(0) = pts[i]*vp(0); // linear shape function + uxb(1) = dispsy(i); + uxg = crdTransf->getPointGlobalDisplFromBasic(pts[i],uxb); + disps(i,0) = uxg(0); + disps(i,1) = uxg(1); + disps(i,2) = 0.0; + } + return eleInfo.setMatrix(disps); + } + else return -1; } diff --git a/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.h b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.h index 8cccb176a3..6587a50ed0 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.h +++ b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.h @@ -215,9 +215,9 @@ class ForceBeamColumnCBDI2d: public Element // following are added for subdivision of displacement increment int maxSubdivisions; // maximum number of subdivisons of dv for local iterations - static Vector *vsSubdivide; - static Vector *SsrSubdivide; - static Matrix *fsSubdivide; + static Vector vsSubdivide[]; + static Vector SsrSubdivide[]; + static Matrix fsSubdivide[]; //static int maxNumSections; // AddingSensitivity:BEGIN ////////////////////////////////////////// diff --git a/SRC/element/forceBeamColumn/ForceBeamColumnCBDI3d.cpp b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI3d.cpp new file mode 100644 index 0000000000..9de1d46f64 --- /dev/null +++ b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI3d.cpp @@ -0,0 +1,4636 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision$ +// $Date$ +// $Source$ + +/* + * References + * + +State Determination Algorithm +--- +Neuenhofer, A. and F. C. Filippou (1997). "Evaluation of Nonlinear Frame Finite +Element Models." Journal of Structural Engineering, 123(7):958-966. + +Spacone, E., V. Ciampi, and F. C. Filippou (1996). "Mixed Formulation of +Nonlinear Beam Finite Element." Computers and Structures, 58(1):71-83. + + +Plastic Hinge Integration +--- +Scott, M. H. and G. L. Fenves (2006). "Plastic Hinge Integration Methods for +Force-Based Beam-Column Elements." Journal of Structural Engineering, +132(2):244-252. + + +Analytical Response Sensitivity (DDM) +--- +Scott, M. H., P. Franchin, G. L. Fenves, and F. C. Filippou (2004). +"Response Sensitivity for Nonlinear Beam-Column Elements." +Journal of Structural Engineering, 130(9):1281-1288. + + +Software Design +--- +Scott, M. H., G. L. Fenves, F. T. McKenna, and F. C. Filippou (2007). +"Software Patterns for Nonlinear Beam-Column Models." +Journal of Structural Engineering, Approved for publication, February 2007. + + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +Matrix ForceBeamColumnCBDI3d::theMatrix(12,12); +Vector ForceBeamColumnCBDI3d::theVector(12); +double ForceBeamColumnCBDI3d::workArea[800]; + +Vector ForceBeamColumnCBDI3d::vsSubdivide[maxNumSections]; +Matrix ForceBeamColumnCBDI3d::fsSubdivide[maxNumSections]; +Vector ForceBeamColumnCBDI3d::SsrSubdivide[maxNumSections]; + +void* OPS_ForceBeamColumnCBDI3d() +{ + if(OPS_GetNumRemainingInputArgs() < 5) { + opserr<<"insufficient arguments:eleTag,iNode,jNode,transfTag,integrationTag\n"; + return 0; + } + + int ndm = OPS_GetNDM(); + int ndf = OPS_GetNDF(); + if(ndm != 3 || ndf != 6) { + opserr<<"ndm must be 3 and ndf must be 6\n"; + return 0; + } + + // inputs: + int iData[5]; + int numData = 5; + if(OPS_GetIntInput(&numData,&iData[0]) < 0) { + opserr << "WARNING invalid int inputs\n"; + return 0; + } + + // options + double mass = 0.0, tol=1e-12; + int maxIter = 10; + numData = 1; + bool includeShear = false; + while(OPS_GetNumRemainingInputArgs() > 0) { + const char* type = OPS_GetString(); + if(strcmp(type, "-iter") == 0) { + if(OPS_GetNumRemainingInputArgs() > 1) { + if(OPS_GetIntInput(&numData,&maxIter) < 0) { + opserr << "WARNING invalid maxIter\n"; + return 0; + } + if(OPS_GetDoubleInput(&numData,&tol) < 0) { + opserr << "WARNING invalid tol\n"; + return 0; + } + } + } else if(strcmp(type,"-mass") == 0) { + if(OPS_GetNumRemainingInputArgs() > 0) { + if(OPS_GetDoubleInput(&numData,&mass) < 0) { + opserr << "WARNING invalid mass\n"; + return 0; + } + } + } else if(strcmp(type,"-shear") == 0) { + includeShear = true; + } + } + + // check transf + CrdTransf* theTransf = OPS_getCrdTransf(iData[3]); + if(theTransf == 0) { + opserr<<"coord transfomration not found\n"; + return 0; + } + + // check beam integrataion + BeamIntegrationRule* theRule = OPS_getBeamIntegrationRule(iData[4]); + if(theRule == 0) { + opserr<<"beam integration not found\n"; + return 0; + } + BeamIntegration* bi = theRule->getBeamIntegration(); + if(bi == 0) { + opserr<<"beam integration is null\n"; + return 0; + } + + // check sections + const ID& secTags = theRule->getSectionTags(); + SectionForceDeformation** sections = new SectionForceDeformation *[secTags.Size()]; + for(int i=0; i 0) { + const char* type = OPS_GetString(); + if(strcmp(type, "-iter") == 0) { + if(OPS_GetNumRemainingInputArgs() > 1) { + if(OPS_GetIntInput(&numData,&maxIter) < 0) { + opserr << "WARNING invalid maxIter\n"; + return 0; + } + if(OPS_GetDoubleInput(&numData,&tol) < 0) { + opserr << "WARNING invalid tol\n"; + return 0; + } + } + } else if(strcmp(type,"-mass") == 0) { + if(OPS_GetNumRemainingInputArgs() > 0) { + if(OPS_GetDoubleInput(&numData,&mass) < 0) { + opserr << "WARNING invalid mass\n"; + return 0; + } + } + } + } + + // check transf + CrdTransf* theTransf = OPS_getCrdTransf(iData[3]); + if(theTransf == 0) { + opserr<<"coord transfomration not found\n"; + return 0; + } + + // check beam integrataion + BeamIntegrationRule* theRule = OPS_getBeamIntegrationRule(iData[4]); + if(theRule == 0) { + opserr<<"beam integration not found\n"; + return 0; + } + BeamIntegration* bi = theRule->getBeamIntegration(); + if(bi == 0) { + opserr<<"beam integration is null\n"; + return 0; + } + + // check sections + const ID& secTags = theRule->getSectionTags(); + SectionForceDeformation** sections = new SectionForceDeformation *[secTags.Size()]; + for(int i=0; isetSectionPointers(numSec, sec); +} + +// ~ForceBeamColumnCBDI3d(): +// destructor +// delete must be invoked on any objects created by the object +ForceBeamColumnCBDI3d::~ForceBeamColumnCBDI3d() +{ + if (sections != 0) { + for (int i=0; i < numSections; i++) + if (sections[i] != 0) + delete sections[i]; + delete [] sections; + } + + if (sizeEleLoads != 0) { + if (eleLoads != 0) + delete [] eleLoads; + + if (eleLoadFactors != 0) + delete [] eleLoadFactors; + } + + if (fs != 0) + delete [] fs; + + if (vs != 0) + delete [] vs; + + if (Ssr != 0) + delete [] Ssr; + + if (vscommit != 0) + delete [] vscommit; + + if (crdTransf != 0) + delete crdTransf; + + if (beamIntegr != 0) + delete beamIntegr; + + if (Ki != 0) + delete Ki; +} + +int +ForceBeamColumnCBDI3d::getNumExternalNodes(void) const +{ + return 2; +} + +const ID & +ForceBeamColumnCBDI3d::getExternalNodes(void) +{ + return connectedExternalNodes; +} + +Node ** +ForceBeamColumnCBDI3d::getNodePtrs() +{ + return theNodes; +} + +int +ForceBeamColumnCBDI3d::getNumDOF(void) +{ + return NEGD; +} + +void +ForceBeamColumnCBDI3d::setDomain(Domain *theDomain) +{ + // check Domain is not null - invoked when object removed from a domain + if (theDomain == 0) { + theNodes[0] = 0; + theNodes[1] = 0; + + opserr << "ForceBeamColumnCBDI3d::setDomain: theDomain = 0 "; + exit(0); + } + + // get pointers to the nodes + + int Nd1 = connectedExternalNodes(0); + int Nd2 = connectedExternalNodes(1); + + theNodes[0] = theDomain->getNode(Nd1); + theNodes[1] = theDomain->getNode(Nd2); + + if (theNodes[0] == 0) { + opserr << "ForceBeamColumnCBDI3d::setDomain: Nd1: "; + opserr << Nd1 << "does not exist in model\n"; + exit(0); + } + + if (theNodes[1] == 0) { + opserr << "ForceBeamColumnCBDI3d::setDomain: Nd2: "; + opserr << Nd2 << "does not exist in model\n"; + exit(0); + } + + // call the DomainComponent class method + this->DomainComponent::setDomain(theDomain); + + // ensure connected nodes have correct number of dof's + int dofNode1 = theNodes[0]->getNumberDOF(); + int dofNode2 = theNodes[1]->getNumberDOF(); + + if ((dofNode1 != NND) || (dofNode2 != NND)) { + opserr << "ForceBeamColumnCBDI3d::setDomain(): Nd2 or Nd1 incorrect dof for element " << this->getTag(); + exit(0); + } + + // initialize the transformation + if (crdTransf->initialize(theNodes[0], theNodes[1])) { + opserr << "ForceBeamColumnCBDI3d::setDomain(): Error initializing coordinate transformation for element " << this->getTag(); + exit(0); + } + + // get element length + double L = crdTransf->getInitialLength(); + if (L == 0.0) { + opserr << "ForceBeamColumnCBDI3d::setDomain(): Zero length for element " << this->getTag(); + exit(0); + } + + if (initialFlag == 0) + this->initializeSectionHistoryVariables(); +} + +int +ForceBeamColumnCBDI3d::commitState() +{ + int err = 0; + int i = 0; + + // call element commitState to do any base class stuff + if ((err = this->Element::commitState()) != 0) { + opserr << "ForceBeamColumnCBDI3d::commitState () - failed in base class"; + } + + do { + vscommit[i] = vs[i]; + err = sections[i++]->commitState(); + + } while (err == 0 && i < numSections); + + if (err) + return err; + + // commit the transformation between coord. systems + if ((err = crdTransf->commitState()) != 0) + return err; + + // commit the element variables state + kvcommit = kv; + Secommit = Se; + + // initialFlag = 0; fmk - commented out, see what happens to Example3.1.tcl if uncommented + // - i have not a clue why, ask remo if he ever gets in contact with us again! + + return err; +} + +int ForceBeamColumnCBDI3d::revertToLastCommit() +{ + int err; + int i = 0; + + do { + vs[i] = vscommit[i]; + err = sections[i]->revertToLastCommit(); + + sections[i]->setTrialSectionDeformation(vs[i]); + Ssr[i] = sections[i]->getStressResultant(); + fs[i] = sections[i]->getSectionFlexibility(); + + i++; + } while (err == 0 && i < numSections); + + + if (err) + return err; + + // revert the transformation to last commit + if ((err = crdTransf->revertToLastCommit()) != 0) + return err; + + // revert the element state to last commit + Se = Secommit; + kv = kvcommit; + + initialFlag = 0; + // this->update(); + + return err; +} + +int ForceBeamColumnCBDI3d::revertToStart() +{ + // revert the sections state to start + int err; + int i = 0; + + do { + fs[i].Zero(); + vs[i].Zero(); + Ssr[i].Zero(); + err = sections[i++]->revertToStart(); + + } while (err == 0 && i < numSections); + + if (err) + return err; + + // revert the transformation to start + if ((err = crdTransf->revertToStart()) != 0) + return err; + + // revert the element state to start + Secommit.Zero(); + kvcommit.Zero(); + + Se.Zero(); + kv.Zero(); + + initialFlag = 0; + // this->update(); + return err; +} + + +const Matrix & +ForceBeamColumnCBDI3d::getInitialStiff(void) +{ + // check for quick return + if (Ki != 0) + return *Ki; + + /* + else + Ki = new Matrix(this->getTangentStiff()); + */ + + static Matrix f(NEBD, NEBD); // element flexibility matrix + this->getInitialFlexibility(f); + + /* + static Matrix I(NEBD,NEBD); // an identity matrix for matrix inverse + I.Zero(); + for (int i=0; igetInitialGlobalStiffMatrix(kvInit)); + + return *Ki; +} + +const Matrix & +ForceBeamColumnCBDI3d::getTangentStiff(void) +{ + crdTransf->update(); // Will remove once we clean up the corotational 2d transformation -- MHS + return crdTransf->getGlobalStiffMatrix(kv, Se); +} + +void +ForceBeamColumnCBDI3d::computeReactions(double *p0) +{ + int type; + double L = crdTransf->getInitialLength(); + + for (int i = 0; i < numEleLoads; i++) { + + double loadFactor = eleLoadFactors[i]; + const Vector &data = eleLoads[i]->getData(type, loadFactor); + + if (type == LOAD_TAG_Beam3dUniformLoad) { + double wy = data(0)*loadFactor; // Transverse + double wz = data(1)*loadFactor; // Transverse + double wa = data(2)*loadFactor; // Axial + + p0[0] -= wa*L; + double V = 0.5*wy*L; + p0[1] -= V; + p0[2] -= V; + V = 0.5*wz*L; + p0[3] -= V; + p0[4] -= V; + } + else if (type == LOAD_TAG_Beam3dPartialUniformLoad) { + double wa = data(2)*loadFactor; // Axial + double wy = data(0)*loadFactor; // Transverse + double wz = data(1)*loadFactor; // Transverse + double a = data(3)*L; + double b = data(4)*L; + + p0[0] -= wa*(b-a); + double Fy = wy*(b-a); + double c = a + 0.5*(b-a); + p0[1] -= Fy*(1-c/L); + p0[2] -= Fy*c/L; + double Fz = wz*(b-a); + p0[3] -= Fz*(1-c/L); + p0[4] -= Fz*c/L; + } + else if (type == LOAD_TAG_Beam3dPointLoad) { + double Py = data(0)*loadFactor; + double Pz = data(1)*loadFactor; + double N = data(2)*loadFactor; + double aOverL = data(3); + + if (aOverL < 0.0 || aOverL > 1.0) + continue; + + double V1 = Py*(1.0-aOverL); + double V2 = Py*aOverL; + p0[0] -= N; + p0[1] -= V1; + p0[2] -= V2; + V1 = Pz*(1.0-aOverL); + V2 = Pz*aOverL; + p0[3] -= V1; + p0[4] -= V2; + } + } +} + +void +ForceBeamColumnCBDI3d::computeReactionSensitivity(double *dp0dh, int gradNumber) +{ + int type; + double L = crdTransf->getInitialLength(); + + double dLdh = crdTransf->getdLdh(); + + for (int i = 0; i < numEleLoads; i++) { + + const Vector &data = eleLoads[i]->getData(type, 1.0); + + if (type == LOAD_TAG_Beam2dUniformLoad) { + double wy = data(0)*1.0; // Transverse + double wa = data(1)*1.0; // Axial + + const Vector &sens = eleLoads[i]->getSensitivityData(gradNumber); + double dwydh = sens(0); + double dwadh = sens(1); + + //p0[0] -= wa*L; + dp0dh[0] -= wa*dLdh + dwadh*L; + + //double V = 0.5*wy*L; + //p0[1] -= V; + //p0[2] -= V; + double dVdh = 0.5*(wy*dLdh + dwydh*L); + dp0dh[1] -= dVdh; + dp0dh[2] -= dVdh; + } + else if (type == LOAD_TAG_Beam2dPointLoad) { + double P = data(0)*1.0; + double N = data(1)*1.0; + double aOverL = data(2); + + if (aOverL < 0.0 || aOverL > 1.0) + continue; + + const Vector &sens = eleLoads[i]->getSensitivityData(gradNumber); + double dPdh = sens(0); + double dNdh = sens(1); + double daLdh = sens(2); + + //double a = aOverL*L; + + //double V1 = P*(1.0-aOverL); + //double V2 = P*aOverL; + double dV1dh = P*(0.0-daLdh) + dPdh*(1.0-aOverL); + double dV2dh = P*daLdh + dPdh*aOverL; + + //p0[0] -= N; + //p0[1] -= V1; + //p0[2] -= V2; + dp0dh[0] -= dNdh; + dp0dh[1] -= dV1dh; + dp0dh[2] -= dV2dh; + } + } +} + +const Vector & +ForceBeamColumnCBDI3d::getResistingForce(void) +{ + // Will remove once we clean up the corotational 2d transformation -- MHS + crdTransf->update(); + + double p0[6]; + Vector p0Vec(p0, 6); + p0Vec.Zero(); + + if (numEleLoads > 0) + this->computeReactions(p0); + + return crdTransf->getGlobalResistingForce(Se, p0Vec); +} + +void +ForceBeamColumnCBDI3d::initializeSectionHistoryVariables (void) +{ + for (int i = 0; i < numSections; i++) { + int order = sections[i]->getOrder(); + + fs[i] = Matrix(order, order); + vs[i] = Vector(order); + Ssr[i] = Vector(order); + + vscommit[i] = Vector(order); + } +} + +/********* NEWTON , SUBDIVIDE AND INITIAL ITERATIONS ******************** + */ +int +ForceBeamColumnCBDI3d::update() +{ + // if have completed a recvSelf() - do a revertToLastCommit + // to get Ssr, etc. set correctly + if (initialFlag == 2) + this->revertToLastCommit(); + + // update the transformation + crdTransf->update(); + + // get basic displacements and increments + const Vector &v = crdTransf->getBasicTrialDisp(); + + static Vector dv(NEBD); + + dv = crdTransf->getBasicIncrDeltaDisp(); + + if (initialFlag != 0 && dv.Norm() <= DBL_EPSILON && numEleLoads == 0) + return 0; + + static Vector vin(NEBD); + vin = v; + vin -= dv; + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + double wt[maxNumSections]; + beamIntegr->getSectionWeights(numSections, L, wt); + + static Vector vr(NEBD); // element residual displacements + static Matrix f(NEBD,NEBD); // element flexibility matrix + + static Matrix I(NEBD,NEBD); // an identity matrix for matrix inverse + double dW; // section strain energy (work) norm + int i, j; + + I.Zero(); + for (i=0; igetOrder(); + const ID& code = sections[0]->getType(); + + Vector stilde(order*numSections); + for (int i = 0; i < numSections; i++) { + int orderi = order*i; + const Vector &s = sections[i]->getStressResultant(); + for (int j = 0; j < order; j++) + stilde(orderi+j) = s(j); + } + + // get CBDI influence matrix + Matrix ls(numSections, numSections); + //getCBDIinfluenceMatrix(numSections, xi, L, ls); + + Matrix G(numSections, numSections); + this->getG(numSections, xi, G); + + Matrix Ginv(numSections, numSections); + + Matrix Hk(numSections, numSections); + for (int i = 0; i < numSections; i++) + Hk(i,i) = 1.0; + + G.Solve(Hk, Ginv); + + this->getHk(numSections, xi, Hk); + + ls.addMatrixProduct(0.0, Hk, Ginv, 1.0); + + Matrix Hg(numSections, numSections); + this->getHg(numSections, xi, Hg); + + Hk.addMatrixProduct(0.0, Hg, Ginv, 1.0); + Matrix &lsg = Hk; + + Matrix lskp(numSections, numSections); + Matrix Hkp(numSections, numSections); + this->getHkp(numSections, xi, Hkp); + lskp.addMatrixProduct(0.0, Hkp, Ginv, 1.0); + + Matrix lsgp(numSections, numSections); + Matrix Hgp(numSections, numSections); + this->getHgp(numSections, xi, Hgp); + lsgp.addMatrixProduct(0.0, Hgp, Ginv, 1.0); + + // calculate nodal force increments and update nodal forces + // dSe = kv * dv; + dSe.addMatrixVector(0.0, kvTrial, dvTrial, 1.0); + + Vector kappa(numSections); + Vector gamma(numSections); + Vector kappay(numSections); + Vector gammaz(numSections); + Vector w(numSections); + Vector wp(numSections); + Vector wz(numSections); + Vector wpz(numSections); + Vector dstilde(order*numSections); + Matrix kEtilde(order*numSections,order*numSections); + Vector detilde(order*numSections); + + //maxIters = 100; + + for (j = 0; j < maxIters; j++) { + + SeTrial += dSe; + + // initialize f and vr for integration + f.Zero(); + vr.Zero(); + + if (beamIntegr->addElasticFlexibility(L, f) < 0) { + vr(0) += f(0,0)*SeTrial(0); + vr(1) += f(1,1)*SeTrial(1) + f(1,2)*SeTrial(2); + vr(2) += f(2,1)*SeTrial(1) + f(2,2)*SeTrial(2); + vr(3) += f(3,3)*SeTrial(3) + f(3,4)*SeTrial(4); + vr(4) += f(4,3)*SeTrial(3) + f(4,4)*SeTrial(4); + vr(5) += f(5,5)*SeTrial(5); + } + + double v0[5]; + v0[0] = 0.0; v0[1] = 0.0; v0[2] = 0.0; + v0[3] = 0.0; v0[4] = 0.0; + + for (int ie = 0; ie < numEleLoads; ie++) + beamIntegr->addElasticDeformations(eleLoads[ie], eleLoadFactors[ie], L, v0); + + // Add effects of element loads + vr(0) += v0[0]; + vr(1) += v0[1]; + vr(2) += v0[2]; + vr(3) += v0[3]; + vr(4) += v0[4]; + + bool isGamma = false; + bool isGammaz = false; + + for (int i = 0; i < numSections; i++) { + kappa(i) = 0.0; + gamma(i) = 0.0; + kappay(i) = 0.0; + gammaz(i) = 0.0; + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + kappa(i) += (vsSubdivide[i])(j); + if (code(j) == SECTION_RESPONSE_VY) { + gamma(i) += (vsSubdivide[i])(j); + isGamma = true; + } + if (code(j) == SECTION_RESPONSE_MY) + kappay(i) += (vsSubdivide[i])(j); + if (code(j) == SECTION_RESPONSE_VZ) { + gammaz(i) += (vsSubdivide[i])(j); + isGammaz = true; + } + } + } + isGamma = CSBDI && isGamma; + + w.addMatrixVector(0.0, ls, kappa, L*L); + if (isGamma) { + w.addMatrixVector(1.0, lsg, gamma, L); + wp.addMatrixVector(0.0, lskp, kappa, L); + wp.addMatrixVector(1.0, lsgp, gamma, 1.0); + } + wz.addMatrixVector(0.0, ls, kappay, L*L); + if (isGammaz) { + wz.addMatrixVector(1.0, lsg, gammaz, L); + wpz.addMatrixVector(0.0, lskp, kappay, L); + wpz.addMatrixVector(1.0, lsgp, gammaz, 1.0); + } + + for (int i = 0; i < numSections; i++) { + + int index = order*i; + + for (int j = 0; j < order; j++) { + + if (code(j) == SECTION_RESPONSE_P) + dstilde(index) = SeTrial(0) - stilde(index); + if (code(j) == SECTION_RESPONSE_MZ) + dstilde(index) = w(i)*SeTrial(0) + (xi[i]-1)*SeTrial(1) + + xi[i]*SeTrial(2) - stilde(index); + if (code(j) == SECTION_RESPONSE_VY) + dstilde(index) = -wp(i)*SeTrial(0) - oneOverL*(SeTrial(1)+SeTrial(2)) - stilde(index); + if (code(j) == SECTION_RESPONSE_MY) + dstilde(index) = wz(i)*SeTrial(0) + (xi[i]-1)*SeTrial(3) + + xi[i]*SeTrial(4) - stilde(index); + if (code(j) == SECTION_RESPONSE_VY) + dstilde(index) = -wpz(i)*SeTrial(0) - oneOverL*(SeTrial(3)+SeTrial(4)) - stilde(index); + if (code(j) == SECTION_RESPONSE_T) + dstilde(index) = SeTrial(5) - stilde(index); + index++; + } + } + + kEtilde.Zero(); + for (int i = 0; i < numSections; i++) { + int orderi = order*i; + for (int j = 0; j < numSections; j++) { + int orderj = order*j; + for (int k = 0; k < order; k++) { + if (code(k) == SECTION_RESPONSE_MZ) { + kEtilde(orderi+k,orderj+k) += ls(i,j)*L*L*SeTrial(0); + if (isGamma) + kEtilde(orderi+k,orderj+k+1) += lsg(i,j)*L*SeTrial(0); + } + if (isGamma && code(k) == SECTION_RESPONSE_VY) { + kEtilde(orderi+k,orderj+k-1) -= lskp(i,j)*L*SeTrial(0); + kEtilde(orderi+k,orderj+k) -= lsgp(i,j)*SeTrial(0); + } + if (code(k) == SECTION_RESPONSE_MY) { + kEtilde(orderi+k,orderj+k) += ls(i,j)*L*L*SeTrial(0); + if (isGammaz) + kEtilde(orderi+k,orderj+k+1) += lsg(i,j)*L*SeTrial(0); + } + if (isGammaz && code(k) == SECTION_RESPONSE_VZ) { + kEtilde(orderi+k,orderj+k-1) -= lskp(i,j)*L*SeTrial(0); + kEtilde(orderi+k,orderj+k) -= lsgp(i,j)*SeTrial(0); + } + } + } + + fsSubdivide[i] = sections[i]->getSectionFlexibility(); + + const Matrix &ks = sections[i]->getSectionTangent(); + for (int ii = 0; ii < order; ii++) + for (int jj = 0; jj < order; jj++) + kEtilde(orderi+ii,orderi+jj) -= ks(ii,jj); + } + + kEtilde.Solve(dstilde, detilde); + + for (int i = 0; i < numSections; i++) { + int orderi = order*i; + for (int j = 0; j < order; j++) + (vsSubdivide[i])(j) -= detilde(orderi+j); + } + + for (int i = 0; i < numSections; i++) { + kappa(i) = 0.0; + gamma(i) = 0.0; + kappay(i) = 0.0; + gammaz(i) = 0.0; + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + kappa(i) += (vsSubdivide[i])(j); + if (code(j) == SECTION_RESPONSE_VY) + gamma(i) += (vsSubdivide[i])(j); + if (code(j) == SECTION_RESPONSE_MY) + kappay(i) += (vsSubdivide[i])(j); + if (code(j) == SECTION_RESPONSE_VZ) + gammaz(i) += (vsSubdivide[i])(j); + } + } + + w.addMatrixVector(0.0, ls, kappa, L*L); + if (isGamma) { + w.addMatrixVector(1.0, lsg, gamma, L); + wp.addMatrixVector(0.0, lskp, kappa, L); + wp.addMatrixVector(1.0, lsgp, gamma, 1.0); + } + wz.addMatrixVector(0.0, ls, kappay, L*L); + if (isGamma) { + wz.addMatrixVector(1.0, lsg, gammaz, L); + wpz.addMatrixVector(0.0, lskp, kappay, L); + wpz.addMatrixVector(1.0, lsgp, gammaz, 1.0); + } + + kEtilde.Zero(); + for (int i = 0; i < numSections; i++) { + + sections[i]->setTrialSectionDeformation(vsSubdivide[i]); + + SsrSubdivide[i] = sections[i]->getStressResultant(); + + int index = order*i; + + for (int j = 0; j < order; j++) { + + if (code(j) == SECTION_RESPONSE_P) + dstilde(index) = SeTrial(0); + if (code(j) == SECTION_RESPONSE_MZ) + dstilde(index) = w(i)*SeTrial(0) + (xi[i]-1.0)*SeTrial(1) + xi[i]*SeTrial(2); + if (code(j) == SECTION_RESPONSE_VY) + dstilde(index) = -wp(i)*SeTrial(0) - oneOverL*(SeTrial(1)+SeTrial(2)); + if (code(j) == SECTION_RESPONSE_MY) + dstilde(index) = wz(i)*SeTrial(0) + (xi[i]-1.0)*SeTrial(3) + xi[i]*SeTrial(4); + if (code(j) == SECTION_RESPONSE_VZ) + dstilde(index) = -wpz(i)*SeTrial(0) - oneOverL*(SeTrial(3)+SeTrial(4)); + if (code(j) == SECTION_RESPONSE_T) + dstilde(index) = SeTrial(5); + + dstilde(index) -= SsrSubdivide[i](j); + + index++; + } + + int orderi = order*i; + for (int j = 0; j < numSections; j++) { + int orderj = order*j; + for (int k = 0; k < order; k++) { + if (code(k) == SECTION_RESPONSE_MZ) { + kEtilde(orderi+k,orderj+k) += ls(i,j)*L*L*SeTrial(0); + if (isGamma) + kEtilde(orderi+k,orderj+k+1) += lsg(i,j)*L*SeTrial(0); + } + if (isGamma && code(k) == SECTION_RESPONSE_VY) { + kEtilde(orderi+k,orderj+k-1) -= lskp(i,j)*L*SeTrial(0); + kEtilde(orderi+k,orderj+k) -= lsgp(i,j)*SeTrial(0); + } + if (code(k) == SECTION_RESPONSE_MY) { + kEtilde(orderi+k,orderj+k) += ls(i,j)*L*L*SeTrial(0); + if (isGammaz) + kEtilde(orderi+k,orderj+k+1) += lsg(i,j)*L*SeTrial(0); + } + if (isGammaz && code(k) == SECTION_RESPONSE_VZ) { + kEtilde(orderi+k,orderj+k-1) -= lskp(i,j)*L*SeTrial(0); + kEtilde(orderi+k,orderj+k) -= lsgp(i,j)*SeTrial(0); + } + } + } + + fsSubdivide[i] = sections[i]->getSectionFlexibility(); + const Matrix &ks = sections[i]->getSectionTangent(); + for (int ii = 0; ii < order; ii++) + for (int jj = 0; jj < order; jj++) + kEtilde(orderi+ii,orderi+jj) -= ks(ii,jj); + } + + kEtilde.Solve(dstilde, detilde); + + for (int i = 0; i < numSections; i++) { + int orderi = order*i; + for (int j = 0; j < order; j++) + (vsSubdivide[i])(j) -= detilde(orderi+j); + } + + for (int i = 0; i < numSections; i++) { + kappa(i) = 0.0; + gamma(i) = 0.0; + kappay(i) = 0.0; + gammaz(i) = 0.0; + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + kappa(i) += (vsSubdivide[i])(j); + if (code(j) == SECTION_RESPONSE_VY) + gamma(i) += (vsSubdivide[i])(j); + if (code(j) == SECTION_RESPONSE_MY) + kappay(i) += (vsSubdivide[i])(j); + if (code(j) == SECTION_RESPONSE_VZ) + gammaz(i) += (vsSubdivide[i])(j); + } + } + + w.addMatrixVector(0.0, ls, kappa, L*L); + if (isGamma) { + w.addMatrixVector(1.0, lsg, gamma, L); + wp.addMatrixVector(0.0, lskp, kappa, L); + wp.addMatrixVector(1.0, lsgp, gamma, 1.0); + } + wz.addMatrixVector(0.0, ls, kappay, L*L); + if (isGammaz) { + wz.addMatrixVector(1.0, lsg, gammaz, L); + wpz.addMatrixVector(0.0, lskp, kappay, L); + wpz.addMatrixVector(1.0, lsgp, gammaz, 1.0); + } + + for (int i = 0; i < numSections; i++) { + + int index = order*i; + + for (int j = 0; j < order; j++) { + + if (code(j) == SECTION_RESPONSE_P) + stilde(index) = SeTrial(0); + if (code(j) == SECTION_RESPONSE_MZ) + stilde(index) = w(i)*SeTrial(0) + (xi[i]-1)*SeTrial(1) + xi[i]*SeTrial(2); + if (code(j) == SECTION_RESPONSE_VY) + stilde(index) = -wp(i)*SeTrial(0) - oneOverL*(SeTrial(1)+SeTrial(2)); + if (code(j) == SECTION_RESPONSE_MY) + stilde(index) = w(i)*SeTrial(0) + (xi[i]-1)*SeTrial(3) + xi[i]*SeTrial(4); + if (code(j) == SECTION_RESPONSE_VZ) + stilde(index) = -wp(i)*SeTrial(0) - oneOverL*(SeTrial(3)+SeTrial(4)); + if (code(j) == SECTION_RESPONSE_T) + stilde(index) = SeTrial(5); + + index++; + } + } + + Matrix dwidq(2*numSections,NEBD); + this->computedwdq(dwidq, SeTrial, w, wp, ls, lsg, lskp, lsgp); + Matrix dwzidq(2*numSections,NEBD); + this->computedwzdq(dwzidq, SeTrial, wz, wpz, ls, lsg, lskp, lsgp); + + Matrix bstar(order,NEBD); + Matrix bhat(order,NEBD); + + for (int i = 0; i < numSections; i++) { + + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_P) { + bstar(j,0) = 1.0; + bhat(j,0) = 1.0; + } + if (code(j) == SECTION_RESPONSE_MZ) { + bstar(j,0) = 0.5*w(i); + bstar(j,1) = xi[i]-1; + bstar(j,2) = xi[i]; + + bhat(j,0) = w(i); + bhat(j,1) = xi[i]-1; + bhat(j,2) = xi[i]; + } + if (code(j) == SECTION_RESPONSE_VY) { + bstar(j,0) = -0.5*wp(i); + bstar(j,1) = -oneOverL; + bstar(j,2) = -oneOverL; + + bhat(j,0) = -wp(i); + bhat(j,1) = -oneOverL; + bhat(j,2) = -oneOverL; + } + if (code(j) == SECTION_RESPONSE_MY) { + bstar(j,0) = 0.5*wz(i); + bstar(j,3) = xi[i]-1; + bstar(j,4) = xi[i]; + + bhat(j,0) = wz(i); + bhat(j,3) = xi[i]-1; + bhat(j,4) = xi[i]; + } + if (code(j) == SECTION_RESPONSE_VZ) { + bstar(j,0) = -0.5*wpz(i); + bstar(j,3) = -oneOverL; + bstar(j,4) = -oneOverL; + + bhat(j,0) = -wpz(i); + bhat(j,3) = -oneOverL; + bhat(j,4) = -oneOverL; + } + if (code(j) == SECTION_RESPONSE_T) { + bstar(j,5) = 1.0; + bhat(j,5) = 1.0; + } + } + + double wtL = wt[i]*L; + const Matrix &fSec = sections[i]->getSectionFlexibility(); + //opserr << fSec << sections[i]->getStressResultant() << sections[i]->getType(); + // f = f + bstar^ (fSec * bhat) * wtL; + f.addMatrixTripleProduct(1.0, bstar, fSec, bhat, wtL); + + // f = f + bstar^ fsec * (dbdw * q * dwdq) * wtL; + bhat.Zero(); + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + for (int k = 0; k < NEBD; k++) + bhat(j,k) = SeTrial(0)*dwidq(i,k); + if (code(j) == SECTION_RESPONSE_MY) + for (int k = 0; k < NEBD; k++) + bhat(j,k) = SeTrial(0)*dwzidq(i,k); + } + f.addMatrixTripleProduct(1.0, bstar, fSec, bhat, wtL); + bhat.Zero(); + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_VY) + for (int k = 0; k < NEBD; k++) + bhat(j,k) = -SeTrial(0)*dwidq(i+numSections,k); + if (code(j) == SECTION_RESPONSE_VZ) + for (int k = 0; k < NEBD; k++) + bhat(j,k) = -SeTrial(0)*dwzidq(i+numSections,k); + } + f.addMatrixTripleProduct(1.0, bstar, fSec, bhat, wtL); + + // f = f + dbstardw^ (e * dwdq) * wtL + const Vector &e = vsSubdivide[i]; + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + for (int k = 0; k < NEBD; k++) + f(0,k) += 0.5*e(j)*dwidq(i,k)*wtL; + if (code(j) == SECTION_RESPONSE_VY) + for (int k = 0; k < NEBD; k++) + f(0,k) -= 0.5*e(j)*dwidq(i+numSections,k)*wtL; + if (code(j) == SECTION_RESPONSE_MY) + for (int k = 0; k < NEBD; k++) + f(0,k) += 0.5*e(j)*dwzidq(i,k)*wtL; + if (code(j) == SECTION_RESPONSE_VZ) + for (int k = 0; k < NEBD; k++) + f(0,k) -= 0.5*e(j)*dwzidq(i+numSections,k)*wtL; + } + + // integrate residual deformations + // vr += (b^ (vs + dvs)) * wtL; + //vr.addMatrixTransposeVector(1.0, b[i], vs[i] + dvs, wtL); + //dvs.addVector(1.0, vsSubdivide[i], 1.0); + const Vector &dvs = vsSubdivide[i]; + double dei, tmp; + int order = sections[i]->getOrder(); + const ID &code = sections[i]->getType(); + for (int ii = 0; ii < order; ii++) { + dei = dvs(ii)*wtL; + switch(code(ii)) { + case SECTION_RESPONSE_P: + vr(0) += dei; + break; + case SECTION_RESPONSE_MZ: + vr(1) += (xi[i]-1)*dei; + vr(2) += xi[i]*dei; + vr(0) += 0.5*w(i)*dei; + break; + case SECTION_RESPONSE_VY: + tmp = oneOverL*dei; + vr(1) -= tmp; + vr(2) -= tmp; + vr(0) -= 0.5*wp(i)*dei; + break; + case SECTION_RESPONSE_MY: + vr(3) += (xi[i]-1)*dei; + vr(4) += xi[i]*dei; + vr(0) += 0.5*wz(i)*dei; + break; + case SECTION_RESPONSE_VZ: + tmp = oneOverL*dei; + vr(3) -= tmp; + vr(4) -= tmp; + vr(0) -= 0.5*wpz(i)*dei; + break; + case SECTION_RESPONSE_T: + vr(5) += dei; + break; + default: + break; + } + } + } + + // dv = vin + dvTrial - vr + //dv = vin; + //dv += dvTrial; + //dv -= vr; + + dv = v; + dv -= vr; + + // dv.addVector(1.0, vr, -1.0); + + // dSe = kv * dv; + dSe.addMatrixVector(0.0, kvTrial, dv, 1.0); + + dW = dv ^ dSe; + + // check for convergence of this interval + if (fabs(dW) < tol) { + break; + } + } + + //opserr << w << endln; + + // calculate element stiffness matrix + // invert3by3Matrix(f, kv); + if (f.Solve(I, kvTrial) < 0) + opserr << "ForceBeamColumnCBDI3d::update() -- could not invert flexibility\n"; + + //opserr << f; + //opserr << w; + //opserr << kappa << endln; + + kv = kvTrial; + Se = SeTrial; + for (int k = 0; k < numSections; k++) { + vs[k] = vsSubdivide[k]; + fs[k] = fsSubdivide[k]; + Ssr[k] = SsrSubdivide[k]; + } + + initialFlag = 1; + + return 0; +} + +void ForceBeamColumnCBDI3d::getForceInterpolatMatrix(double xi, Matrix &b, const ID &code) +{ + b.Zero(); + + double L = crdTransf->getInitialLength(); + for (int i = 0; i < code.Size(); i++) { + switch (code(i)) { + case SECTION_RESPONSE_MZ: // Moment, Mz, interpolation + b(i,1) = xi - 1.0; + b(i,2) = xi; + break; + case SECTION_RESPONSE_P: // Axial, P, interpolation + b(i,0) = 1.0; + break; + case SECTION_RESPONSE_VY: // Shear, Vy, interpolation + b(i,1) = b(i,2) = 1.0/L; + break; + default: + break; + } + } +} + +void ForceBeamColumnCBDI3d::getDistrLoadInterpolatMatrix(double xi, Matrix &bp, const ID &code) +{ + bp.Zero(); + + double L = crdTransf->getInitialLength(); + for (int i = 0; i < code.Size(); i++) { + switch (code(i)) { + case SECTION_RESPONSE_MZ: // Moment, Mz, interpolation + bp(i,1) = xi*(xi-1)*L*L/2; + break; + case SECTION_RESPONSE_P: // Axial, P, interpolation + bp(i,0) = (1-xi)*L; + break; + case SECTION_RESPONSE_VY: // Shear, Vy, interpolation + bp(i,1) = (xi-0.5)*L; + break; + default: + break; + } + } +} + +const Matrix & +ForceBeamColumnCBDI3d::getMass(void) +{ + theMatrix.Zero(); + + double L = crdTransf->getInitialLength(); + if (rho != 0.0) + theMatrix(0,0) = theMatrix(1,1) = theMatrix(2,2) = + theMatrix(6,6) = theMatrix(7,7) = theMatrix(8,8) = 0.5*L*rho; + + return theMatrix; +} + +void +ForceBeamColumnCBDI3d::zeroLoad(void) +{ + // This is a semi-hack -- MHS + numEleLoads = 0; + + return; +} + +int +ForceBeamColumnCBDI3d::addLoad(ElementalLoad *theLoad, double loadFactor) +{ + if (numEleLoads == sizeEleLoads) { + + // + // create larger arrays, copy old, delete old & set as new + // + + ElementalLoad ** theNextEleLoads = new ElementalLoad *[sizeEleLoads+1]; + double *theNextEleLoadFactors = new double[sizeEleLoads+1]; + for (int i=0; igetInitialLength(); + + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + double x = xi[isec]*L; + + int order = sections[isec]->getOrder(); + const ID &code = sections[isec]->getType(); + + for (int i = 0; i < numEleLoads; i++) { + + double loadFactor = eleLoadFactors[i]; + const Vector &data = eleLoads[i]->getData(type, loadFactor); + + if (type == LOAD_TAG_Beam3dUniformLoad) { + double wy = data(0)*loadFactor; // Transverse + double wz = data(1)*loadFactor; // Transverse + double wa = data(2)*loadFactor; // Axial + + for (int ii = 0; ii < order; ii++) { + + switch(code(ii)) { + case SECTION_RESPONSE_P: + sp(ii) += wa*(L-x); + break; + case SECTION_RESPONSE_MZ: + sp(ii) += wy*0.5*x*(x-L); + break; + case SECTION_RESPONSE_VY: + sp(ii) += wy*(x-0.5*L); + break; + case SECTION_RESPONSE_MY: + sp(ii) += wz*0.5*x*(L-x); + break; + case SECTION_RESPONSE_VZ: + sp(ii) += wz*(x-0.5*L); + break; + default: + break; + } + } + } + else if (type == LOAD_TAG_Beam3dPartialUniformLoad) { + double wa = data(2)*loadFactor; // Axial + double wy = data(0)*loadFactor; // Transverse + double wz = data(1)*loadFactor; // Transverse + double a = data(3)*L; + double b = data(4)*L; + + double Fa = wa*(b-a); // resultant axial load + double Fy = wy*(b-a); // resultant transverse load + double Fz = wz*(b-a); // resultant transverse load + double c = a + 0.5*(b-a); + double VyI = Fy*(1-c/L); + double VyJ = Fy*c/L; + double VzI = Fz*(1-c/L); + double VzJ = Fz*c/L; + + for (int ii = 0; ii < order; ii++) { + + if (x <= a) { + switch(code(ii)) { + case SECTION_RESPONSE_P: + sp(ii) += Fa; + break; + case SECTION_RESPONSE_MZ: + sp(ii) -= VyI*x; + break; + case SECTION_RESPONSE_MY: + sp(ii) += VzI*x; + break; + case SECTION_RESPONSE_VY: + sp(ii) -= VyI; + break; + case SECTION_RESPONSE_VZ: + sp(ii) -= VzI; + break; + default: + break; + } + } + else if (x >= b) { + switch(code(ii)) { + case SECTION_RESPONSE_MZ: + sp(ii) += VyJ*(x-L); + break; + case SECTION_RESPONSE_MY: + sp(ii) -= VzJ*(x-L); + break; + case SECTION_RESPONSE_VY: + sp(ii) += VyJ; + break; + case SECTION_RESPONSE_VZ: + sp(ii) += VzJ; + break; + default: + break; + } + } + else { + switch(code(ii)) { + case SECTION_RESPONSE_P: + sp(ii) += Fa-wa*(x-a); + break; + case SECTION_RESPONSE_MZ: + sp(ii) += -VyI*x + 0.5*wy*x*x + wy*a*(0.5*a-x); + break; + case SECTION_RESPONSE_MY: + sp(ii) += VzI*x - 0.5*wz*x*x - wz*a*(0.5*a-x); + break; + case SECTION_RESPONSE_VY: + sp(ii) += -VyI + wy*(x-a); + break; + case SECTION_RESPONSE_VZ: + sp(ii) += -VzI + wz*(x-a); + break; + default: + break; + } + } + } + } + else if (type == LOAD_TAG_Beam3dPointLoad) { + double Py = data(0)*loadFactor; + double Pz = data(1)*loadFactor; + double N = data(2)*loadFactor; + double aOverL = data(3); + + if (aOverL < 0.0 || aOverL > 1.0) + continue; + + double a = aOverL*L; + + double Vy1 = Py*(1.0-aOverL); + double Vy2 = Py*aOverL; + + double Vz1 = Pz*(1.0-aOverL); + double Vz2 = Pz*aOverL; + + for (int ii = 0; ii < order; ii++) { + + if (x <= a) { + switch(code(ii)) { + case SECTION_RESPONSE_P: + sp(ii) += N; + break; + case SECTION_RESPONSE_MZ: + sp(ii) -= x*Vy1; + break; + case SECTION_RESPONSE_VY: + sp(ii) -= Vy1; + break; + case SECTION_RESPONSE_MY: + sp(ii) += x*Vz1; + break; + case SECTION_RESPONSE_VZ: + sp(ii) -= Vz1; + break; + default: + break; + } + } + else { + switch(code(ii)) { + case SECTION_RESPONSE_MZ: + sp(ii) -= (L-x)*Vy2; + break; + case SECTION_RESPONSE_VY: + sp(ii) += Vy2; + break; + case SECTION_RESPONSE_MY: + sp(ii) += (L-x)*Vz2; + break; + case SECTION_RESPONSE_VZ: + sp(ii) += Vz2; + break; + default: + break; + } + } + } + } + else { + opserr << "ForceBeamColumnCBDI3d::addLoad -- load type unknown for element with tag: " << + this->getTag() << endln; + } + } + + // Don't think we need to do this anymore -- MHS + //this->update(); // quick fix -- MHS +} + +void +ForceBeamColumnCBDI3d::computeSectionForceSensitivity(Vector &dspdh, int isec, + int gradNumber) +{ + int type; + + double L = crdTransf->getInitialLength(); + double dLdh = crdTransf->getdLdh(); + + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + double dxidh[maxNumSections]; + beamIntegr->getLocationsDeriv(numSections, L, dLdh, dxidh); + + double x = xi[isec]*L; + double dxdh = xi[isec]*dLdh + dxidh[isec]*L; + + int order = sections[isec]->getOrder(); + const ID &code = sections[isec]->getType(); + + for (int i = 0; i < numEleLoads; i++) { + + const Vector &data = eleLoads[i]->getData(type, 1.0); + + if (type == LOAD_TAG_Beam2dUniformLoad) { + double wy = data(0)*1.0; // Transverse + double wa = data(1)*1.0; // Axial + + const Vector &sens = eleLoads[i]->getSensitivityData(gradNumber); + double dwydh = sens(0); + double dwadh = sens(1); + //opserr << wy << ' ' << dwydh << endln; + for (int ii = 0; ii < order; ii++) { + + switch(code(ii)) { + case SECTION_RESPONSE_P: + //sp(ii) += wa*(L-x); + dspdh(ii) += dwadh*(L-x) + wa*(dLdh-dxdh); + break; + case SECTION_RESPONSE_MZ: + //sp(ii) += wy*0.5*x*(x-L); + //dspdh(ii) += 0.5 * (dwydh*x*(x-L) + wy*dxdh*(x-L) + wy*x*(dxdh-dLdh)); + dspdh(ii) += 0.5 * (dwydh*x*(x-L) + wy*(dxdh*(2*x-L)-x*dLdh)); + break; + case SECTION_RESPONSE_VY: + //sp(ii) += wy*(x-0.5*L); + dspdh(ii) += dwydh*(x-0.5*L) + wy*(dxdh-0.5*dLdh); + break; + default: + break; + } + } + } + else if (type == LOAD_TAG_Beam2dPointLoad) { + double P = data(0)*1.0; + double N = data(1)*1.0; + double aOverL = data(2); + + if (aOverL < 0.0 || aOverL > 1.0) + continue; + + const Vector &sens = eleLoads[i]->getSensitivityData(gradNumber); + double dPdh = sens(0); + double dNdh = sens(1); + double daLdh = sens(2); + + double a = aOverL*L; + + double V1 = P*(1.0-aOverL); + double V2 = P*aOverL; + double dV1dh = P*(0.0-daLdh) + dPdh*(1.0-aOverL); + double dV2dh = P*daLdh + dPdh*aOverL; + + for (int ii = 0; ii < order; ii++) { + + if (x <= a) { + switch(code(ii)) { + case SECTION_RESPONSE_P: + //sp(ii) += N; + dspdh(ii) += dNdh; + break; + case SECTION_RESPONSE_MZ: + //sp(ii) -= x*V1; + dspdh(ii) -= (dxdh*V1 + x*dV1dh); + break; + case SECTION_RESPONSE_VY: + //sp(ii) -= V1; + dspdh(ii) -= dV1dh; + break; + default: + break; + } + } + else { + switch(code(ii)) { + case SECTION_RESPONSE_MZ: + //sp(ii) -= (L-x)*V2; + dspdh(ii) -= (dLdh-dxdh)*V2 + (L-x)*dV2dh; + break; + case SECTION_RESPONSE_VY: + //sp(ii) += V2; + dspdh(ii) += dV2dh; + break; + default: + break; + } + } + } + } + else { + opserr << "ForceBeamColumnCBDI3d::computeSectionForceSensitivity -- load type unknown for element with tag: " << + this->getTag() << endln; + } + } +} + +int +ForceBeamColumnCBDI3d::addInertiaLoadToUnbalance(const Vector &accel) +{ + // Check for a quick return + if (rho == 0.0) + return 0; + + // get R * accel from the nodes + const Vector &Raccel1 = theNodes[0]->getRV(accel); + const Vector &Raccel2 = theNodes[1]->getRV(accel); + + double L = crdTransf->getInitialLength(); + double m = 0.5*rho*L; + + // Should be done through p0[0] + /* + load(0) -= m*Raccel1(0); + load(1) -= m*Raccel1(1); + load(2) -= m*Raccel1(2); + load(6) -= m*Raccel2(0); + load(7) -= m*Raccel2(1); + load(8) -= m*Raccel2(2); + */ + + return 0; +} + +const Vector & +ForceBeamColumnCBDI3d::getResistingForceIncInertia() +{ + // Compute the current resisting force + theVector = this->getResistingForce(); + + // Check for a quick return + if (rho != 0.0) { + const Vector &accel1 = theNodes[0]->getTrialAccel(); + const Vector &accel2 = theNodes[1]->getTrialAccel(); + + double L = crdTransf->getInitialLength(); + double m = 0.5*rho*L; + + theVector(0) += m*accel1(0); + theVector(1) += m*accel1(1); + theVector(2) += m*accel1(2); + theVector(6) += m*accel2(0); + theVector(7) += m*accel2(1); + theVector(8) += m*accel2(2); + + // add the damping forces if rayleigh damping + if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + theVector += this->getRayleighDampingForces(); + + } else { + // add the damping forces if rayleigh damping + if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + theVector += this->getRayleighDampingForces(); + } + + return theVector; +} + +int +ForceBeamColumnCBDI3d::sendSelf(int commitTag, Channel &theChannel) +{ + // place the integer data into an ID + int dbTag = this->getDbTag(); + int i, j , k; + int loc = 0; + + static ID idData(11); // one bigger than needed so no clash later + idData(0) = this->getTag(); + idData(1) = connectedExternalNodes(0); + idData(2) = connectedExternalNodes(1); + idData(3) = numSections; + idData(4) = maxIters; + idData(5) = initialFlag; + + idData(6) = crdTransf->getClassTag(); + int crdTransfDbTag = crdTransf->getDbTag(); + if (crdTransfDbTag == 0) { + crdTransfDbTag = theChannel.getDbTag(); + if (crdTransfDbTag != 0) + crdTransf->setDbTag(crdTransfDbTag); + } + idData(7) = crdTransfDbTag; + + idData(8) = beamIntegr->getClassTag(); + int beamIntegrDbTag = beamIntegr->getDbTag(); + if (beamIntegrDbTag == 0) { + beamIntegrDbTag = theChannel.getDbTag(); + if (beamIntegrDbTag != 0) + beamIntegr->setDbTag(beamIntegrDbTag); + } + idData(9) = beamIntegrDbTag; + + if (theChannel.sendID(dbTag, commitTag, idData) < 0) { + opserr << "ForceBeamColumnCBDI3d::sendSelf() - failed to send ID data\n"; + return -1; + } + + // send the coordinate transformation + if (crdTransf->sendSelf(commitTag, theChannel) < 0) { + opserr << "ForceBeamColumnCBDI3d::sendSelf() - failed to send crdTrans\n"; + return -1; + } + + // send the beam integration + if (beamIntegr->sendSelf(commitTag, theChannel) < 0) { + opserr << "ForceBeamColumnCBDI3d::sendSelf() - failed to send beamIntegr\n"; + return -1; + } + + // + // send an ID for the sections containing each sections dbTag and classTag + // if section ha no dbTag get one and assign it + // + + ID idSections(2*numSections); + loc = 0; + for (i = 0; igetClassTag(); + int sectDbTag = sections[i]->getDbTag(); + if (sectDbTag == 0) { + sectDbTag = theChannel.getDbTag(); + sections[i]->setDbTag(sectDbTag); + } + + idSections(loc) = sectClassTag; + idSections(loc+1) = sectDbTag; + loc += 2; + } + + if (theChannel.sendID(dbTag, commitTag, idSections) < 0) { + opserr << "ForceBeamColumnCBDI3d::sendSelf() - failed to send ID data\n"; + return -1; + } + + // + // send the sections + // + + for (j = 0; jsendSelf(commitTag, theChannel) < 0) { + opserr << "ForceBeamColumnCBDI3d::sendSelf() - section " << + j << "failed to send itself\n"; + return -1; + } + } + + // into a vector place distrLoadCommit, rho, UeCommit, Secommit and kvcommit + int secDefSize = 0; + for (i = 0; i < numSections; i++) { + int size = sections[i]->getOrder(); + secDefSize += size; + } + + Vector dData(1+1+NEBD+NEBD*NEBD+secDefSize+4); + loc = 0; + + // place double variables into Vector + dData(loc++) = rho; + dData(loc++) = tol; + + // put distrLoadCommit into the Vector + // for (i=0; igetOrder(); i++) + dData(loc++) = (vscommit[k])(i); + + // send damping coefficients + dData(loc++) = alphaM; + dData(loc++) = betaK; + dData(loc++) = betaK0; + dData(loc++) = betaKc; + + if (theChannel.sendVector(dbTag, commitTag, dData) < 0) { + opserr << "ForceBeamColumnCBDI3d::sendSelf() - failed to send Vector data\n"; + return -1; + } + + return 0; +} + +int +ForceBeamColumnCBDI3d::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +{ + // + // receive the integer data containing tag, numSections and coord transformation info + // + int dbTag = this->getDbTag(); + int i,j,k; + + static ID idData(11); // one bigger than needed + + if (theChannel.recvID(dbTag, commitTag, idData) < 0) { + opserr << "ForceBeamColumnCBDI3d::recvSelf() - failed to recv ID data\n"; + return -1; + } + + this->setTag(idData(0)); + connectedExternalNodes(0) = idData(1); + connectedExternalNodes(1) = idData(2); + maxIters = idData(4); + initialFlag = idData(5); + + int crdTransfClassTag = idData(6); + int crdTransfDbTag = idData(7); + + int beamIntegrClassTag = idData(8); + int beamIntegrDbTag = idData(9); + + // create a new crdTransf object if one needed + if (crdTransf == 0 || crdTransf->getClassTag() != crdTransfClassTag) { + if (crdTransf != 0) + delete crdTransf; + + crdTransf = theBroker.getNewCrdTransf(crdTransfClassTag); + + if (crdTransf == 0) { + opserr << "ForceBeamColumnCBDI3d::recvSelf() - failed to obtain a CrdTrans object with classTag" << + crdTransfClassTag << endln; + exit(-1); + } + } + + crdTransf->setDbTag(crdTransfDbTag); + + // invoke recvSelf on the coordTransf object + if (crdTransf->recvSelf(commitTag, theChannel, theBroker) < 0) + { + opserr << "ForceBeamColumnCBDI3d::sendSelf() - failed to recv crdTranf\n"; + + return -3; + } + + // create a new beamIntegr object if one needed + if (beamIntegr == 0 || beamIntegr->getClassTag() != beamIntegrClassTag) { + if (beamIntegr != 0) + delete beamIntegr; + + beamIntegr = theBroker.getNewBeamIntegration(beamIntegrClassTag); + + if (beamIntegr == 0) { + opserr << "ForceBeamColumnCBDI3d::recvSelf() - failed to obtain the beam integration object with classTag" << + beamIntegrClassTag << endln; + exit(-1); + } + } + + beamIntegr->setDbTag(beamIntegrDbTag); + + // invoke recvSelf on the beamIntegr object + if (beamIntegr->recvSelf(commitTag, theChannel, theBroker) < 0) + { + opserr << "ForceBeamColumnCBDI3d::sendSelf() - failed to recv beam integration\n"; + + return -3; + } + + // + // recv an ID for the sections containing each sections dbTag and classTag + // + + ID idSections(2*idData(3)); + int loc = 0; + + if (theChannel.recvID(dbTag, commitTag, idSections) < 0) { + opserr << "ForceBeamColumnCBDI3d::recvSelf() - failed to recv ID data\n"; + return -1; + } + + // + // now receive the sections + // + if (numSections != idData(3)) { + + // + // we do not have correct number of sections, must delete the old and create + // new ones before can recvSelf on the sections + // + + // delete the old + if (numSections != 0) { + for (int i=0; isetDbTag(sectDbTag); + if (sections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "ForceBeamColumnCBDI3d::recvSelf() - section " << + i << "failed to recv itself\n"; + return -1; + } + } + + this->initializeSectionHistoryVariables(); + + } else { + + // + // for each existing section, check it is of correct type + // (if not delete old & create a new one) then recvSelf on it + // + + loc = 0; + for (i=0; igetClassTag() != sectClassTag) { + // delete the old section[i] and create a new one + delete sections[i]; + sections[i] = theBroker.getNewSection(sectClassTag); + if (sections[i] == 0) { + opserr << "ForceBeamColumnCBDI3d::recvSelf() - Broker could not create Section of class type" << + sectClassTag << endln; + return -1; + } + } + + // recvvSelf on it + sections[i]->setDbTag(sectDbTag); + if (sections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "ForceBeamColumnCBDI3d::recvSelf() - section " << + i << "failed to recv itself\n"; + return -1; + } + } + } + + // into a vector place distrLoadCommit, rho, UeCommit, Secommit and kvcommit + int secDefSize = 0; + for (int ii = 0; ii < numSections; ii++) { + int size = sections[ii]->getOrder(); + secDefSize += size; + } + + Vector dData(1+1+NEBD+NEBD*NEBD+secDefSize+4); + + if (theChannel.recvVector(dbTag, commitTag, dData) < 0) { + opserr << "ForceBeamColumnCBDI3d::sendSelf() - failed to send Vector data\n"; + return -1; + } + + loc = 0; + + // place double variables into Vector + rho = dData(loc++); + tol = dData(loc++); + + // put distrLoadCommit into the Vector + //for (i=0; igetOrder(); + + // place vscommit into vector + vscommit[k] = Vector(order); + for (i = 0; i < order; i++) + (vscommit[k])(i) = dData(loc++); + } + + // set damping coefficients + alphaM = dData(loc++); + betaK = dData(loc++); + betaK0 = dData(loc++); + betaKc = dData(loc++); + + initialFlag = 2; + + return 0; +} + +int +ForceBeamColumnCBDI3d::getInitialFlexibility(Matrix &fe) +{ + fe.Zero(); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + // Flexibility from elastic interior + beamIntegr->addElasticFlexibility(L, fe); + + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + double wt[maxNumSections]; + beamIntegr->getSectionWeights(numSections, L, wt); + + for (int i = 0; i < numSections; i++) { + + int order = sections[i]->getOrder(); + const ID &code = sections[i]->getType(); + + Matrix fb(workArea, order, NEBD); + + double xL = xi[i]; + double xL1 = xL-1.0; + double wtL = wt[i]*L; + + const Matrix &fSec = sections[i]->getInitialFlexibility(); + fb.Zero(); + double tmp; + int ii, jj; + for (ii = 0; ii < order; ii++) { + switch(code(ii)) { + case SECTION_RESPONSE_P: + for (jj = 0; jj < order; jj++) + fb(jj,0) += fSec(jj,ii)*wtL; + break; + case SECTION_RESPONSE_MZ: + for (jj = 0; jj < order; jj++) { + tmp = fSec(jj,ii)*wtL; + fb(jj,1) += xL1*tmp; + fb(jj,2) += xL*tmp; + } + break; + case SECTION_RESPONSE_VY: + for (jj = 0; jj < order; jj++) { + tmp = oneOverL*fSec(jj,ii)*wtL; + fb(jj,1) += tmp; + fb(jj,2) += tmp; + } + break; + case SECTION_RESPONSE_MY: + for (jj = 0; jj < order; jj++) { + tmp = fSec(jj,ii)*wtL; + fb(jj,3) += xL1*tmp; + fb(jj,4) += xL*tmp; + } + break; + case SECTION_RESPONSE_VZ: + for (jj = 0; jj < order; jj++) { + tmp = oneOverL*fSec(jj,ii)*wtL; + fb(jj,3) += tmp; + fb(jj,4) += tmp; + } + break; + case SECTION_RESPONSE_T: + for (jj = 0; jj < order; jj++) + fb(jj,5) += fSec(jj,ii)*wtL; + break; + default: + break; + } + } + for (ii = 0; ii < order; ii++) { + switch (code(ii)) { + case SECTION_RESPONSE_P: + for (jj = 0; jj < NEBD; jj++) + fe(0,jj) += fb(ii,jj); + break; + case SECTION_RESPONSE_MZ: + for (jj = 0; jj < NEBD; jj++) { + tmp = fb(ii,jj); + fe(1,jj) += xL1*tmp; + fe(2,jj) += xL*tmp; + } + break; + case SECTION_RESPONSE_VY: + for (jj = 0; jj < NEBD; jj++) { + tmp = oneOverL*fb(ii,jj); + fe(1,jj) += tmp; + fe(2,jj) += tmp; + } + break; + case SECTION_RESPONSE_MY: + for (jj = 0; jj < NEBD; jj++) { + tmp = fb(ii,jj); + fe(3,jj) += xL1*tmp; + fe(4,jj) += xL*tmp; + } + break; + case SECTION_RESPONSE_VZ: + for (jj = 0; jj < NEBD; jj++) { + tmp = oneOverL*fb(ii,jj); + fe(3,jj) += tmp; + fe(4,jj) += tmp; + } + break; + case SECTION_RESPONSE_T: + for (jj = 0; jj < NEBD; jj++) + fe(5,jj) += fb(ii,jj); + break; + default: + break; + } + } + } + + return 0; +} + +int +ForceBeamColumnCBDI3d::getInitialDeformations(Vector &v0) +{ + v0.Zero(); + if (numEleLoads < 1) + return 0; + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + double wt[maxNumSections]; + beamIntegr->getSectionWeights(numSections, L, wt); + + for (int i = 0; i < numSections; i++) { + + int order = sections[i]->getOrder(); + const ID &code = sections[i]->getType(); + + double xL = xi[i]; + double xL1 = xL-1.0; + double wtL = wt[i]*L; + + static Vector sp; + sp.setData(workArea, order); + sp.Zero(); + + this->computeSectionForces(sp, i); + + const Matrix &fse = sections[i]->getInitialFlexibility(); + + static Vector e; + e.setData(&workArea[order], order); + + e.addMatrixVector(0.0, fse, sp, 1.0); + + double dei, tmp; + for (int ii = 0; ii < order; ii++) { + dei = e(ii)*wtL; + switch(code(ii)) { + case SECTION_RESPONSE_P: + v0(0) += dei; + break; + case SECTION_RESPONSE_MZ: + v0(1) += xL1*dei; v0(2) += xL*dei; + break; + case SECTION_RESPONSE_VY: + tmp = oneOverL*dei; + v0(1) += tmp; v0(2) += tmp; + break; + case SECTION_RESPONSE_MY: + v0(3) += xL1*dei; v0(4) += xL*dei; + break; + case SECTION_RESPONSE_VZ: + tmp = oneOverL*dei; + v0(3) += tmp; v0(4) += tmp; + break; + case SECTION_RESPONSE_T: + v0(5) += dei; + break; + default: + break; + } + } + } + + return 0; +} + +void +ForceBeamColumnCBDI3d::getG(int numSections, double xi[], Matrix &G) +{ + for (int i = 0; i < numSections; i++) { + G(i,0) = 1; + for (int j = 1; j < numSections; j++) + G(i,j) = pow(xi[i],j); + } + + return; +} + +void +ForceBeamColumnCBDI3d::getGinv(int numSections, double xi[], Matrix &Ginv) +{ + Matrix G(numSections, numSections); + this->getG(numSections, xi, G); + + Matrix I(numSections, numSections); + for (int i = 0; i < numSections; i++) + I(i,i) = 1.0; + + G.Solve(I, Ginv); +} + +void +ForceBeamColumnCBDI3d::getHk(int numSections, double xi[], Matrix &H) +{ + for (int i = 0; i < numSections; i++) { + for (int j = 0; j < numSections; j++) + H(i,j) = (pow(xi[i],j+2)-xi[i])/(j+1)/(j+2); + } + + return; +} + +void +ForceBeamColumnCBDI3d::getHkp(int numSections, double xi[], Matrix &H) +{ + for (int i = 0; i < numSections; i++) + for (int j = 0; j < numSections; j++) + H(i,j) = pow(xi[i],j+1)/(j+1) - 1.0/(j+1)/(j+2); +} + +void +ForceBeamColumnCBDI3d::getHg(int numSections, double xi[], Matrix &H) +{ + for (int i = 0; i < numSections; i++) { + H(i,0) = 0; + for (int j = 1; j < numSections; j++) + H(i,j) = (pow(xi[i],j+1)-xi[i])/(j+1); + } +} + +void +ForceBeamColumnCBDI3d::getHgp(int numSections, double xi[], Matrix &H) +{ + for (int i = 0; i < numSections; i++) { + H(i,0) = 0; + for (int j = 1; j < numSections; j++) + H(i,j) = pow(xi[i],j) - 1/(j+1); + } +} + +void +ForceBeamColumnCBDI3d::computedwdh(double dwidh[], int gradNumber, + const Vector &q) +{ + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + Matrix G(numSections, numSections); + this->getG(numSections, xi, G); + + Matrix Ginv(numSections, numSections); + this->getGinv(numSections, xi, Ginv); + + Matrix Hk(numSections, numSections); + this->getHk(numSections, xi, Hk); + + Matrix ls(numSections, numSections); + ls.addMatrixProduct(0.0, Hk, Ginv, 1.0); + + Matrix Hg(numSections, numSections); + this->getHg(numSections, xi, Hg); + + Matrix lsg(numSections, numSections); + lsg.addMatrixProduct(0.0, Hg, Ginv, 1.0); + + Matrix Hkp(numSections, numSections); + this->getHkp(numSections, xi, Hkp); + + Matrix lskp(numSections, numSections); + lskp.addMatrixProduct(0.0, Hkp, Ginv, 1.0); + + Matrix Hgp(numSections, numSections); + this->getHgp(numSections, xi, Hgp); + + Matrix lsgp(numSections, numSections); + lsgp.addMatrixProduct(0.0, Hgp, Ginv, 1.0); + + double dLdh = crdTransf->getdLdh(); + double dxidh[maxNumSections]; + beamIntegr->getLocationsDeriv(numSections, L, dLdh, dxidh); + + bool isdxidh = false; + for (int i = 0; i < numSections; i++) { + dxidh[i] = dxidh[i];// - xi[i]/L*dLdh; + if (dxidh[i] != 0.0) + isdxidh = true; + } + + Matrix A(2*numSections,2*numSections); + Vector b(2*numSections); + + Vector Fksdsdh(numSections); + Vector Fgsdsdh(numSections); + + Vector kappa(numSections); + Vector gamma(numSections); + + double q1 = q(0); + double q2q3 = q(1)+q(2); + + bool isGamma = false; + + for (int i = 0; i < numSections; i++) { + + const Matrix &fs = sections[i]->getSectionFlexibility(); + const Vector &dsdh = sections[i]->getStressResultantSensitivity(gradNumber,true); + Fksdsdh(i) = 0.0; + Fgsdsdh(i) = 0.0; + + double FkM = 0.0; + double FgM = 0.0; + double FkV = 0.0; + double FgV = 0.0; + + const ID &code = sections[i]->getType(); + int order = sections[i]->getOrder(); + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) { + FkM += fs(j,j); + kappa(i) += (vs[i])(j); + for (int k = 0; k < order; k++) { + Fksdsdh(i) -= fs(j,k)*dsdh(k); + if (code(k) == SECTION_RESPONSE_VY) + FkV += fs(j,k); + } + } + if (code(j) == SECTION_RESPONSE_VY) { + isGamma = true; + FgV += fs(j,j); + gamma(i) += (vs[i])(j); + for (int k = 0; k < order; k++) { + Fgsdsdh(i) -= fs(j,k)*dsdh(k); + if (code(k) == SECTION_RESPONSE_MZ) + FgM += fs(j,k); + } + } + } + + isGamma = CSBDI && isGamma; + + Fksdsdh(i) += q2q3*FkM*dxidh[i]; + + if (isGamma) { + Fksdsdh(i) += q2q3*oneOverL*oneOverL*FkV*dLdh; + Fgsdsdh(i) += q2q3*FgM*dxidh[i]; + Fgsdsdh(i) += q2q3*oneOverL*oneOverL*FgV*dLdh; + } + + A(i,i) = 1.0; + A(i+numSections,i+numSections) = 1.0; + + for (int j = 0; j < numSections; j++) { + A(j,i) -= q1*L*L*FkM*ls(j,i); + if (isGamma) { + A(j,i) -= q1*L*FgM*lsg(j,i); + + A(j,i+numSections) += q1*L*L*FkV*ls(j,i); + A(j,i+numSections) += q1*L*FgV*lsg(j,i); + + A(j+numSections,i) -= q1*L*FkM*lskp(j,i); + A(j+numSections,i) -= q1*FgM*lsgp(j,i); + + A(j+numSections,i+numSections) += q1*L*FkV*lskp(j,i); + A(j+numSections,i+numSections) += q1*FgV*lsgp(j,i); + } + } + } + + Vector mhs(numSections); + + mhs.addMatrixVector(0.0, ls, Fksdsdh, L*L); + mhs.addMatrixVector(1.0, ls, kappa, 2*L*dLdh); + if (isGamma) { + mhs.addMatrixVector(1.0, lsg, Fgsdsdh, L); + mhs.addMatrixVector(1.0, lsg, gamma, dLdh); + } + for (int i = 0; i < numSections; i++) + b(i) = mhs(i); + + if (isGamma) { + mhs.addMatrixVector(0.0, lskp, Fksdsdh, L); + mhs.addMatrixVector(1.0, lsgp, Fgsdsdh, 1.0); + mhs.addMatrixVector(1.0, lskp, kappa, dLdh); + //mhs.addMatrixVector(1.0, lsgp, gamma, 0*dLdh); + for (int i = 0; i < numSections; i++) + b(i+numSections) = mhs(i); + } + + + if (isdxidh) { + Matrix dGdh(numSections, numSections); + for (int i = 0; i < numSections; i++) { + dGdh(i,0) = 0; + for (int j = 1; j < numSections; j++) { + dGdh(i,j) = j*pow(xi[i],j-1)*dxidh[i]; + } + } + + Matrix dlsdh(numSections, numSections); + + + + + Matrix dHkdh(numSections, numSections); + for (int i = 0; i < numSections; i++) { + for (int j = 0; j < numSections; j++) { + dHkdh(i,j) = (pow(xi[i],j+1)/(j+1)-1.0/(j+1)/(j+2))*dxidh[i]; + } + } + dlsdh.addMatrixProduct(0.0, dHkdh, Ginv, 1.0); + dlsdh.addMatrixProduct(1.0, ls*dGdh, Ginv, -1.0); + mhs.addMatrixVector(0.0, dlsdh, kappa, L*L); + + if (isGamma) { + Matrix dHgdh(numSections, numSections); + for (int i = 0; i < numSections; i++) { + for (int j = 0; j < numSections; j++) { + dHgdh(i,j) = (pow(xi[i],j) - 1.0/(j+1))*dxidh[i]; + } + } + dlsdh.addMatrixProduct(0.0, dHgdh, Ginv, 1.0); + dlsdh.addMatrixProduct(1.0, lsg*dGdh, Ginv, -1.0); + mhs.addMatrixVector(1.0, dlsdh, gamma, L); + } + + for (int i = 0; i < numSections; i++) + b(i) += mhs(i); + + + + if (isGamma) { + Matrix dHkpdh(numSections, numSections); + for (int i = 0; i < numSections; i++) { + for (int j = 0; j < numSections; j++) { + dHkpdh(i,j) = pow(xi[i],j)*dxidh[i]; + } + } + dlsdh.addMatrixProduct(0.0, dHkpdh, Ginv, 1.0); + dlsdh.addMatrixProduct(1.0, lskp*dGdh, Ginv, -1.0); + mhs.addMatrixVector(0.0, dlsdh, kappa, L); + + Matrix dHgpdh(numSections, numSections); + for (int i = 0; i < numSections; i++) { + dHgpdh(i,0) = 0.0; + for (int j = 1; j < numSections; j++) { + dHgpdh(i,j) = (j*pow(xi[i],j-1))*dxidh[i]; + } + } + dlsdh.addMatrixProduct(0.0, dHgpdh, Ginv, 1.0); + dlsdh.addMatrixProduct(1.0, lsgp*dGdh, Ginv, -1.0); + mhs.addMatrixVector(1.0, dlsdh, gamma, 1.0); + + for (int i = 0; i < numSections; i++) + b(i+numSections) += mhs(i); + } + } + + + + Vector ajs(dwidh, 2*numSections); + + A.Solve(b, ajs); + + return; +} + +void +ForceBeamColumnCBDI3d::computew(Vector &w, Vector &wp, double xi[], + const Vector &kappa, const Vector &gamma) +{ + double L = crdTransf->getInitialLength(); + + Matrix ls(numSections, numSections); + + Matrix Ginv(numSections, numSections); + this->getGinv(numSections, xi, Ginv); + + Matrix H(numSections, numSections); + + bool isGamma = false; + for (int i = 0; i < numSections; i++) { + if (gamma(i) != 0.0) + isGamma = true; + } + isGamma = CSBDI && isGamma; + + this->getHk(numSections, xi, H); + ls.addMatrixProduct(0.0, H, Ginv, 1.0); + w.addMatrixVector(0.0, ls, kappa, L*L); + + if (isGamma) { + this->getHg(numSections, xi, H); + ls.addMatrixProduct(0.0, H, Ginv, 1.0); + w.addMatrixVector(1.0, ls, gamma, L); + + this->getHkp(numSections, xi, H); + ls.addMatrixProduct(0.0, H, Ginv, 1.0); + wp.addMatrixVector(0.0, ls, kappa, L); + + this->getHgp(numSections, xi, H); + ls.addMatrixProduct(0.0, H, Ginv, 1.0); + wp.addMatrixVector(1.0, ls, gamma, 1.0); + } +} + +void +ForceBeamColumnCBDI3d::computedwdq(Matrix &dwidq, const Vector &q, + const Vector &w, const Vector &wp, + const Matrix &lsk, const Matrix &lsg, + const Matrix &lskp, const Matrix &lsgp) +{ + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + Matrix A(2*numSections,2*numSections); + Matrix b(2*numSections,NEBD); + + Matrix Fksb(numSections,NEBD); + Matrix Fgsb(numSections,NEBD); + + bool isGamma = false; + + for (int i = 0; i < numSections; i++) { + + const Matrix &fs = sections[i]->getSectionFlexibility(); + + double FkM = 0.0; + double FgM = 0.0; + double FkV = 0.0; + double FgV = 0.0; + + int order = sections[i]->getOrder(); + const ID &code = sections[i]->getType(); + for (int j = 0; j < order; j++) { + + if (code(j) == SECTION_RESPONSE_MZ) { + FkM += fs(j,j); + + for (int k = 0; k < order; k++) { + if (code(k) == SECTION_RESPONSE_P) + Fksb(i,0) += fs(j,k); + if (code(k) == SECTION_RESPONSE_MZ) { + Fksb(i,0) += w(i)*fs(j,k); + Fksb(i,1) += (xi[i]-1)*fs(j,k); + Fksb(i,2) += xi[i]*fs(j,k); + } + if (code(k) == SECTION_RESPONSE_VY) { + FkV += fs(j,k); + + Fksb(i,0) -= wp(i)*fs(j,k); + Fksb(i,1) -= oneOverL*fs(j,k); + Fksb(i,2) -= oneOverL*fs(j,k); + } + } + } + if (code(j) == SECTION_RESPONSE_VY) { + isGamma = true; + FgV += fs(j,j); + + for (int k = 0; k < order; k++) { + if (code(k) == SECTION_RESPONSE_P) + Fgsb(i,0) += fs(j,k); + if (code(k) == SECTION_RESPONSE_MZ) { + FgM += fs(j,k); + + Fgsb(i,0) += w(i)*fs(j,k); + Fgsb(i,1) += (xi[i]-1)*fs(j,k); + Fgsb(i,2) += xi[i]*fs(j,k); + } + if (code(k) == SECTION_RESPONSE_VY) { + Fgsb(i,0) -= wp(i)*fs(j,k); + Fgsb(i,1) -= oneOverL*fs(j,k); + Fgsb(i,2) -= oneOverL*fs(j,k); + } + } + } + } + + isGamma = CSBDI && isGamma; + + A(i,i) = 1.0; + A(i+numSections,i+numSections) = 1.0; + + double q1 = q(0); + + for (int j = 0; j < numSections; j++) { + A(j,i) -= q1*L*L*FkM*lsk(j,i); + if (isGamma) { + A(j,i) -= q1*L*FgM*lsg(j,i); + + A(j,i+numSections) += q1*L*L*FkV*lsk(j,i); + A(j,i+numSections) += q1*L*FgV*lsg(j,i); + + A(j+numSections,i) -= q1*L*FkM*lskp(j,i); + A(j+numSections,i) -= q1*FgM*lsgp(j,i); + + A(j+numSections,i+numSections) += q1*L*FkV*lskp(j,i); + A(j+numSections,i+numSections) += q1*FgV*lsgp(j,i); + } + } + } + + Matrix mhs(numSections,NEBD); + + mhs.addMatrixProduct(0.0, lsk, Fksb, L*L); + if (isGamma) + mhs.addMatrixProduct(1.0, lsg, Fgsb, L); + + for (int i = 0; i < numSections; i++) + for (int j = 0; j < NEBD; j++) + b(i,j) = mhs(i,j); + + if (isGamma) { + mhs.addMatrixProduct(0.0, lskp, Fksb, L); + mhs.addMatrixProduct(1.0, lsgp, Fgsb, 1.0); + for (int i = 0; i < numSections; i++) + for (int j = 0; j < NEBD; j++) + b(i+numSections,j) = mhs(i,j); + } + + A.Solve(b, dwidq); + + return; +} + +void +ForceBeamColumnCBDI3d::computedwzdq(Matrix &dwzidq, const Vector &q, + const Vector &wz, const Vector &wpz, + const Matrix &lsk, const Matrix &lsg, + const Matrix &lskp, const Matrix &lsgp) +{ + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + Matrix A(2*numSections,2*numSections); + Matrix b(2*numSections,NEBD); + + Matrix Fksb(numSections,NEBD); + Matrix Fgsb(numSections,NEBD); + + bool isGamma = false; + + for (int i = 0; i < numSections; i++) { + + const Matrix &fs = sections[i]->getSectionFlexibility(); + + double FkM = 0.0; + double FgM = 0.0; + double FkV = 0.0; + double FgV = 0.0; + + int order = sections[i]->getOrder(); + const ID &code = sections[i]->getType(); + for (int j = 0; j < order; j++) { + + if (code(j) == SECTION_RESPONSE_MY) { + FkM += fs(j,j); + + for (int k = 0; k < order; k++) { + if (code(k) == SECTION_RESPONSE_P) + Fksb(i,0) += fs(j,k); + if (code(k) == SECTION_RESPONSE_MY) { + Fksb(i,0) += wz(i)*fs(j,k); + Fksb(i,3) += (xi[i]-1)*fs(j,k); + Fksb(i,4) += xi[i]*fs(j,k); + } + if (code(k) == SECTION_RESPONSE_VZ) { + FkV += fs(j,k); + + Fksb(i,0) -= wpz(i)*fs(j,k); + Fksb(i,3) -= oneOverL*fs(j,k); + Fksb(i,4) -= oneOverL*fs(j,k); + } + } + } + if (code(j) == SECTION_RESPONSE_VZ) { + isGamma = true; + FgV += fs(j,j); + + for (int k = 0; k < order; k++) { + if (code(k) == SECTION_RESPONSE_P) + Fgsb(i,0) += fs(j,k); + if (code(k) == SECTION_RESPONSE_MY) { + FgM += fs(j,k); + + Fgsb(i,0) += wz(i)*fs(j,k); + Fgsb(i,3) += (xi[i]-1)*fs(j,k); + Fgsb(i,4) += xi[i]*fs(j,k); + } + if (code(k) == SECTION_RESPONSE_VZ) { + Fgsb(i,0) -= wpz(i)*fs(j,k); + Fgsb(i,3) -= oneOverL*fs(j,k); + Fgsb(i,4) -= oneOverL*fs(j,k); + } + } + } + } + + isGamma = CSBDI && isGamma; + + A(i,i) = 1.0; + A(i+numSections,i+numSections) = 1.0; + + double q1 = q(0); + + for (int j = 0; j < numSections; j++) { + A(j,i) -= q1*L*L*FkM*lsk(j,i); + if (isGamma) { + A(j,i) -= q1*L*FgM*lsg(j,i); + + A(j,i+numSections) += q1*L*L*FkV*lsk(j,i); + A(j,i+numSections) += q1*L*FgV*lsg(j,i); + + A(j+numSections,i) -= q1*L*FkM*lskp(j,i); + A(j+numSections,i) -= q1*FgM*lsgp(j,i); + + A(j+numSections,i+numSections) += q1*L*FkV*lskp(j,i); + A(j+numSections,i+numSections) += q1*FgV*lsgp(j,i); + } + } + } + + Matrix mhs(numSections,NEBD); + + mhs.addMatrixProduct(0.0, lsk, Fksb, L*L); + if (isGamma) + mhs.addMatrixProduct(1.0, lsg, Fgsb, L); + + for (int i = 0; i < numSections; i++) + for (int j = 0; j < NEBD; j++) + b(i,j) = mhs(i,j); + + if (isGamma) { + mhs.addMatrixProduct(0.0, lskp, Fksb, L); + mhs.addMatrixProduct(1.0, lsgp, Fgsb, 1.0); + for (int i = 0; i < numSections; i++) + for (int j = 0; j < NEBD; j++) + b(i+numSections,j) = mhs(i,j); + } + + A.Solve(b, dwzidq); + + return; +} + +void ForceBeamColumnCBDI3d::compSectionDisplacements(Vector sectionCoords[], Vector sectionDispls[]) const +{ + // get basic displacements and increments + static Vector ub(NEBD); + ub = crdTransf->getBasicTrialDisp(); + + double L = crdTransf->getInitialLength(); + + // get integration point positions and weights + // const Matrix &xi_pt = quadRule.getIntegrPointCoords(numSections); + // get integration point positions and weights + static double xi_pts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi_pts); + + // setup Vandermode and CBDI influence matrices + int i; + double xi; + + // get CBDI influence matrix + Matrix ls(numSections, numSections); + getCBDIinfluenceMatrix(numSections, xi_pts, L, ls); + + // get section curvatures + Vector kappa(numSections); // curvature + static Vector vs; // section deformations + + for (i=0; igetType(); + int ii; + for (ii = 0; ii < code.Size(); ii++) + if (code(ii) == SECTION_RESPONSE_MZ) + { + sectionKey = ii; + break; + } + + if (ii == code.Size()) { + opserr << "FATAL NLBeamColumnCBDI3d::compSectionDispls - section does not provide Mz response\n"; + exit(-1); + } + + // get section deformations + vs = sections[i]->getSectionDeformation(); + kappa(i) = vs(sectionKey); + } + + Vector w(numSections); + static Vector xl(NDM), uxb(NDM); + static Vector xg(NDM), uxg(NDM); + + // w = ls * kappa; + w.addMatrixVector (0.0, ls, kappa, 1.0); + + for (i=0; igetPointGlobalCoordFromLocal(xl); + + // compute section displacements + uxb(0) = xi * ub(0); // consider linear variation for axial displacement. CHANGE LATER!!!!!!!!!! + uxb(1) = w(i); + + // get section displacements in global system + sectionDispls[i] = crdTransf->getPointGlobalDisplFromBasic(xi, uxb); + } + return; +} + +void +ForceBeamColumnCBDI3d::Print(OPS_Stream &s, int flag) +{ + if (flag == 2) { + + s << "#ForceBeamColumnCBDI2D\n"; + + const Vector &node1Crd = theNodes[0]->getCrds(); + const Vector &node2Crd = theNodes[1]->getCrds(); + const Vector &node1Disp = theNodes[0]->getDisp(); + const Vector &node2Disp = theNodes[1]->getDisp(); + + s << "#NODE " << node1Crd(0) << " " << node1Crd(1) + << " " << node1Disp(0) << " " << node1Disp(1) << " " << node1Disp(2) << endln; + + s << "#NODE " << node2Crd(0) << " " << node2Crd(1) + << " " << node2Disp(0) << " " << node2Disp(1) << " " << node2Disp(2) << endln; + + double P = Secommit(0); + double M1 = Secommit(1); + double M2 = Secommit(2); + double L = crdTransf->getInitialLength(); + double V = (M1+M2)/L; + + double p0[6]; + p0[0] = 0.0; p0[1] = 0.0; p0[2] = 0.0; + p0[3] = 0.0; p0[4] = 0.0; p0[5] = 0.0; + if (numEleLoads > 0) + this->computeReactions(p0); + + s << "#END_FORCES " << -P+p0[0] << " " << V+p0[1] << " " << M1 << endln; + s << "#END_FORCES " << P << " " << -V+p0[2] << " " << M2 << endln; + + // plastic hinge rotation + static Vector vp(6); + static Matrix fe(6,6); + this->getInitialFlexibility(fe); + vp = crdTransf->getBasicTrialDisp(); + vp.addMatrixVector(1.0, fe, Se, -1.0); + s << "#PLASTIC_HINGE_ROTATION " << vp[1] << " " << vp[2] << " " << 0.1*L << " " << 0.1*L << endln; +/* + // allocate array of vectors to store section coordinates and displacements + static int maxNumSections = 0; + static Vector *coords = 0; + static Vector *displs = 0; + if (maxNumSections < numSections) { + if (coords != 0) + delete [] coords; + if (displs != 0) + delete [] displs; + + coords = new Vector [numSections]; + displs = new Vector [numSections]; + + if (!coords) { + opserr << "NLBeamColumn3d::Print() -- failed to allocate coords array"; + exit(-1); + } + + int i; + for (i = 0; i < numSections; i++) + coords[i] = Vector(NDM); + + if (!displs) { + opserr << "NLBeamColumn3d::Print() -- failed to allocate coords array"; + exit(-1); + } + + for (i = 0; i < numSections; i++) + displs[i] = Vector(NDM); + + + maxNumSections = numSections; + } + + // compute section location & displacements + this->compSectionDisplacements(coords, displs); + + // spit out the section location & invoke print on the scetion + for (int i=0; iPrint(s, flag); + } + */ + } + + if (flag == OPS_PRINT_CURRENTSTATE) { + + s << "\nEment: " << this->getTag() << " Type: ForceBeamColumnCBDI3d "; + s << "\tConnected Nodes: " << connectedExternalNodes ; + s << "\tNumber of Sections: " << numSections; + s << "\tMass density: " << rho << endln; + beamIntegr->Print(s, flag); + double P = Secommit(0); + double M1 = Secommit(1); + double M2 = Secommit(2); + double L = crdTransf->getInitialLength(); + double V = (M1+M2)/L; + theVector(1) = V; + theVector(4) = -V; + double p0[6]; + p0[0] = 0.0; p0[1] = 0.0; p0[2] = 0.0; + p0[3] = 0.0; p0[4] = 0.0; p0[5] = 0.0; + if (numEleLoads > 0) + this->computeReactions(p0); + + s << "\tEnd 1 Forces (P V M): " << -P+p0[0] << " " << V+p0[1] << " " << M1 << endln; + s << "\tEnd 2 Forces (P V M): " << P << " " << -V+p0[2] << " " << M2 << endln; + + if (flag == 1) { + for (int i = 0; i < numSections; i++) + s << "\nSection "<getTag() << ", "; + s << "\"type\": \"ForceBeamColumnCBDI3d\", "; + s << "\"nodes\": [" << connectedExternalNodes(0) << ", " << connectedExternalNodes(1) << "], "; + s << "\"sections\": ["; + for (int i = 0; i < numSections - 1; i++) + s << "\"" << sections[i]->getTag() << "\", "; + s << "\"" << sections[numSections - 1]->getTag() << "\"], "; + s << "\"integration\": "; + beamIntegr->Print(s, flag); + s << ", \"massperlength\": " << rho << ", "; + s << "\"crdTransformation\": \"" << crdTransf->getTag() << "\"}"; + } +} + +OPS_Stream &operator<<(OPS_Stream &s, ForceBeamColumnCBDI3d &E) +{ + E.Print(s); + return s; +} + + +void +ForceBeamColumnCBDI3d::setSectionPointers(int numSec, SectionForceDeformation **secPtrs) +{ + if (numSec > maxNumSections) { + opserr << "Error: ForceBeamColumnCBDI3d::setSectionPointers -- max number of sections exceeded"; + } + + numSections = numSec; + + if (secPtrs == 0) { + opserr << "Error: ForceBeamColumnCBDI3d::setSectionPointers -- invalid section pointer"; + } + + sections = new SectionForceDeformation *[numSections]; + if (sections == 0) { + opserr << "Error: ForceBeamColumnCBDI3d::setSectionPointers -- could not allocate section pointers"; + } + + for (int i = 0; i < numSections; i++) { + + if (secPtrs[i] == 0) { + opserr << "Error: ForceBeamColumnCBDI3d::setSectionPointers -- null section pointer " << i << endln; + } + + sections[i] = secPtrs[i]->getCopy(); + + if (sections[i] == 0) { + opserr << "Error: ForceBeamColumnCBDI3d::setSectionPointers -- could not create copy of section " << i << endln; + } + } + + // allocate section flexibility matrices and section deformation vectors + fs = new Matrix [numSections]; + if (fs == 0) { + opserr << "ForceBeamColumnCBDI3d::setSectionPointers -- failed to allocate fs array"; + } + + vs = new Vector [numSections]; + if (vs == 0) { + opserr << "ForceBeamColumnCBDI3d::setSectionPointers -- failed to allocate vs array"; + } + + Ssr = new Vector [numSections]; + if (Ssr == 0) { + opserr << "ForceBeamColumnCBDI3d::setSectionPointers -- failed to allocate Ssr array"; + } + + vscommit = new Vector [numSections]; + if (vscommit == 0) { + opserr << "ForceBeamColumnCBDI3d::setSectionPointers -- failed to allocate vscommit array"; + } + +} + +int +ForceBeamColumnCBDI3d::displaySelf(Renderer &theViewer, int displayMode, float fact, const char **modes, int numMode) +{ + // first determine the end points of the beam based on + // the display factor (a measure of the distorted image) + const Vector &end1Crd = theNodes[0]->getCrds(); + const Vector &end2Crd = theNodes[1]->getCrds(); + + static Vector v1(3); + static Vector v2(3); + + if (displayMode >= 0) { + const Vector &end1Disp = theNodes[0]->getDisp(); + const Vector &end2Disp = theNodes[1]->getDisp(); + + for (int i = 0; i < 3; i++) { + v1(i) = end1Crd(i) + end1Disp(i)*fact; + v2(i) = end2Crd(i) + end2Disp(i)*fact; + } + } else { + int mode = displayMode * -1; + const Matrix &eigen1 = theNodes[0]->getEigenvectors(); + const Matrix &eigen2 = theNodes[1]->getEigenvectors(); + if (eigen1.noCols() >= mode) { + for (int i = 0; i < 3; i++) { + v1(i) = end1Crd(i) + eigen1(i,mode-1)*fact; + v2(i) = end2Crd(i) + eigen2(i,mode-1)*fact; + } + } else { + for (int i = 0; i < 3; i++) { + v1(i) = end1Crd(i); + v2(i) = end2Crd(i); + } + } + } + + return theViewer.drawLine (v1, v2, 1.0, 1.0); +} + +Response* +ForceBeamColumnCBDI3d::setResponse(const char **argv, int argc, OPS_Stream &output) +{ + Response *theResponse = 0; + + output.tag("ElementOutput"); + output.attr("eleType","ForceBeamColumnCBDI3d"); + output.attr("eleTag",this->getTag()); + output.attr("node1",connectedExternalNodes[0]); + output.attr("node2",connectedExternalNodes[1]); + + // global force - + if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0 + || strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0) { + + output.tag("ResponseType","Px_1"); + output.tag("ResponseType","Py_1"); + output.tag("ResponseType","Mz_1"); + output.tag("ResponseType","Px_2"); + output.tag("ResponseType","Py_2"); + output.tag("ResponseType","Mz_2"); + + theResponse = new ElementResponse(this, 1, theVector); + + + // local force - + } else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0) { + + output.tag("ResponseType","N_1"); + output.tag("ResponseType","V_1"); + output.tag("ResponseType","M_1"); + output.tag("ResponseType","N_2"); + output.tag("ResponseType","V_2"); + output.tag("ResponseType","M_2"); + + theResponse = new ElementResponse(this, 2, theVector); + + + // basic force - + } else if (strcmp(argv[0],"basicForce") == 0 || strcmp(argv[0],"basicForces") == 0) { + + output.tag("ResponseType","N"); + output.tag("ResponseType","M_1"); + output.tag("ResponseType","M_2"); + + theResponse = new ElementResponse(this, 7, Vector(6)); + + // chord rotation - + } else if (strcmp(argv[0],"chordRotation") == 0 || strcmp(argv[0],"chordDeformation") == 0 + || strcmp(argv[0],"basicDeformation") == 0) { + + output.tag("ResponseType","eps"); + output.tag("ResponseType","theta_1"); + output.tag("ResponseType","theta_2"); + + theResponse = new ElementResponse(this, 3, Vector(6)); + + // plastic rotation - + } else if (strcmp(argv[0],"plasticRotation") == 0 || strcmp(argv[0],"plasticDeformation") == 0) { + + output.tag("ResponseType","epsP"); + output.tag("ResponseType","thetaP_1"); + output.tag("ResponseType","thetaP_2"); + + theResponse = new ElementResponse(this, 4, Vector(6)); + + // point of inflection + } else if (strcmp(argv[0],"inflectionPoint") == 0) { + + output.tag("ResponseType","inflectionPoint"); + + theResponse = new ElementResponse(this, 5, 0.0); + + // tangent drift + } else if (strcmp(argv[0],"tangentDrift") == 0) { + theResponse = new ElementResponse(this, 6, Vector(4)); + + // basic forces + } else if (strcmp(argv[0],"basicForce") == 0) + theResponse = new ElementResponse(this, 7, Se); + + /* + // Curvature sensitivity + else if (strcmp(argv[0],"dcurvdh") == 0) + return new ElementResponse(this, 7, Vector(numSections)); + + // basic deformation sensitivity + else if (strcmp(argv[0],"dvdh") == 0) + return new ElementResponse(this, 8, Vector(3)); + */ + + // plastic deformation sensitivity + else if (strcmp(argv[0],"dvpdh") == 0) + return new ElementResponse(this, 9, Vector(6)); + + // basic force sensitivity + else if (strcmp(argv[0],"dqdh") == 0) + return new ElementResponse(this, 12, Vector(6)); + + else if (strcmp(argv[0],"integrationPoints") == 0) + theResponse = new ElementResponse(this, 10, Vector(numSections)); + + else if (strcmp(argv[0],"integrationWeights") == 0) + theResponse = new ElementResponse(this, 11, Vector(numSections)); + + else if (strcmp(argv[0],"sectionDisplacements") == 0) + theResponse = new ElementResponse(this, 111, Matrix(numSections,3)); + + else if (strcmp(argv[0],"cbdiDisplacements") == 0) + theResponse = new ElementResponse(this, 112, Matrix(20,3)); + + else if (strcmp(argv[0],"xaxis") == 0 || strcmp(argv[0],"xlocal") == 0) + theResponse = new ElementResponse(this, 201, Vector(3)); + + else if (strcmp(argv[0],"yaxis") == 0 || strcmp(argv[0],"ylocal") == 0) + theResponse = new ElementResponse(this, 202, Vector(3)); + + else if (strcmp(argv[0],"zaxis") == 0 || strcmp(argv[0],"zlocal") == 0) + theResponse = new ElementResponse(this, 203, Vector(3)); + + // section response - + else if (strstr(argv[0],"sectionX") != 0) { + if (argc > 2) { + float sectionLoc = atof(argv[1]); + + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamIntegr->getSectionLocations(numSections, L, xi); + + sectionLoc /= L; + + float minDistance = fabs(xi[0]-sectionLoc); + int sectionNum = 0; + for (int i = 1; i < numSections; i++) { + if (fabs(xi[i]-sectionLoc) < minDistance) { + minDistance = fabs(xi[i]-sectionLoc); + sectionNum = i; + } + } + + output.tag("GaussPointOutput"); + output.attr("number",sectionNum+1); + output.attr("eta",xi[sectionNum]*L); + + if (strcmp(argv[2],"dsdh") != 0) { + theResponse = sections[sectionNum]->setResponse(&argv[2], argc-2, output); + } else { + int order = sections[sectionNum]->getOrder(); + theResponse = new ElementResponse(this, 76, Vector(order)); + Information &info = theResponse->getInformation(); + info.theInt = sectionNum; + } + } + } + + // section response - + else if (strstr(argv[0],"section") != 0) { + + if (argc > 1) { + + int sectionNum = atoi(argv[1]); + + if (sectionNum > 0 && sectionNum <= numSections && argc > 2) { + + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamIntegr->getSectionLocations(numSections, L, xi); + + output.tag("GaussPointOutput"); + output.attr("number",sectionNum); + output.attr("eta",xi[sectionNum-1]*L); + + if (strcmp(argv[2],"dsdh") != 0) { + theResponse = sections[sectionNum-1]->setResponse(&argv[2], argc-2, output); + } else { + int order = sections[sectionNum-1]->getOrder(); + theResponse = new ElementResponse(this, 76, Vector(order)); + Information &info = theResponse->getInformation(); + info.theInt = sectionNum; + } + + output.endTag(); + + } else if (sectionNum == 0) { // argv[1] was not an int, we want all sections, + + CompositeResponse *theCResponse = new CompositeResponse(); + int numResponse = 0; + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamIntegr->getSectionLocations(numSections, L, xi); + + for (int i=0; isetResponse(&argv[1], argc-1, output); + + if (theSectionResponse != 0) { + numResponse = theCResponse->addResponse(theSectionResponse); + } + + output.endTag(); + + } + + if (numResponse == 0) // no valid responses found + delete theCResponse; + else + theResponse = theCResponse; + + } + } + } + + output.endTag(); // ElementOutput + + return theResponse; +} + +int +ForceBeamColumnCBDI3d::getResponse(int responseID, Information &eleInfo) +{ + static Vector vp(6); + static Matrix fe(6,6); + + if (responseID == 1) + return eleInfo.setVector(this->getResistingForce()); + + else if (responseID == 2) { + double p0[6]; + p0[0] = 0.0; p0[1] = 0.0; p0[2] = 0.0; + p0[3] = 0.0; p0[4] = 0.0; p0[5] = 0.0; + if (numEleLoads > 0) + this->computeReactions(p0); + theVector(3) = Se(0); + theVector(0) = -Se(0)+p0[0]; + theVector(2) = Se(1); + theVector(5) = Se(2); + double V = (Se(1)+Se(2))/crdTransf->getInitialLength(); + theVector(1) = V+p0[1]; + theVector(4) = -V+p0[2]; + return eleInfo.setVector(theVector); + } + + // Chord rotation + else if (responseID == 7) { + return eleInfo.setVector(Se); + } + + // Chord rotation + else if (responseID == 3) { + vp = crdTransf->getBasicTrialDisp(); + return eleInfo.setVector(vp); + } + + // Plastic rotation + else if (responseID == 4) { + this->getInitialFlexibility(fe); + vp = crdTransf->getBasicTrialDisp(); + vp.addMatrixVector(1.0, fe, Se, -1.0); + static Vector v0(6); + this->getInitialDeformations(v0); + vp.addVector(1.0, v0, -1.0); + return eleInfo.setVector(vp); + } + + // Point of inflection + else if (responseID == 5) { + double LI = 0.0; + + if (fabs(Se(1)+Se(2)) > DBL_EPSILON) { + double L = crdTransf->getInitialLength(); + + LI = Se(1)/(Se(1)+Se(2))*L; + } + + return eleInfo.setDouble(LI); + } + + // Tangent drift + else if (responseID == 6) { + double d2 = 0.0; + double d3 = 0.0; + + double L = crdTransf->getInitialLength(); + + // Location of inflection point from node I + double LI = 0.0; + if (fabs(Se(1)+Se(2)) > DBL_EPSILON) + LI = Se(1)/(Se(1)+Se(2))*L; + + double wts[maxNumSections]; + beamIntegr->getSectionWeights(numSections, L, wts); + + double pts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, pts); + + int i; + for (i = 0; i < numSections; i++) { + double x = pts[i]*L; + if (x > LI) + continue; + const ID &type = sections[i]->getType(); + int order = sections[i]->getOrder(); + double kappa = 0.0; + for (int j = 0; j < order; j++) + if (type(j) == SECTION_RESPONSE_MZ) + kappa += vs[i](j); + double b = -LI+x; + d2 += (wts[i]*L)*kappa*b; + } + + d2 += beamIntegr->getTangentDriftI(L, LI, Se(1), Se(2)); + + for (i = numSections-1; i >= 0; i--) { + double x = pts[i]*L; + if (x < LI) + continue; + const ID &type = sections[i]->getType(); + int order = sections[i]->getOrder(); + double kappa = 0.0; + for (int j = 0; j < order; j++) + if (type(j) == SECTION_RESPONSE_MZ) + kappa += vs[i](j); + double b = x-LI; + d3 += (wts[i]*L)*kappa*b; + } + + d3 += beamIntegr->getTangentDriftJ(L, LI, Se(1), Se(2)); + + static Vector d(2); + d(0) = d2; + d(1) = d3; + + return eleInfo.setVector(d); + } + + else if (responseID == 7) + return eleInfo.setVector(Se); + + /* + // Curvature sensitivity + else if (responseID == 7) { + Vector curv(numSections); + for (int i = 0; i < numSections; i++) { + int order = sections[i]->getOrder(); + const ID &type = sections[i]->getType(); + const Vector &dedh = sections[i]->getdedh(); + for (int j = 0; j < order; j++) { + if (type(j) == SECTION_RESPONSE_MZ) + curv(i) = dedh(j); + } + } + return eleInfo.setVector(curv); + } + */ + + else if (responseID == 10) { + double L = crdTransf->getInitialLength(); + double pts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, pts); + Vector locs(numSections); + for (int i = 0; i < numSections; i++) + locs(i) = pts[i]*L; + return eleInfo.setVector(locs); + } + + else if (responseID == 11) { + double L = crdTransf->getInitialLength(); + double wts[maxNumSections]; + beamIntegr->getSectionWeights(numSections, L, wts); + Vector weights(numSections); + for (int i = 0; i < numSections; i++) + weights(i) = wts[i]*L; + return eleInfo.setVector(weights); + } + + else if (responseID == 111) { + double L = crdTransf->getInitialLength(); + double pts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, pts); + // CBDI influence matrix + Matrix ls(numSections, numSections); + getCBDIinfluenceMatrix(numSections, pts, L, ls); + // Curvature vector + Vector kappaz(numSections); // about section z + Vector kappay(numSections); // about section y + for (int i = 0; i < numSections; i++) { + const ID &code = sections[i]->getType(); + const Vector &e = sections[i]->getSectionDeformation(); + int order = sections[i]->getOrder(); + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + kappaz(i) += e(j); + if (code(j) == SECTION_RESPONSE_MY) + kappay(i) += e(j); + } + } + // Displacement vector + Vector dispsy(numSections); // along local y + Vector dispsz(numSections); // along local z + dispsy.addMatrixVector(0.0, ls, kappaz, 1.0); + dispsz.addMatrixVector(0.0, ls, kappay, -1.0); + beamIntegr->getSectionLocations(numSections, L, pts); + static Vector uxb(3); + static Vector uxg(3); + Matrix disps(numSections,3); + vp = crdTransf->getBasicTrialDisp(); + for (int i = 0; i < numSections; i++) { + uxb(0) = pts[i]*vp(0); // linear shape function + uxb(1) = dispsy(i); + uxb(2) = dispsz(i); + uxg = crdTransf->getPointGlobalDisplFromBasic(pts[i],uxb); + disps(i,0) = uxg(0); + disps(i,1) = uxg(1); + disps(i,2) = uxg(2); + } + return eleInfo.setMatrix(disps); + } + + else if (responseID == 112) { + double L = crdTransf->getInitialLength(); + double ipts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, ipts); + // CBDI influence matrix + double pts[20]; + for (int i = 0; i < 20; i++) + pts[i] = 1.0/(20-1)*i; + Matrix ls(20, numSections); + getCBDIinfluenceMatrix(20, pts, numSections, ipts, L, ls); + // Curvature vector + Vector kappaz(numSections); // about section z + Vector kappay(numSections); // about section y + for (int i = 0; i < numSections; i++) { + const ID &code = sections[i]->getType(); + const Vector &e = sections[i]->getSectionDeformation(); + int order = sections[i]->getOrder(); + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + kappaz(i) += e(j); + if (code(j) == SECTION_RESPONSE_MY) + kappay(i) += e(j); + } + } + // Displacement vector + Vector dispsy(20); // along local y + Vector dispsz(20); // along local z + dispsy.addMatrixVector(0.0, ls, kappaz, 1.0); + dispsz.addMatrixVector(0.0, ls, kappay, -1.0); + static Vector uxb(3); + static Vector uxg(3); + Matrix disps(20,3); + vp = crdTransf->getBasicTrialDisp(); + for (int i = 0; i < 20; i++) { + uxb(0) = pts[i]*vp(0); // linear shape function + uxb(1) = dispsy(i); + uxb(2) = dispsz(i); + uxg = crdTransf->getPointGlobalDisplFromBasic(pts[i],uxb); + disps(i,0) = uxg(0); + disps(i,1) = uxg(1); + disps(i,2) = uxg(2); + } + return eleInfo.setMatrix(disps); + } + + else if (responseID >= 201 && responseID <= 203) { + static Vector xlocal(3); + static Vector ylocal(3); + static Vector zlocal(3); + + crdTransf->getLocalAxes(xlocal,ylocal,zlocal); + + if (responseID == 201) + return eleInfo.setVector(xlocal); + if (responseID == 202) + return eleInfo.setVector(ylocal); + if (responseID == 203) + return eleInfo.setVector(zlocal); + } + + else + return -1; +} + +int +ForceBeamColumnCBDI3d::getResponseSensitivity(int responseID, int gradNumber, + Information &eleInfo) +{ + // Basic deformation sensitivity + if (responseID == 3) { + const Vector &dvdh = crdTransf->getBasicDisplSensitivity(gradNumber); + return eleInfo.setVector(dvdh); + } + + // Basic force sensitivity + else if (responseID == 7) { + static Vector dqdh(6); + + const Vector &dvdh = crdTransf->getBasicDisplSensitivity(gradNumber); + + dqdh.addMatrixVector(0.0, kv, dvdh, 1.0); + + dqdh.addVector(1.0, this->computedqdh(gradNumber), 1.0); + //opserr << "FBC2d: " << gradNumber; + + return eleInfo.setVector(dqdh); + } + + // dsdh + else if (responseID == 76) { + + int sectionNum = eleInfo.theInt; + int order = sections[sectionNum-1]->getOrder(); + + Vector dsdh(workArea,order); + dsdh.Zero(); + + if (numEleLoads > 0) { + this->computeSectionForceSensitivity(dsdh, sectionNum-1, gradNumber); + } + //opserr << "FBC2d::getRespSens dspdh: " << dsdh; + static Vector dqdh(NEBD); + + const Vector &dvdh = crdTransf->getBasicDisplSensitivity(gradNumber); + + dqdh.addMatrixVector(0.0, kv, dvdh, 1.0); + + dqdh.addVector(1.0, this->computedqdh(gradNumber), 1.0); + + //opserr << "FBC2d::getRespSens dqdh: " << dqdh; + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + double pts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, pts); + + const ID &code = sections[sectionNum-1]->getType(); + + double xL = pts[sectionNum-1]; + double xL1 = xL-1.0; + + Vector kappa(numSections); + Vector gamma(numSections); + + bool isGamma = false; + + for (int i = 0; i < numSections; i++) { + int order = sections[i]->getOrder(); + const ID &code = sections[i]->getType(); + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + kappa(i) += (vs[i])(j); + if (code(j) == SECTION_RESPONSE_VY) { + isGamma = true; + gamma(i) += (vs[i])(j); + } + } + } + + isGamma = CSBDI && isGamma; + + double wi[maxNumSections]; + Vector w(wi, numSections); + double wpi[maxNumSections]; + Vector wp(wpi, numSections); + wp.Zero(); + this->computew(w, wp, pts, kappa, gamma); + + Matrix Ginv(numSections, numSections); + this->getGinv(numSections, pts, Ginv); + + Matrix ls(numSections, numSections); + Matrix Hk(numSections, numSections); + this->getHk(numSections, pts, Hk); + ls.addMatrixProduct(0.0, Hk, Ginv, 1.0); + + Matrix lsg(numSections, numSections); + Matrix Hg(numSections, numSections); + this->getHg(numSections, pts, Hg); + lsg.addMatrixProduct(0.0, Hg, Ginv, 1.0); + + Matrix lskp(numSections, numSections); + Matrix Hkp(numSections, numSections); + this->getHkp(numSections, pts, Hkp); + lskp.addMatrixProduct(0.0, Hkp, Ginv, 1.0); + + Matrix lsgp(numSections, numSections); + Matrix Hgp(numSections, numSections); + this->getHgp(numSections, pts, Hgp); + lsgp.addMatrixProduct(0.0, Hgp, Ginv, 1.0); + + Matrix dwidq(2*numSections,NEBD); + this->computedwdq(dwidq, Se, w, wp, ls, lsg, lskp, lsgp); + + double dwidh[2*maxNumSections]; + this->computedwdh(dwidh, gradNumber, Se); + + for (int ii = 0; ii < order; ii++) { + switch(code(ii)) { + case SECTION_RESPONSE_P: + dsdh(ii) += dqdh(0); + break; + case SECTION_RESPONSE_MZ: + dsdh(ii) += xL1*dqdh(1) + xL*dqdh(2); + dsdh(ii) += wi[sectionNum-1]*dqdh(0); + for (int jj = 0; jj < NEBD; jj++) + dsdh(ii) += Se(0)*dwidq(sectionNum-1,jj)*dqdh(jj); + dsdh(ii) += Se(0)*dwidh[sectionNum-1]; + break; + case SECTION_RESPONSE_VY: + dsdh(ii) -= oneOverL*(dqdh(1)+dqdh(2)); + dsdh(ii) -= wpi[sectionNum-1]*dqdh(0); + for (int jj = 0; jj < NEBD; jj++) + dsdh(ii) -= Se(0)*dwidq(numSections+sectionNum-1,jj)*dqdh(jj); + dsdh(ii) -= Se(0)*dwidh[numSections+sectionNum-1]; + break; + default: + dsdh(ii) += 0.0; + break; + } + } + + double dLdh = crdTransf->getdLdh(); + double d1oLdh = crdTransf->getd1overLdh(); + + double dptsdh[maxNumSections]; + beamIntegr->getLocationsDeriv(numSections, L, dLdh, dptsdh); + double dxLdh = dptsdh[sectionNum-1];// - xL/L*dLdh; + + for (int j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_MZ: + dsdh(j) += dxLdh*(Se(1)+Se(2)); + //dsdh(j) -= dLdh*xL/L*(Se(1)+Se(2)); + //dsdh(j) -= dxLdh*ti[sectionNum-1]*Se(0); + break; + case SECTION_RESPONSE_VY: + dsdh(j) -= d1oLdh*(Se(1)+Se(2)); + break; + default: + break; + } + } + + /* + opserr << "FBC2d::getRespSens dsdh=b*dqdh+dspdh: " << dsdh; + + dsdh.Zero(); + if (numEleLoads > 0) { + this->computeSectionForceSensitivity(dsdh, sectionNum-1, gradNumber); + } + const Matrix &ks = sections[sectionNum-1]->getSectionTangent(); + const Vector &dedh = sections[sectionNum-1]->getSectionDeformationSensitivity(gradNumber); + dsdh.addMatrixVector(1.0, ks, dedh, 1.0); + dsdh.addVector(1.0, sections[sectionNum-1]->getStressResultantSensitivity(gradNumber, true), 1.0); + + opserr << "FBC2d::getRespSens dsdh=b*dqdh+dspdh: " << dsdh; + */ + + return eleInfo.setVector(dsdh); + } + + // Plastic deformation sensitivity + else if (responseID == 4) { + static Vector dvpdh(6); + + const Vector &dvdh = crdTransf->getBasicDisplSensitivity(gradNumber); + + dvpdh = dvdh; + //opserr << dvpdh; + + static Matrix fe(6,6); + this->getInitialFlexibility(fe); + + const Vector &dqdh = this->computedqdh(gradNumber); + + dvpdh.addMatrixVector(1.0, fe, dqdh, -1.0); + //opserr << dvpdh; + + static Matrix fek(6,6); + fek.addMatrixProduct(0.0, fe, kv, 1.0); + + dvpdh.addMatrixVector(1.0, fek, dvdh, -1.0); + //opserr << dvpdh; + + const Matrix &dfedh = this->computedfedh(gradNumber); + + dvpdh.addMatrixVector(1.0, dfedh, Se, -1.0); + //opserr << dvpdh << endln; + //opserr << dfedh << endln; + + //opserr << dqdh + kv*dvdh << endln; + + return eleInfo.setVector(dvpdh); + } + + else + return -1; +} + +int +ForceBeamColumnCBDI3d::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc < 1) + return -1; + + int result = -1; + + if (strcmp(argv[0],"rho") == 0) + return param.addObject(1, this); + + // section response - + else if (strstr(argv[0],"sectionX") != 0) { + if (argc > 2) { + float sectionLoc = atof(argv[1]); + + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamIntegr->getSectionLocations(numSections, L, xi); + + sectionLoc /= L; + + float minDistance = fabs(xi[0]-sectionLoc); + int sectionNum = 0; + for (int i = 1; i < numSections; i++) { + if (fabs(xi[i]-sectionLoc) < minDistance) { + minDistance = fabs(xi[i]-sectionLoc); + sectionNum = i; + } + } + + return sections[sectionNum]->setParameter(&argv[2], argc-2, param); + } + } + + // If the parameter belongs to a section or lower + else if (strstr(argv[0],"section") != 0) { + + if (argc < 3) + return -1; + + // Get section number: 1...Np + int sectionNum = atoi(argv[1]); + + if (sectionNum > 0 && sectionNum <= numSections) + return sections[sectionNum-1]->setParameter(&argv[2], argc-2, param); + + else + return -1; + + /* + // Find the right section and call its setParameter method + int ok = 0; + for (int i = 0; i < numSections; i++) + if (paramSectionTag == sections[i]->getTag()) + ok += sections[i]->setParameter(&argv[2], argc-2, param); + + return ok; + */ + } + + else if (strstr(argv[0],"integration") != 0) { + + if (argc < 2) + return -1; + + return beamIntegr->setParameter(&argv[1], argc-1, param); + } + + // Default, send to everything + int ok; + + for (int i = 0; i < numSections; i++) { + ok = sections[i]->setParameter(argv, argc, param); + if (ok != -1) + result = ok; + } + + ok = beamIntegr->setParameter(argv, argc, param); + if (ok != -1) + result = ok; + + return result; +} + + + +int +ForceBeamColumnCBDI3d::updateParameter (int parameterID, Information &info) +{ + if (parameterID == 1) { + rho = info.theDouble; + return 0; + } + else + return -1; +} + +int +ForceBeamColumnCBDI3d::activateParameter(int passedParameterID) +{ + parameterID = passedParameterID; + + return 0; +} + +const Matrix& +ForceBeamColumnCBDI3d::getKiSensitivity(int gradNumber) +{ + theMatrix.Zero(); + return theMatrix; +} + +const Matrix& +ForceBeamColumnCBDI3d::getMassSensitivity(int gradNumber) +{ + theMatrix.Zero(); + return theMatrix; +} + +const Vector& +ForceBeamColumnCBDI3d::getResistingForceSensitivity(int gradNumber) +{ + static Vector dqdh(6); + dqdh = this->computedqdh(gradNumber); + + // Transform forces + double dp0dh[6]; + dp0dh[0] = 0.0; dp0dh[1] = 0.0; dp0dh[2] = 0.0; + dp0dh[3] = 0.0; dp0dh[4] = 0.0; dp0dh[5] = 0.0; + this->computeReactionSensitivity(dp0dh, gradNumber); + Vector dp0dhVec(dp0dh, 3); + + static Vector P(12); + P.Zero(); + + if (crdTransf->isShapeSensitivity()) { + // dAdh^T q + P = crdTransf->getGlobalResistingForceShapeSensitivity(Se, dp0dhVec, gradNumber); + // k dAdh u + const Vector &dAdh_u = crdTransf->getBasicTrialDispShapeSensitivity(); + dqdh.addMatrixVector(1.0, kv, dAdh_u, 1.0); + } + + // A^T (dqdh + k dAdh u) + P += crdTransf->getGlobalResistingForce(dqdh, dp0dhVec); + + return P; +} + +int +ForceBeamColumnCBDI3d::commitSensitivity(int gradNumber, int numGrads) +{ + int err = 0; + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + double pts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, pts); + + double wts[maxNumSections]; + beamIntegr->getSectionWeights(numSections, L, wts); + + double dLdh = crdTransf->getdLdh(); + + double dptsdh[maxNumSections]; + beamIntegr->getLocationsDeriv(numSections, L, dLdh, dptsdh); + + double d1oLdh = crdTransf->getd1overLdh(); + + static Vector dqdh(3); + dqdh = this->computedqdh(gradNumber); + + // dvdh = A dudh + dAdh u + const Vector &dvdh = crdTransf->getBasicDisplSensitivity(gradNumber); + dqdh.addMatrixVector(1.0, kv, dvdh, 1.0); // A dudh + + if (crdTransf->isShapeSensitivity()) { + //const Vector &dAdh_u = crdTransf->getBasicTrialDispShapeSensitivity(); + //dqdh.addMatrixVector(1.0, kv, dAdh_u, 1.0); // dAdh u + } + + bool isGamma = false; + + Vector kappa(numSections); + Vector gamma(numSections); + for (int i = 0; i < numSections; i++) { + int order = sections[i]->getOrder(); + const ID &code = sections[i]->getType(); + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + kappa(i) += (vs[i])(j); + if (code(j) == SECTION_RESPONSE_VY) { + gamma(i) += (vs[i])(j); + isGamma = true; + } + } + } + isGamma = CSBDI && isGamma; + + double wi[maxNumSections]; + Vector w(wi, numSections); + double wpi[maxNumSections]; + Vector wp(wpi, numSections); + wp.Zero(); + this->computew(w, wp, pts, kappa, gamma); + + Matrix Ginv(numSections, numSections); + this->getGinv(numSections, pts, Ginv); + + Matrix ls(numSections, numSections); + Matrix Hk(numSections, numSections); + this->getHk(numSections, pts, Hk); + ls.addMatrixProduct(0.0, Hk, Ginv, 1.0); + + Matrix lsg(numSections, numSections); + Matrix Hg(numSections, numSections); + this->getHg(numSections, pts, Hg); + lsg.addMatrixProduct(0.0, Hg, Ginv, 1.0); + + Matrix lskp(numSections, numSections); + Matrix Hkp(numSections, numSections); + this->getHkp(numSections, pts, Hkp); + lskp.addMatrixProduct(0.0, Hkp, Ginv, 1.0); + + Matrix lsgp(numSections, numSections); + Matrix Hgp(numSections, numSections); + this->getHgp(numSections, pts, Hgp); + lsgp.addMatrixProduct(0.0, Hgp, Ginv, 1.0); + + Matrix dwidq(2*numSections,NEBD); + this->computedwdq(dwidq, Se, w, wp, ls, lsg, lskp, lsgp); + + double dwidh[2*maxNumSections]; + this->computedwdh(dwidh, gradNumber, Se); + + // Loop over integration points + for (int i = 0; i < numSections; i++) { + + int order = sections[i]->getOrder(); + const ID &code = sections[i]->getType(); + + double xL = pts[i]; + double xL1 = xL-1.0; + + double dxLdh = dptsdh[i];// - xL/L*dLdh; + + Vector ds(workArea, order); + ds.Zero(); + + // Add sensitivity wrt element loads + if (numEleLoads > 0) { + this->computeSectionForceSensitivity(ds, i, gradNumber); + } + + int j; + for (j = 0; j < order; j++) { + switch(code(j)) { + case SECTION_RESPONSE_P: + ds(j) += dqdh(0); + break; + case SECTION_RESPONSE_MZ: + ds(j) += xL1*dqdh(1) + xL*dqdh(2); + ds(j) += wi[i]*dqdh(0); + break; + case SECTION_RESPONSE_VY: + ds(j) -= oneOverL*(dqdh(1)+dqdh(2)); + ds(j) -= wpi[i]*dqdh(0); + break; + default: + break; + } + } + + const Vector &dsdh = sections[i]->getStressResultantSensitivity(gradNumber,true); + ds -= dsdh; + + for (j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_MZ: + ds(j) += dxLdh*(Se(1)+Se(2)); + ds(j) += (dwidq(i,0)*dqdh(0)+dwidq(i,1)*dqdh(1)+dwidq(i,2)*dqdh(2) + dwidh[i])*Se(0); + break; + case SECTION_RESPONSE_VY: + ds(j) -= d1oLdh*(Se(1)+Se(2)); + ds(j) -= (dwidq(i+numSections,0)*dqdh(0)+dwidq(i+numSections,1)*dqdh(1)+dwidq(i+numSections,2)*dqdh(2) + dwidh[i+numSections])*Se(0); + break; + default: + break; + } + } + + Vector de(&workArea[order], order); + const Matrix &fs = sections[i]->getSectionFlexibility(); + de.addMatrixVector(0.0, fs, ds, 1.0); + + err += sections[i]->commitSensitivity(de, gradNumber, numGrads); + } + + return err; +} + +const Vector & +ForceBeamColumnCBDI3d::computedqdh(int gradNumber) +{ + //opserr << "FBC2d::computedqdh " << gradNumber << endln; + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + double pts[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, pts); + + double wts[maxNumSections]; + beamIntegr->getSectionWeights(numSections, L, wts); + + double dLdh = crdTransf->getdLdh(); + + double dptsdh[maxNumSections]; + beamIntegr->getLocationsDeriv(numSections, L, dLdh, dptsdh); + + double dwtsdh[maxNumSections]; + beamIntegr->getWeightsDeriv(numSections, L, dLdh, dwtsdh); + + double d1oLdh = crdTransf->getd1overLdh(); + + static Vector dvdh(NEBD); + dvdh.Zero(); + + Vector kappa(numSections); + Vector gamma(numSections); + for (int i = 0; i < numSections; i++) { + int order = sections[i]->getOrder(); + const ID &code = sections[i]->getType(); + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + kappa(i) += (vs[i])(j); + if (code(j) == SECTION_RESPONSE_VY) + gamma(i) += (vs[i])(j); + } + } + + double wi[maxNumSections]; + Vector w(wi, numSections); + double wpi[maxNumSections]; + Vector wp(wpi, numSections); + wp.Zero(); + this->computew(w, wp, pts, kappa, gamma); + + Matrix Ginv(numSections, numSections); + this->getGinv(numSections, pts, Ginv); + + double dwidh[2*maxNumSections]; + this->computedwdh(dwidh, gradNumber, Se); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = sections[i]->getOrder(); + const ID &code = sections[i]->getType(); + + double xL = pts[i]; + double xL1 = xL-1.0; + double wtL = wts[i]*L; + + double dxLdh = dptsdh[i];// - xL/L*dLdh; + double dwtLdh = wts[i]*dLdh + dwtsdh[i]*L; + + //opserr << dptsdh[i] << ' ' << dwtsdh[i] << endln; + + // Get section stress resultant gradient + Vector dsdh(&workArea[order], order); + dsdh = sections[i]->getStressResultantSensitivity(gradNumber,true); + //opserr << "FBC2d::dqdh -- " << gradNumber << ' ' << dsdh; + + Vector dspdh(&workArea[2*order], order); + dspdh.Zero(); + // Add sensitivity wrt element loads + if (numEleLoads > 0) { + this->computeSectionForceSensitivity(dspdh, i, gradNumber); + //opserr << "FBC2d::dspdh -- " << i << ' ' << dsdh; + } + dsdh.addVector(1.0, dspdh, -1.0); + + int j; + for (j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_MZ: + dsdh(j) -= dxLdh*(Se(1)+Se(2)); + //dsdh(j) += ti[i]*dxLdh*Se(0); + dsdh(j) -= dwidh[i]*Se(0); + //dsdh(j) += (2*wi[i]*oneOverL)*Se(0)*dLdh; + break; + case SECTION_RESPONSE_VY: + dsdh(j) += d1oLdh*(Se(1)+Se(2)); + dsdh(j) += dwidh[i+numSections]*Se(0); + break; + default: + break; + } + } + + Vector dedh(workArea, order); + const Matrix &fs = sections[i]->getSectionFlexibility(); + dedh.addMatrixVector(0.0, fs, dsdh, 1.0); + + for (j = 0; j < order; j++) { + double dei = dedh(j)*wtL; + switch(code(j)) { + case SECTION_RESPONSE_P: + dvdh(0) += dei; + break; + case SECTION_RESPONSE_MZ: + dvdh(1) += xL1*dei; + dvdh(2) += xL*dei; + dvdh(0) += 0.5*wi[i]*dei; + break; + case SECTION_RESPONSE_VY: + dei = oneOverL*dei; + dvdh(1) -= dei; + dvdh(2) -= dei; + dvdh(0) -= 0.5*wpi[i]*dei; + default: + break; + } + } + + const Vector &e = vs[i]; + for (j = 0; j < order; j++) { + switch(code(j)) { + case SECTION_RESPONSE_P: + dvdh(0) -= e(j)*dwtLdh; + break; + case SECTION_RESPONSE_MZ: + dvdh(1) -= xL1*e(j)*dwtLdh; + dvdh(2) -= xL*e(j)*dwtLdh; + dvdh(0) -= 0.5*wi[i]*e(j)*dwtLdh; + + dvdh(1) -= dxLdh*e(j)*wtL; + dvdh(2) -= dxLdh*e(j)*wtL; + //dvdh(0) += 0.5*ti[i]*dxLdh*e(j)*wtL; + dvdh(0) -= 0.5*dwidh[i]*e(j)*wtL; + + //dvdh(0) += (wi[i]*oneOverL)*dLdh*e(j)*wtL; + break; + case SECTION_RESPONSE_VY: + dvdh(1) += oneOverL*e(j)*dwtLdh; + dvdh(2) += oneOverL*e(j)*dwtLdh; + dvdh(0) += 0.5*wpi[i]*e(j)*dwtLdh; + + dvdh(1) += d1oLdh*e(j)*wtL; + dvdh(2) += d1oLdh*e(j)*wtL; + dvdh(0) += 0.5*dwidh[i+numSections]*e(j)*wtL; + break; + default: + break; + } + } + } + + static Matrix dfedh(6,6); + dfedh.Zero(); + + if (beamIntegr->addElasticFlexDeriv(L, dfedh, dLdh) < 0) + dvdh.addMatrixVector(1.0, dfedh, Se, -1.0); + + //opserr << "dfedh: " << dfedh << endln; + + static Vector dqdh(3); + dqdh.addMatrixVector(0.0, kv, dvdh, 1.0); + + //opserr << "dqdh: " << dqdh << endln; + + return dqdh; +} + +const Matrix& +ForceBeamColumnCBDI3d::computedfedh(int gradNumber) +{ + static Matrix dfedh(6,6); + + dfedh.Zero(); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + double dLdh = crdTransf->getdLdh(); + double d1oLdh = crdTransf->getd1overLdh(); + + beamIntegr->addElasticFlexDeriv(L, dfedh, dLdh); + + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + double wt[maxNumSections]; + beamIntegr->getSectionWeights(numSections, L, wt); + + double dptsdh[maxNumSections]; + beamIntegr->getLocationsDeriv(numSections, L, dLdh, dptsdh); + + double dwtsdh[maxNumSections]; + beamIntegr->getWeightsDeriv(numSections, L, dLdh, dwtsdh); + + for (int i = 0; i < numSections; i++) { + + int order = sections[i]->getOrder(); + const ID &code = sections[i]->getType(); + + Matrix fb(workArea, order, NEBD); + Matrix fb2(&workArea[order*NEBD], order, NEBD); + + double xL = xi[i]; + double xL1 = xL-1.0; + double wtL = wt[i]*L; + + double dxLdh = dptsdh[i];// - xL/L*dLdh; + double dwtLdh = wt[i]*dLdh + dwtsdh[i]*L; + + const Matrix &fs = sections[i]->getInitialFlexibility(); + const Matrix &dfsdh = sections[i]->getInitialFlexibilitySensitivity(gradNumber); + fb.Zero(); + fb2.Zero(); + + double tmp; + int ii, jj; + for (ii = 0; ii < order; ii++) { + switch(code(ii)) { + case SECTION_RESPONSE_P: + for (jj = 0; jj < order; jj++) { + fb(jj,0) += dfsdh(jj,ii)*wtL; // 1 + + //fb(jj,0) += fs(jj,ii)*dwtLdh; // 3 + + //fb2(jj,0) += fs(jj,ii)*wtL; // 4 + } + break; + case SECTION_RESPONSE_MZ: + for (jj = 0; jj < order; jj++) { + tmp = dfsdh(jj,ii)*wtL; // 1 + fb(jj,1) += xL1*tmp; + fb(jj,2) += xL*tmp; + + tmp = fs(jj,ii)*wtL; // 2 + //fb(jj,1) += dxLdh*tmp; + //fb(jj,2) += dxLdh*tmp; + + tmp = fs(jj,ii)*dwtLdh; // 3 + //fb(jj,1) += xL1*tmp; + //fb(jj,2) += xL*tmp; + + tmp = fs(jj,ii)*wtL; // 4 + //fb2(jj,1) += xL1*tmp; + //fb2(jj,2) += xL*tmp; + } + break; + case SECTION_RESPONSE_VY: + for (jj = 0; jj < order; jj++) { + tmp = oneOverL*dfsdh(jj,ii)*wtL; + fb(jj,1) += tmp; + fb(jj,2) += tmp; + + // Need to complete for dLdh != 0 + } + break; + default: + break; + } + } + for (ii = 0; ii < order; ii++) { + switch (code(ii)) { + case SECTION_RESPONSE_P: + for (jj = 0; jj < NEBD; jj++) + dfedh(0,jj) += fb(ii,jj); + break; + case SECTION_RESPONSE_MZ: + for (jj = 0; jj < NEBD; jj++) { + tmp = fb(ii,jj); // 1,2,3 + dfedh(1,jj) += xL1*tmp; + dfedh(2,jj) += xL*tmp; + + tmp = fb2(ii,jj); // 4 + //dfedh(1,jj) += dxLdh*tmp; + //dfedh(2,jj) += dxLdh*tmp; + } + break; + case SECTION_RESPONSE_VY: + for (jj = 0; jj < NEBD; jj++) { + tmp = oneOverL*fb(ii,jj); + dfedh(1,jj) += tmp; + dfedh(2,jj) += tmp; + + // Need to complete for dLdh != 0 + } + break; + default: + break; + } + } + } + + return dfedh; +} diff --git a/SRC/element/forceBeamColumn/ForceBeamColumnCBDI3d.h b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI3d.h new file mode 100644 index 0000000000..4a5f1c0096 --- /dev/null +++ b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI3d.h @@ -0,0 +1,237 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision$ +// $Date$ +// $Source$ + +/* + * References + * + +State Determination Algorithm +--- +Neuenhofer, A. and F. C. Filippou (1997). "Evaluation of Nonlinear Frame Finite +Element Models." Journal of Structural Engineering, 123(7):958-966. + +Spacone, E., V. Ciampi, and F. C. Filippou (1996). "Mixed Formulation of +Nonlinear Beam Finite Element." Computers and Structures, 58(1):71-83. + + +Plastic Hinge Integration +--- +Scott, M. H. and G. L. Fenves (2006). "Plastic Hinge Integration Methods for +Force-Based Beam-Column Elements." Journal of Structural Engineering, +132(2):244-252. + + +Analytical Response Sensitivity (DDM) +--- +Scott, M. H., P. Franchin, G. L. Fenves, and F. C. Filippou (2004). +"Response Sensitivity for Nonlinear Beam-Column Elements." +Journal of Structural Engineering, 130(9):1281-1288. + + +Software Design +--- +Scott, M. H., G. L. Fenves, F. T. McKenna, and F. C. Filippou (2007). +"Software Patterns for Nonlinear Beam-Column Models." +Journal of Structural Engineering, Approved for publication, February 2007. + + * + */ + +#ifndef ForceBeamColumnCBDI3d_h +#define ForceBeamColumnCBDI3d_h + +#include +#include +#include +#include +#include +#include +#include +#include + +class Response; +class ElementalLoad; + +class ForceBeamColumnCBDI3d: public Element +{ + public: + ForceBeamColumnCBDI3d(); + ForceBeamColumnCBDI3d(int tag, int nodeI, int nodeJ, + int numSections, SectionForceDeformation **sec, + BeamIntegration &beamIntegr, + CrdTransf &coordTransf, + double rho = 0.0, bool includeShear = false, + int maxNumIters = 10, double tolerance = 1.0e-12); + + ~ForceBeamColumnCBDI3d(); + + const char *getClassType(void) const {return "ForceBeamColumnCBDI3d";}; + + int getNumExternalNodes(void) const; + const ID &getExternalNodes(void); + Node **getNodePtrs(void); + + int getNumDOF(void); + + void setDomain(Domain *theDomain); + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + int update(void); + + const Matrix &getTangentStiff(void); + const Matrix &getInitialStiff(void); + const Matrix &getMass(void); + + void zeroLoad(void); + int addLoad(ElementalLoad *theLoad, double loadFactor); + int addInertiaLoadToUnbalance(const Vector &accel); + + const Vector &getResistingForce(void); + const Vector &getResistingForceIncInertia(void); + + int sendSelf(int cTag, Channel &theChannel); + int recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + int displaySelf(Renderer &theViewer, int displayMode, float fact, const char **displayModes=0, int numModes=0); + + friend OPS_Stream &operator<<(OPS_Stream &s, ForceBeamColumnCBDI3d &E); + void Print(OPS_Stream &s, int flag =0); + + Response *setResponse(const char **argv, int argc, OPS_Stream &s); + int getResponse(int responseID, Information &eleInformation); + int getResponseSensitivity(int responseID, int gradNumber, + Information &eleInformation); + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int setParameter(const char **argv, int argc, Parameter ¶m); + int updateParameter(int parameterID, Information &info); + int activateParameter(int parameterID); + const Vector &getResistingForceSensitivity(int gradNumber); + const Matrix &getKiSensitivity(int gradNumber); + const Matrix &getMassSensitivity(int gradNumber); + int commitSensitivity(int gradNumber, int numGrads); + // AddingSensitivity:END /////////////////////////////////////////// + + protected: + void setSectionPointers(int numSections, SectionForceDeformation **secPtrs); + int getInitialFlexibility(Matrix &fe); + int getInitialDeformations(Vector &v0); + + private: + void getForceInterpolatMatrix(double xi, Matrix &b, const ID &code); + void getDistrLoadInterpolatMatrix(double xi, Matrix &bp, const ID &code); + void computew(Vector &w, Vector &wp, double xi[], + const Vector &kappa, const Vector &gamma); + void computedwdq(Matrix &dwidq, const Vector &q, + const Vector &w, const Vector &wp, + const Matrix &lsk, const Matrix &lsg, + const Matrix &lskp, const Matrix &lsgp); + void computedwzdq(Matrix &dwidzq, const Vector &q, + const Vector &wz, const Vector &wpz, + const Matrix &lsk, const Matrix &lsg, + const Matrix &lskp, const Matrix &lsgp); + void compSectionDisplacements(Vector sectionCoords[], Vector sectionDispls[]) const; + void initializeSectionHistoryVariables (void); + + void getG(int numSections, double xi[], Matrix &G); + void getGinv(int numSections, double xi[], Matrix &Ginv); + void getHk(int numSections, double xi[], Matrix &H); + void getHg(int numSections, double xi[], Matrix &H); + void getHkp(int numSections, double xi[], Matrix &H); + void getHgp(int numSections, double xi[], Matrix &H); + + // Reactions of basic system due to element loads + void computeReactions(double *p0); + + // Section forces due to element loads + void computeSectionForces(Vector &sp, int isec); + + // internal data + ID connectedExternalNodes; // tags of the end nodes + + BeamIntegration *beamIntegr; + int numSections; + SectionForceDeformation **sections; // array of pointers to sections + CrdTransf *crdTransf; // pointer to coordinate transformation object + // (performs the transformation between the global and basic system) + bool CSBDI; + double rho; // mass density per unit length + int maxIters; // maximum number of local iterations + double tol; // tolerance for relative energy norm for local iterations + + int initialFlag; // indicates if the element has been initialized + + Node *theNodes[2]; // pointers to the nodes + + Matrix kv; // stiffness matrix in the basic system + Vector Se; // element resisting forces in the basic system + + Matrix kvcommit; // committed stiffness matrix in the basic system + Vector Secommit; // committed element end forces in the basic system + + Matrix *fs; // array of section flexibility matrices + Vector *vs; // array of section deformation vectors + Vector *Ssr; // array of section resisting force vectors + + Vector *vscommit; // array of committed section deformation vectors + + enum {maxNumEleLoads = 100}; + enum {NDM = 3}; // dimension of the problem (2d) + enum {NND = 6}; // number of nodal dof's + enum {NEGD = 12}; // number of element global dof's + enum {NEBD = 6}; // number of element dof's in the basic system + + int numEleLoads; // Number of element load objects + int sizeEleLoads; + ElementalLoad **eleLoads; + double *eleLoadFactors; + + Matrix *Ki; + + static Matrix theMatrix; + static Vector theVector; + static double workArea[]; + + enum {maxNumSections = 20}; + enum {maxSectionOrder = 10}; + + // following are added for subdivision of displacement increment + int maxSubdivisions; // maximum number of subdivisons of dv for local iterations + + static Vector vsSubdivide[]; + static Vector SsrSubdivide[]; + static Matrix fsSubdivide[]; + //static int maxNumSections; + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int parameterID; + const Vector &computedqdh(int gradNumber); + const Matrix &computedfedh(int gradNumber); + void computedwdh(double dwidh[], int gradNumber, const Vector &q); + void computeReactionSensitivity(double *dp0dh, int gradNumber); + void computeSectionForceSensitivity(Vector &dspdh, int isec, int gradNumber); + // AddingSensitivity:END /////////////////////////////////////////// +}; + +#endif diff --git a/SRC/element/forceBeamColumn/ForceBeamColumnWarping2d.cpp b/SRC/element/forceBeamColumn/ForceBeamColumnWarping2d.cpp index 39412a1fc4..06b4cd9ed3 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumnWarping2d.cpp +++ b/SRC/element/forceBeamColumn/ForceBeamColumnWarping2d.cpp @@ -89,9 +89,9 @@ Matrix ForceBeamColumnWarping2d::theMatrix(8,8); Vector ForceBeamColumnWarping2d::theVector(10); double ForceBeamColumnWarping2d::workArea[200]; -Vector *ForceBeamColumnWarping2d::vsSubdivide = 0; -Matrix *ForceBeamColumnWarping2d::fsSubdivide = 0; -Vector *ForceBeamColumnWarping2d::SsrSubdivide = 0; +Vector ForceBeamColumnWarping2d::vsSubdivide[maxNumSections]; +Matrix ForceBeamColumnWarping2d::fsSubdivide[maxNumSections]; +Vector ForceBeamColumnWarping2d::SsrSubdivide[maxNumSections]; void* OPS_ForceBeamColumnWarping2d() { @@ -194,17 +194,6 @@ ForceBeamColumnWarping2d::ForceBeamColumnWarping2d(): { theNodes[0] = 0; theNodes[1] = 0; - - if (vsSubdivide == 0) - vsSubdivide = new Vector [maxNumSections]; - if (fsSubdivide == 0) - fsSubdivide = new Matrix [maxNumSections]; - if (SsrSubdivide == 0) - SsrSubdivide = new Vector [maxNumSections]; - if (!vsSubdivide || !fsSubdivide || !SsrSubdivide) { - opserr << "ForceBeamColumnWarping2d::ForceBeamColumnWarping2d() -- failed to allocate Subdivide arrays"; - exit(-1); - } } // constructor which takes the unique element tag, sections, @@ -245,17 +234,6 @@ ForceBeamColumnWarping2d::ForceBeamColumnWarping2d (int tag, int nodeI, int node } this->setSectionPointers(numSec, sec); - - if (vsSubdivide == 0) - vsSubdivide = new Vector [maxNumSections]; - if (fsSubdivide == 0) - fsSubdivide = new Matrix [maxNumSections]; - if (SsrSubdivide == 0) - SsrSubdivide = new Vector [maxNumSections]; - if (!vsSubdivide || !fsSubdivide || !SsrSubdivide) { - opserr << "ForceBeamColumnWarping2d::ForceBeamColumnWarping2d() -- failed to allocate Subdivide arrays"; - exit(-1); - } } // ~ForceBeamColumnWarping2d(): diff --git a/SRC/element/forceBeamColumn/ForceBeamColumnWarping2d.h b/SRC/element/forceBeamColumn/ForceBeamColumnWarping2d.h index ef0260c960..d007c9a1da 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumnWarping2d.h +++ b/SRC/element/forceBeamColumn/ForceBeamColumnWarping2d.h @@ -200,9 +200,9 @@ class ForceBeamColumnWarping2d: public Element // following are added for subdivision of displacement increment int maxSubdivisions; // maximum number of subdivisons of dv for local iterations - static Vector *vsSubdivide; - static Vector *SsrSubdivide; - static Matrix *fsSubdivide; + static Vector vsSubdivide[]; + static Vector SsrSubdivide[]; + static Matrix fsSubdivide[]; //static int maxNumSections; // AddingSensitivity:BEGIN ////////////////////////////////////////// diff --git a/SRC/element/forceBeamColumn/Makefile b/SRC/element/forceBeamColumn/Makefile index 47e449d7dd..2ff6406144 100644 --- a/SRC/element/forceBeamColumn/Makefile +++ b/SRC/element/forceBeamColumn/Makefile @@ -4,7 +4,7 @@ OBJS = ForceBeamColumn2d.o ForceBeamColumn3d.o \ ForceBeamColumn2dThermal.o \ ElasticForceBeamColumn2d.o ElasticForceBeamColumn3d.o \ ElasticForceBeamColumnWarping2d.o \ - ForceBeamColumnCBDI2d.o \ + ForceBeamColumnCBDI2d.o ForceBeamColumnCBDI3d.o \ ForceBeamColumnWarping2d.o \ TclForceBeamColumnCommand.o \ BeamIntegration.o \ diff --git a/SRC/element/forceBeamColumn/TclForceBeamColumnCommand.cpp b/SRC/element/forceBeamColumn/TclForceBeamColumnCommand.cpp index 2b8ef20cd7..33b9500ecd 100644 --- a/SRC/element/forceBeamColumn/TclForceBeamColumnCommand.cpp +++ b/SRC/element/forceBeamColumn/TclForceBeamColumnCommand.cpp @@ -1278,7 +1278,7 @@ TclModelBuilder_addForceBeamColumn(ClientData clientData, Tcl_Interp *interp, opserr << argv[1] << " element: " << eleTag << endln; return TCL_ERROR; } - argi += 3; + argi += 2; } else if (strcmp(argv[argi],"-mass") == 0) { if (argc < argi+2) { opserr << "WARNING not enough -mass args need -mass mass?\n"; @@ -1290,13 +1290,11 @@ TclModelBuilder_addForceBeamColumn(ClientData clientData, Tcl_Interp *interp, opserr << argv[1] << " element: " << eleTag << endln; return TCL_ERROR; } - argi += 2; + argi += 1; } else if ((strcmp(argv[argi],"-lMass") == 0 || strcmp(argv[argi],"lMass") == 0)) { cMass = 0; - argi++; } else if ((strcmp(argv[argi],"-cMass") == 0 || strcmp(argv[argi],"cMass") == 0)) { cMass = 1; - argi++; } argi += 1; } diff --git a/SRC/element/fourNodeQuad/EightNodeQuad.cpp b/SRC/element/fourNodeQuad/EightNodeQuad.cpp new file mode 100644 index 0000000000..03aba90d00 --- /dev/null +++ b/SRC/element/fourNodeQuad/EightNodeQuad.cpp @@ -0,0 +1,1628 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// based on FourNodeQuad by MHS +// Written: Seweryn Kokot, Opole University of Technology, Poland +// Created: Aug 2020 +// +// Description: This file contains the class definition for EightNodeQuad. + +#include "EightNodeQuad.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void* OPS_EightNodeQuad() +{ + int ndm = OPS_GetNDM(); + int ndf = OPS_GetNDF(); + + if (ndm != 2 || ndf != 2) { + opserr << "WARNING -- model dimensions and/or nodal DOF not compatible with quad element\n"; + return 0; + } + + if (OPS_GetNumRemainingInputArgs() < 12) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element EightNodeQuad eleTag? Node1? Node2? Node3? Node4? Node5? Node6? Node7? Node8? thk? type? matTag? \n"; + return 0; + } + + // EightNodeQuadId, iNode, jNode, kNode, lNode + // nNode, mNode, pNode, qNode + int idata[9]; + int num = 9; + if (OPS_GetIntInput(&num,idata) < 0) { + opserr<<"WARNING: invalid integer inputs\n"; + return 0; + } + + double thk = 1.0; + num = 1; + if (OPS_GetDoubleInput(&num,&thk) < 0) { + opserr<<"WARNING: invalid double inputs\n"; + return 0; + } + + const char* type = OPS_GetString(); + + int matTag; + num = 1; + if (OPS_GetIntInput(&num,&matTag) < 0) { + opserr<<"WARNING: invalid matTag\n"; + return 0; + } + + NDMaterial* mat = OPS_getNDMaterial(matTag); + if (mat == 0) { + opserr << "WARNING material not found\n"; + opserr << "Material: " << matTag; + opserr << "\nEightNodeQuad element: " << idata[0] << endln; + return 0; + } + + // p, rho, b1, b2 + double data[4] = {0,0,0,0}; + num = OPS_GetNumRemainingInputArgs(); + if (num > 4) { + num = 4; + } + if (num > 0) { + if (OPS_GetDoubleInput(&num,data) < 0) { + opserr<<"WARNING: invalid integer data\n"; + return 0; + } + } + + return new EightNodeQuad(idata[0],idata[1],idata[2],idata[3],idata[4], + idata[5],idata[6],idata[7],idata[8], + *mat,type,thk,data[0],data[1],data[2],data[3]); +} + + +double EightNodeQuad::matrixData[(nnodes*2)*(nnodes*2)]; +Matrix EightNodeQuad::K(matrixData, nnodes*2, nnodes*2); +Vector EightNodeQuad::P(nnodes*2); +double EightNodeQuad::shp[3][nnodes]; +double EightNodeQuad::pts[nip][2]; +double EightNodeQuad::wts[nip]; + +EightNodeQuad::EightNodeQuad(int tag, int nd1, int nd2, int nd3, int nd4, + int nd5, int nd6, int nd7, int nd8, + NDMaterial &m, const char *type, double t, + double p, double r, double b1, double b2) +:Element (tag, ELE_TAG_EightNodeQuad), + theMaterial(0), connectedExternalNodes(nnodes), + Q(nnodes*2), applyLoad(0), pressureLoad(nnodes*2), thickness(t), pressure(p), rho(r), Ki(0) +{ + pts[0][0] = -0.7745966692414834; + pts[0][1] = -0.7745966692414834; + pts[1][0] = 0.7745966692414834; + pts[1][1] = -0.7745966692414834; + pts[2][0] = 0.7745966692414834; + pts[2][1] = 0.7745966692414834; + pts[3][0] = -0.7745966692414834; + pts[3][1] = 0.7745966692414834; + pts[4][0] = 0.0; + pts[4][1] = -0.7745966692414834; + pts[5][0] = 0.7745966692414834; + pts[5][1] = 0.0; + pts[6][0] = 0.0; + pts[6][1] = 0.7745966692414834; + pts[7][0] = -0.7745966692414834; + pts[7][1] = 0.0; + pts[8][0] = 0.0; + pts[8][1] = 0.0; + + wts[0] = 0.30864197530864196; + wts[1] = 0.30864197530864196; + wts[2] = 0.30864197530864196; + wts[3] = 0.30864197530864196; + wts[4] = 0.49382716049382713; + wts[5] = 0.49382716049382713; + wts[6] = 0.49382716049382713; + wts[7] = 0.49382716049382713; + wts[8] = 0.7901234567901234; + + if (strcmp(type,"PlaneStrain") != 0 && strcmp(type,"PlaneStress") != 0 + && strcmp(type,"PlaneStrain2D") != 0 && strcmp(type,"PlaneStress2D") != 0) { + opserr << "EightNodeQuad::EightNodeQuad -- improper material type: " << type << "for EightNodeQuad\n"; + exit(-1); + } + + // Body forces + b[0] = b1; + b[1] = b2; + + // Allocate arrays of pointers to NDMaterials + theMaterial = new NDMaterial *[nip]; + + if (theMaterial == 0) { + opserr << "EightNodeQuad::EightNodeQuad - failed allocate material model pointer\n"; + exit(-1); + } + + int i; + for (i = 0; i < nip; i++) { + + // Get copies of the material model for each integration point + theMaterial[i] = m.getCopy(type); + + // Check allocation + if (theMaterial[i] == 0) { + opserr << "EightNodeQuad::EightNodeQuad -- failed to get a copy of material model\n"; + exit(-1); + } + } + + // Set connected external node IDs + connectedExternalNodes(0) = nd1; + connectedExternalNodes(1) = nd2; + connectedExternalNodes(2) = nd3; + connectedExternalNodes(3) = nd4; + connectedExternalNodes(4) = nd5; + connectedExternalNodes(5) = nd6; + connectedExternalNodes(6) = nd7; + connectedExternalNodes(7) = nd8; + + for (i=0; igetNode(Nd1); + theNodes[1] = theDomain->getNode(Nd2); + theNodes[2] = theDomain->getNode(Nd3); + theNodes[3] = theDomain->getNode(Nd4); + theNodes[4] = theDomain->getNode(Nd5); + theNodes[5] = theDomain->getNode(Nd6); + theNodes[6] = theDomain->getNode(Nd7); + theNodes[7] = theDomain->getNode(Nd8); + + if (theNodes[0] == 0 || theNodes[1] == 0 || theNodes[2] == 0 || theNodes[3] == 0 || + theNodes[4] == 0 || theNodes[5] == 0 || theNodes[6] == 0 || theNodes[7] == 0) { + //opserr << "FATAL ERROR EightNodeQuad (tag: %d), node not found in domain", + // this->getTag()); + + return; + } + + int dofNd1 = theNodes[0]->getNumberDOF(); + int dofNd2 = theNodes[1]->getNumberDOF(); + int dofNd3 = theNodes[2]->getNumberDOF(); + int dofNd4 = theNodes[3]->getNumberDOF(); + int dofNd5 = theNodes[4]->getNumberDOF(); + int dofNd6 = theNodes[5]->getNumberDOF(); + int dofNd7 = theNodes[6]->getNumberDOF(); + int dofNd8 = theNodes[7]->getNumberDOF(); + + if (dofNd1 != 2 || dofNd2 != 2 || dofNd3 != 2 || dofNd4 != 2 || + dofNd5 != 2 || dofNd6 != 2 || dofNd7 != 2 || dofNd8 != 2) { + //opserr << "FATAL ERROR EightNodeQuad (tag: %d), has differing number of DOFs at its nodes", + // this->getTag()); + + return; + } + this->DomainComponent::setDomain(theDomain); + + // Compute consistent nodal loads due to pressure + this->setPressureLoadAtNodes(); +} + +int +EightNodeQuad::commitState() +{ + int retVal = 0; + + // call element commitState to do any base class stuff + if ((retVal = this->Element::commitState()) != 0) { + opserr << "EightNodeQuad::commitState () - failed in base class"; + } + + // Loop over the integration points and commit the material states + for (int i = 0; i < nip; i++) + retVal += theMaterial[i]->commitState(); + + return retVal; +} + +int +EightNodeQuad::revertToLastCommit() +{ + int retVal = 0; + + // Loop over the integration points and revert to last committed state + for (int i = 0; i < nip; i++) + retVal += theMaterial[i]->revertToLastCommit(); + + return retVal; +} + +int +EightNodeQuad::revertToStart() +{ + int retVal = 0; + + // Loop over the integration points and revert states to start + for (int i = 0; i < nip; i++) + retVal += theMaterial[i]->revertToStart(); + + return retVal; +} + + +int +EightNodeQuad::update() +{ + const Vector &disp1 = theNodes[0]->getTrialDisp(); + const Vector &disp2 = theNodes[1]->getTrialDisp(); + const Vector &disp3 = theNodes[2]->getTrialDisp(); + const Vector &disp4 = theNodes[3]->getTrialDisp(); + const Vector &disp5 = theNodes[4]->getTrialDisp(); + const Vector &disp6 = theNodes[5]->getTrialDisp(); + const Vector &disp7 = theNodes[6]->getTrialDisp(); + const Vector &disp8 = theNodes[7]->getTrialDisp(); + + static double u[2][nnodes]; + + u[0][0] = disp1(0); + u[1][0] = disp1(1); + u[0][1] = disp2(0); + u[1][1] = disp2(1); + u[0][2] = disp3(0); + u[1][2] = disp3(1); + u[0][3] = disp4(0); + u[1][3] = disp4(1); + u[0][4] = disp5(0); + u[1][4] = disp5(1); + u[0][5] = disp6(0); + u[1][5] = disp6(1); + u[0][6] = disp7(0); + u[1][6] = disp7(1); + u[0][7] = disp8(0); + u[1][7] = disp8(1); + + static Vector eps(3); + + int ret = 0; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + this->shapeFunction(pts[i][0], pts[i][1]); + + // Interpolate strains + //eps = B*u; + //eps.addMatrixVector(0.0, B, u, 1.0); + eps.Zero(); + for (int beta = 0; beta < nnodes; beta++) { + eps(0) += shp[0][beta]*u[0][beta]; + eps(1) += shp[1][beta]*u[1][beta]; + eps(2) += shp[0][beta]*u[1][beta] + shp[1][beta]*u[0][beta]; + } + + // Set the material strain + ret += theMaterial[i]->setTrialStrain(eps); + } + + return ret; +} + + +const Matrix& +EightNodeQuad::getTangentStiff() +{ + + K.Zero(); + + double dvol; + double DB[3][2]; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + dvol = this->shapeFunction(pts[i][0], pts[i][1]); + dvol *= (thickness*wts[i]); + + // Get the material tangent + const Matrix &D = theMaterial[i]->getTangent(); + + // Perform numerical integration + //K = K + (B^ D * B) * intWt(i)*intWt(j) * detJ; + //K.addMatrixTripleProduct(1.0, B, D, intWt(i)*intWt(j)*detJ); + + double D00 = D(0,0); double D01 = D(0,1); double D02 = D(0,2); + double D10 = D(1,0); double D11 = D(1,1); double D12 = D(1,2); + double D20 = D(2,0); double D21 = D(2,1); double D22 = D(2,2); + + // for (int beta = 0, ib = 0, colIb =0, colIbP1 = 8; + // beta < 4; + // beta++, ib += 2, colIb += 16, colIbP1 += 16) { + + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia += 2) { + for (int beta = 0, ib = 0; beta < nnodes; beta++, ib += 2) { + + DB[0][0] = dvol * (D00 * shp[0][beta] + D02 * shp[1][beta]); + DB[1][0] = dvol * (D10 * shp[0][beta] + D12 * shp[1][beta]); + DB[2][0] = dvol * (D20 * shp[0][beta] + D22 * shp[1][beta]); + DB[0][1] = dvol * (D01 * shp[1][beta] + D02 * shp[0][beta]); + DB[1][1] = dvol * (D11 * shp[1][beta] + D12 * shp[0][beta]); + DB[2][1] = dvol * (D21 * shp[1][beta] + D22 * shp[0][beta]); + + + K(ia,ib) += shp[0][alpha]*DB[0][0] + shp[1][alpha]*DB[2][0]; + K(ia,ib+1) += shp[0][alpha]*DB[0][1] + shp[1][alpha]*DB[2][1]; + K(ia+1,ib) += shp[1][alpha]*DB[1][0] + shp[0][alpha]*DB[2][0]; + K(ia+1,ib+1) += shp[1][alpha]*DB[1][1] + shp[0][alpha]*DB[2][1]; + // matrixData[colIb + ia] += shp[0][alpha]*DB[0][0] + shp[1][alpha]*DB[2][0]; + // matrixData[colIbP1 + ia] += shp[0][alpha]*DB[0][1] + shp[1][alpha]*DB[2][1]; + // matrixData[colIb + ia+1] += shp[1][alpha]*DB[1][0] + shp[0][alpha]*DB[2][0]; + // matrixData[colIbP1 + ia+1] += shp[1][alpha]*DB[1][1] + shp[0][alpha]*DB[2][1]; + + } + } + } + + return K; +} + + +const Matrix& +EightNodeQuad::getInitialStiff() +{ + if (Ki != 0) + return *Ki; + + K.Zero(); + + double dvol; + double DB[3][2]; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + dvol = this->shapeFunction(pts[i][0], pts[i][1]); + dvol *= (thickness*wts[i]); + + // Get the material tangent + const Matrix &D = theMaterial[i]->getInitialTangent(); + + double D00 = D(0,0); double D01 = D(0,1); double D02 = D(0,2); + double D10 = D(1,0); double D11 = D(1,1); double D12 = D(1,2); + double D20 = D(2,0); double D21 = D(2,1); double D22 = D(2,2); + + // Perform numerical integration + //K = K + (B^ D * B) * intWt(i)*intWt(j) * detJ; + //K.addMatrixTripleProduct(1.0, B, D, intWt(i)*intWt(j)*detJ); + for (int beta = 0, ib = 0, colIb =0, colIbP1 = 8; + beta < nnodes; + beta++, ib += 2, colIb += 16, colIbP1 += 16) { + + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia += 2) { + + DB[0][0] = dvol * (D00 * shp[0][beta] + D02 * shp[1][beta]); + DB[1][0] = dvol * (D10 * shp[0][beta] + D12 * shp[1][beta]); + DB[2][0] = dvol * (D20 * shp[0][beta] + D22 * shp[1][beta]); + DB[0][1] = dvol * (D01 * shp[1][beta] + D02 * shp[0][beta]); + DB[1][1] = dvol * (D11 * shp[1][beta] + D12 * shp[0][beta]); + DB[2][1] = dvol * (D21 * shp[1][beta] + D22 * shp[0][beta]); + + matrixData[colIb + ia] += shp[0][alpha]*DB[0][0] + shp[1][alpha]*DB[2][0]; + matrixData[colIbP1 + ia] += shp[0][alpha]*DB[0][1] + shp[1][alpha]*DB[2][1]; + matrixData[colIb + ia+1] += shp[1][alpha]*DB[1][0] + shp[0][alpha]*DB[2][0]; + matrixData[colIbP1 + ia+1] += shp[1][alpha]*DB[1][1] + shp[0][alpha]*DB[2][1]; + } + } + } + + Ki = new Matrix(K); + return K; +} + +const Matrix& +EightNodeQuad::getMass() +{ + K.Zero(); + + int i; + static double rhoi[nip]; + double sum = 0.0; + for (i = 0; i < nip; i++) { + if (rho == 0) + rhoi[i] = theMaterial[i]->getRho(); + else + rhoi[i] = rho; + sum += rhoi[i]; + } + + if (sum == 0.0) + return K; + + double rhodvol, Nrho; + + // Compute a lumped mass matrix + for (i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + rhodvol = this->shapeFunction(pts[i][0], pts[i][1]); + + // Element plus material density ... MAY WANT TO REMOVE ELEMENT DENSITY + rhodvol *= (rhoi[i]*thickness*wts[i]); + + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia++) { + Nrho = shp[2][alpha]*rhodvol; + K(ia,ia) += Nrho; + ia++; + K(ia,ia) += Nrho; + } + } + + return K; +} + +void +EightNodeQuad::zeroLoad(void) +{ + Q.Zero(); + + applyLoad = 0; + + appliedB[0] = 0.0; + appliedB[1] = 0.0; + + return; +} + +int +EightNodeQuad::addLoad(ElementalLoad *theLoad, double loadFactor) +{ + // Added option for applying body forces in load pattern: C.McGann, U.Washington + int type; + const Vector &data = theLoad->getData(type, loadFactor); + + if (type == LOAD_TAG_SelfWeight) { + applyLoad = 1; + appliedB[0] += loadFactor*data(0)*b[0]; + appliedB[1] += loadFactor*data(1)*b[1]; + return 0; + } else { + opserr << "EightNodeQuad::addLoad - load type unknown for ele with tag: " << this->getTag() << endln; + return -1; + } + + return -1; +} + +int +EightNodeQuad::addInertiaLoadToUnbalance(const Vector &accel) +{ + int i; + static double rhoi[nip]; + double sum = 0.0; + for (i = 0; i < nip; i++) { + rhoi[i] = theMaterial[i]->getRho(); + sum += rhoi[i]; + } + + if (sum == 0.0) + return 0; + + // Get R * accel from the nodes + const Vector &Raccel1 = theNodes[0]->getRV(accel); + const Vector &Raccel2 = theNodes[1]->getRV(accel); + const Vector &Raccel3 = theNodes[2]->getRV(accel); + const Vector &Raccel4 = theNodes[3]->getRV(accel); + const Vector &Raccel5 = theNodes[4]->getRV(accel); + const Vector &Raccel6 = theNodes[5]->getRV(accel); + const Vector &Raccel7 = theNodes[6]->getRV(accel); + const Vector &Raccel8 = theNodes[7]->getRV(accel); + + if (2 != Raccel1.Size() || 2 != Raccel2.Size() || 2 != Raccel3.Size() || + 2 != Raccel4.Size() || 2 != Raccel5.Size() || 2 != Raccel6.Size() || + 2 != Raccel7.Size() || 2 != Raccel8.Size()) { + opserr << "EightNodeQuad::addInertiaLoadToUnbalance matrix and vector sizes are incompatible\n"; + return -1; + } + + static double ra[nnodes*2]; + + ra[0] = Raccel1(0); + ra[1] = Raccel1(1); + ra[2] = Raccel2(0); + ra[3] = Raccel2(1); + ra[4] = Raccel3(0); + ra[5] = Raccel3(1); + ra[6] = Raccel4(0); + ra[7] = Raccel4(1); + ra[8] = Raccel5(0); + ra[9] = Raccel5(1); + ra[10] = Raccel6(0); + ra[11] = Raccel6(1); + ra[12] = Raccel7(0); + ra[13] = Raccel7(1); + ra[14] = Raccel8(0); + ra[15] = Raccel8(1); + + // Compute mass matrix + this->getMass(); + + // Want to add ( - fact * M R * accel ) to unbalance + // Take advantage of lumped mass matrix + for (i = 0; i < 2*nnodes; i++) + Q(i) += -K(i,i)*ra[i]; + + return 0; +} + +const Vector& +EightNodeQuad::getResistingForce() +{ + P.Zero(); + + double dvol; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + dvol = this->shapeFunction(pts[i][0], pts[i][1]); + dvol *= (thickness*wts[i]); + + // Get material stress response + const Vector &sigma = theMaterial[i]->getStress(); + + // Perform numerical integration on internal force + //P = P + (B^ sigma) * intWt(i)*intWt(j) * detJ; + //P.addMatrixTransposeVector(1.0, B, sigma, intWt(i)*intWt(j)*detJ); + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia += 2) { + + P(ia) += dvol*(shp[0][alpha]*sigma(0) + shp[1][alpha]*sigma(2)); + + P(ia+1) += dvol*(shp[1][alpha]*sigma(1) + shp[0][alpha]*sigma(2)); + + // Subtract equiv. body forces from the nodes + //P = P - (N^ b) * intWt(i)*intWt(j) * detJ; + //P.addMatrixTransposeVector(1.0, N, b, -intWt(i)*intWt(j)*detJ); + if (applyLoad == 0) { + P(ia) -= dvol*(shp[2][alpha]*b[0]); + P(ia+1) -= dvol*(shp[2][alpha]*b[1]); + } else { + P(ia) -= dvol*(shp[2][alpha]*appliedB[0]); + P(ia+1) -= dvol*(shp[2][alpha]*appliedB[1]); + } + } + } + + // Subtract pressure loading from resisting force + if (pressure != 0.0) { + //P = P - pressureLoad; + P.addVector(1.0, pressureLoad, -1.0); + } + + // Subtract other external nodal loads ... P_res = P_int - P_ext + //P = P - Q; + P.addVector(1.0, Q, -1.0); + + return P; +} + +const Vector& +EightNodeQuad::getResistingForceIncInertia() +{ + int i; + static double rhoi[nip]; + double sum = 0.0; + for (i = 0; i < nip; i++) { + rhoi[i] = theMaterial[i]->getRho(); + sum += rhoi[i]; + } + + // if no mass terms .. just add damping terms + if (sum == 0.0) { + this->getResistingForce(); + + // add the damping forces if rayleigh damping + if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P += this->getRayleighDampingForces(); + + return P; + } + + const Vector &accel1 = theNodes[0]->getTrialAccel(); + const Vector &accel2 = theNodes[1]->getTrialAccel(); + const Vector &accel3 = theNodes[2]->getTrialAccel(); + const Vector &accel4 = theNodes[3]->getTrialAccel(); + const Vector &accel5 = theNodes[4]->getTrialAccel(); + const Vector &accel6 = theNodes[5]->getTrialAccel(); + const Vector &accel7 = theNodes[6]->getTrialAccel(); + const Vector &accel8 = theNodes[7]->getTrialAccel(); + + static double a[nnodes*2]; + + a[0] = accel1(0); + a[1] = accel1(1); + a[2] = accel2(0); + a[3] = accel2(1); + a[4] = accel3(0); + a[5] = accel3(1); + a[6] = accel4(0); + a[7] = accel4(1); + a[8] = accel5(0); + a[9] = accel5(1); + a[10] = accel6(0); + a[11] = accel6(1); + a[12] = accel7(0); + a[13] = accel7(1); + a[14] = accel8(0); + a[15] = accel8(1); + + // Compute the current resisting force + this->getResistingForce(); + + // Compute the mass matrix + this->getMass(); + + // Take advantage of lumped mass matrix + for (i = 0; i < 2*nnodes; i++) + P(i) += K(i,i)*a[i]; + + // add the damping forces if rayleigh damping + if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P += this->getRayleighDampingForces(); + + return P; +} + +int +EightNodeQuad::sendSelf(int commitTag, Channel &theChannel) +{ + int res = 0; + + // note: we don't check for dataTag == 0 for Element + // objects as that is taken care of in a commit by the Domain + // object - don't want to have to do the check if sending data + int dataTag = this->getDbTag(); + + // Quad packs its data into a Vector and sends this to theChannel + // along with its dbTag and the commitTag passed in the arguments + static Vector data(9); + data(0) = this->getTag(); + data(1) = thickness; + data(2) = b[0]; + data(3) = b[1]; + data(4) = pressure; + + data(5) = alphaM; + data(6) = betaK; + data(7) = betaK0; + data(8) = betaKc; + + res += theChannel.sendVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING EightNodeQuad::sendSelf() - " << this->getTag() << " failed to send Vector\n"; + return res; + } + + + // Now quad sends the ids of its materials + int matDbTag; + + static ID idData(2*nip+nnodes); + + int i; + for (i = 0; i < nip; i++) { + idData(i) = theMaterial[i]->getClassTag(); + matDbTag = theMaterial[i]->getDbTag(); + // NOTE: we do have to ensure that the material has a database + // tag if we are sending to a database channel. + if (matDbTag == 0) { + matDbTag = theChannel.getDbTag(); + if (matDbTag != 0) + theMaterial[i]->setDbTag(matDbTag); + } + idData(i+nip) = matDbTag; + } + + for( i = 0; i < nnodes; i++) + idData(2*nip+i) = connectedExternalNodes(i); + + res += theChannel.sendID(dataTag, commitTag, idData); + if (res < 0) { + opserr << "WARNING EightNodeQuad::sendSelf() - " << this->getTag() << " failed to send ID\n"; + return res; + } + + // Finally, quad asks its material objects to send themselves + for (i = 0; i < nip; i++) { + res += theMaterial[i]->sendSelf(commitTag, theChannel); + if (res < 0) { + opserr << "WARNING EightNodeQuad::sendSelf() - " << this->getTag() << " failed to send its Material\n"; + return res; + } + } + + return res; +} + +int +EightNodeQuad::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + + int dataTag = this->getDbTag(); + + // Quad creates a Vector, receives the Vector and then sets the + // internal data with the data in the Vector + static Vector data(9); + res += theChannel.recvVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING EightNodeQuad::recvSelf() - failed to receive Vector\n"; + return res; + } + + this->setTag((int)data(0)); + thickness = data(1); + b[0] = data(2); + b[1] = data(3); + pressure = data(4); + + alphaM = data(5); + betaK = data(6); + betaK0 = data(7); + betaKc = data(8); + + static ID idData(2*nip+nnodes); + // Quad now receives the tags of its nine external nodes + res += theChannel.recvID(dataTag, commitTag, idData); + if (res < 0) { + opserr << "WARNING EightNodeQuad::recvSelf() - " << this->getTag() << " failed to receive ID\n"; + return res; + } + + for( int i = 0; i < nnodes; i++) + connectedExternalNodes(i) = idData(2*nip+i); + + if (theMaterial == 0) { + // Allocate new materials + theMaterial = new NDMaterial *[nip]; + if (theMaterial == 0) { + opserr << "EightNodeQuad::recvSelf() - Could not allocate NDMaterial* array\n"; + return -1; + } + for (int i = 0; i < nip; i++) { + int matClassTag = idData(i); + int matDbTag = idData(i+nip); + // Allocate new material with the sent class tag + theMaterial[i] = theBroker.getNewNDMaterial(matClassTag); + if (theMaterial[i] == 0) { + opserr << "EightNodeQuad::recvSelf() - Broker could not create NDMaterial of class type " << matClassTag << endln; + return -1; + } + // Now receive materials into the newly allocated space + theMaterial[i]->setDbTag(matDbTag); + res += theMaterial[i]->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "EightNodeQuad::recvSelf() - material " << i << "failed to recv itself\n"; + return res; + } + } + } + + // materials exist , ensure materials of correct type and recvSelf on them + else { + for (int i = 0; i < nip; i++) { + int matClassTag = idData(i); + int matDbTag = idData(i+nip); + // Check that material is of the right type; if not, + // delete it and create a new one of the right type + if (theMaterial[i]->getClassTag() != matClassTag) { + delete theMaterial[i]; + theMaterial[i] = theBroker.getNewNDMaterial(matClassTag); + if (theMaterial[i] == 0) { + opserr << "EightNodeQuad::recvSelf() - material " << i << "failed to create\n"; + return -1; + } + } + // Receive the material + theMaterial[i]->setDbTag(matDbTag); + res += theMaterial[i]->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "EightNodeQuad::recvSelf() - material " << i << "failed to recv itself\n"; + return res; + } + } + } + + return res; +} + +void +EightNodeQuad::Print(OPS_Stream &s, int flag) +{ + if (flag == 2) { + + s << "#EightNodeQuad\n"; + + int i; + const int numNodes = nnodes; + const int nstress = nip ; + + for (i=0; igetCrds(); + // const Vector &nodeDisp = theNodes[i]->getDisp(); + s << "#NODE " << nodeCrd(0) << " " << nodeCrd(1) << " " << endln; + } + + // spit out the section location & invoke print on the scetion + const int numMaterials = nip; + + static Vector avgStress(nstress); + static Vector avgStrain(nstress); + avgStress.Zero(); + avgStrain.Zero(); + for (i=0; igetStress(); + avgStrain += theMaterial[i]->getStrain(); + } + avgStress /= numMaterials; + avgStrain /= numMaterials; + + s << "#AVERAGE_STRESS "; + for (i=0; igetTag() << endln; + s << "\tConnected external nodes: " << connectedExternalNodes; + s << "\tthickness: " << thickness << endln; + s << "\tsurface pressure: " << pressure << endln; + s << "\tmass density: " << rho << endln; + s << "\tbody forces: " << b[0] << " " << b[1] << endln; + theMaterial[0]->Print(s,flag); + s << "\tStress (xx yy xy)" << endln; + for (int i = 0; i < nip; i++) + s << "\t\tGauss point " << i+1 << ": " << theMaterial[i]->getStress(); + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << "\t\t\t{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"EightNodeQuad\", "; + s << "\"nodes\": [" << connectedExternalNodes(0) << ", "; + s << connectedExternalNodes(1) << ", "; + s << connectedExternalNodes(2) << ", "; + s << connectedExternalNodes(3) << ", "; + s << connectedExternalNodes(4) << ", "; + s << connectedExternalNodes(5) << ", "; + s << connectedExternalNodes(6) << ", "; + s << connectedExternalNodes(7) << "], "; + s << "\"thickness\": " << thickness << ", "; + s << "\"surfacePressure\": " << pressure << ", "; + s << "\"masspervolume\": " << rho << ", "; + s << "\"bodyForces\": [" << b[0] << ", " << b[1] << "], "; + s << "\"material\": \"" << theMaterial[0]->getTag() << "\"}"; + } +} + +int +EightNodeQuad::displaySelf(Renderer &theViewer, int displayMode, float fact, const char **modes, int numMode) +{ + + // first set the quantity to be displayed at the nodes; + // if displayMode is 1 through 3 we will plot material stresses otherwise 0.0 + + static Vector values(nip); + + for (int j=0; j 0) { + for (int i=0; igetStress(); + values(i) = stress(displayMode-1); + } + } + + // now determine the end points of the quad based on + // the display factor (a measure of the distorted image) + // store this information in 4 3d vectors v1 through v4 + const Vector &end1Crd = theNodes[0]->getCrds(); + const Vector &end2Crd = theNodes[1]->getCrds(); + const Vector &end3Crd = theNodes[2]->getCrds(); + const Vector &end4Crd = theNodes[3]->getCrds(); + const Vector &end5Crd = theNodes[4]->getCrds(); + const Vector &end6Crd = theNodes[5]->getCrds(); + const Vector &end7Crd = theNodes[6]->getCrds(); + const Vector &end8Crd = theNodes[7]->getCrds(); + + static Matrix coords(nnodes,3); + + if (displayMode >= 0) { + + const Vector &end1Disp = theNodes[0]->getDisp(); + const Vector &end2Disp = theNodes[1]->getDisp(); + const Vector &end3Disp = theNodes[2]->getDisp(); + const Vector &end4Disp = theNodes[3]->getDisp(); + const Vector &end5Disp = theNodes[4]->getDisp(); + const Vector &end6Disp = theNodes[5]->getDisp(); + const Vector &end7Disp = theNodes[6]->getDisp(); + const Vector &end8Disp = theNodes[7]->getDisp(); + + for (int i = 0; i < 2; i++) { + coords(0,i) = end1Crd(i) + end1Disp(i)*fact; + coords(1,i) = end2Crd(i) + end2Disp(i)*fact; + coords(2,i) = end3Crd(i) + end3Disp(i)*fact; + coords(3,i) = end4Crd(i) + end4Disp(i)*fact; + coords(4,i) = end5Crd(i) + end5Disp(i)*fact; + coords(5,i) = end6Crd(i) + end6Disp(i)*fact; + coords(6,i) = end7Crd(i) + end7Disp(i)*fact; + coords(7,i) = end8Crd(i) + end8Disp(i)*fact; + } + } else { + int mode = displayMode * -1; + const Matrix &eigen1 = theNodes[0]->getEigenvectors(); + const Matrix &eigen2 = theNodes[1]->getEigenvectors(); + const Matrix &eigen3 = theNodes[2]->getEigenvectors(); + const Matrix &eigen4 = theNodes[3]->getEigenvectors(); + const Matrix &eigen5 = theNodes[4]->getEigenvectors(); + const Matrix &eigen6 = theNodes[5]->getEigenvectors(); + const Matrix &eigen7 = theNodes[6]->getEigenvectors(); + const Matrix &eigen8 = theNodes[7]->getEigenvectors(); + if (eigen1.noCols() >= mode) { + for (int i = 0; i < 2; i++) { + coords(0,i) = end1Crd(i) + eigen1(i,mode-1)*fact; + coords(1,i) = end2Crd(i) + eigen2(i,mode-1)*fact; + coords(2,i) = end3Crd(i) + eigen3(i,mode-1)*fact; + coords(3,i) = end4Crd(i) + eigen4(i,mode-1)*fact; + coords(4,i) = end5Crd(i) + eigen5(i,mode-1)*fact; + coords(5,i) = end6Crd(i) + eigen6(i,mode-1)*fact; + coords(6,i) = end7Crd(i) + eigen7(i,mode-1)*fact; + coords(7,i) = end8Crd(i) + eigen8(i,mode-1)*fact; + } + } else { + for (int i = 0; i < 2; i++) { + coords(0,i) = end1Crd(i); + coords(1,i) = end2Crd(i); + coords(2,i) = end3Crd(i); + coords(3,i) = end4Crd(i); + coords(4,i) = end5Crd(i); + coords(5,i) = end6Crd(i); + coords(6,i) = end7Crd(i); + coords(7,i) = end8Crd(i); + } + } + } + + int error = 0; + + // finally we the element using drawPolygon + error += theViewer.drawPolygon (coords, values, this->getTag()); + + return error; +} + +Response* +EightNodeQuad::setResponse(const char **argv, int argc, + OPS_Stream &output) +{ + Response *theResponse =0; + + output.tag("ElementOutput"); + output.attr("eleType","EightNodeQuad"); + output.attr("eleTag",this->getTag()); + output.attr("node1",connectedExternalNodes[0]); + output.attr("node2",connectedExternalNodes[1]); + output.attr("node3",connectedExternalNodes[2]); + output.attr("node4",connectedExternalNodes[3]); + output.attr("node5",connectedExternalNodes[4]); + output.attr("node6",connectedExternalNodes[5]); + output.attr("node7",connectedExternalNodes[6]); + output.attr("node8",connectedExternalNodes[7]); + + char dataOut[10]; + if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) { + + for (int i=1; i<=nip; i++) { + sprintf(dataOut,"P1_%d",i); + output.tag("ResponseType",dataOut); + sprintf(dataOut,"P2_%d",i); + output.tag("ResponseType",dataOut); + } + + theResponse = new ElementResponse(this, 1, P); + } + + else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"integrPoint") == 0) { + + int pointNum = atoi(argv[1]); + if (pointNum > 0 && pointNum <= nip) { + + output.tag("GaussPoint"); + output.attr("number",pointNum); + output.attr("eta",pts[pointNum-1][0]); + output.attr("neta",pts[pointNum-1][1]); + + theResponse = theMaterial[pointNum-1]->setResponse(&argv[2], argc-2, output); + + output.endTag(); + + } + } + else if ((strcmp(argv[0],"stresses") ==0) || (strcmp(argv[0],"stress") ==0)) { + for (int i=0; igetClassTag()); + output.attr("tag", theMaterial[i]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma12"); + + output.endTag(); // GaussPoint + output.endTag(); // NdMaterialOutput + } + theResponse = new ElementResponse(this, 3, Vector(3*nip)); + } + + else if ((strcmp(argv[0],"stressesAtNodes") ==0) || (strcmp(argv[0],"stressAtNodes") ==0)) { + for (int i=0; igetClassTag()); + // output.attr("tag", theMaterial[i]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma12"); + + output.endTag(); // GaussPoint + // output.endTag(); // NdMaterialOutput + } + theResponse = new ElementResponse(this, 11, Vector(3*nnodes)); + } + + else if ((strcmp(argv[0],"strain") ==0) || (strcmp(argv[0],"strains") ==0)) { + for (int i=0; igetClassTag()); + output.attr("tag", theMaterial[i]->getTag()); + + output.tag("ResponseType","eta11"); + output.tag("ResponseType","eta22"); + output.tag("ResponseType","eta12"); + + output.endTag(); // GaussPoint + output.endTag(); // NdMaterialOutput + } + theResponse = new ElementResponse(this, 4, Vector(3*nip)); + } + + output.endTag(); // ElementOutput + + return theResponse; +} + +int +EightNodeQuad::getResponse(int responseID, Information &eleInfo) +{ + if (responseID == 1) { + + return eleInfo.setVector(this->getResistingForce()); + + } else if (responseID == 3) { + + // Loop over the integration points + static Vector stresses(3*nip); + int cnt = 0; + for (int i = 0; i < nip; i++) { + + // Get material stress response + const Vector &sigma = theMaterial[i]->getStress(); + stresses(cnt) = sigma(0); + stresses(cnt+1) = sigma(1); + stresses(cnt+2) = sigma(2); + cnt += 3; + } + + return eleInfo.setVector(stresses); + + } else if (responseID == 11) { + + // extrapolate stress from Gauss points to element nodes + static Vector stressGP(3*nip); + static Vector stressAtNodes(3*nnodes); + stressAtNodes.Zero(); + int cnt = 0; + // first get stress components (xx, yy, xy) at Gauss points + for (int i = 0; i < nip; i++) { + // Get material stress response + const Vector &sigma = theMaterial[i]->getStress(); + stressGP(cnt) = sigma(0); + stressGP(cnt+1) = sigma(1); + stressGP(cnt+2) = sigma(2); + cnt += 3; + } + + const double We[nnodes][nip] = {{2.0758287072798374, 0.1666666666666666, -0.075828707279838, 0.1666666666666666, -0.7636648162452683, 0.0969981495786018, 0.0969981495786018, -0.7636648162452683, 0.0}, + {0.1666666666666666, 2.0758287072798374, 0.1666666666666666, -0.075828707279838, -0.7636648162452683, -0.7636648162452683, 0.0969981495786018, 0.0969981495786018, 0.0}, + {-0.075828707279838, 0.1666666666666666, 2.0758287072798374, 0.1666666666666666, 0.0969981495786018, -0.7636648162452683, -0.7636648162452683, 0.0969981495786018, 0.0}, + {0.1666666666666666, -0.075828707279838, 0.1666666666666666, 2.0758287072798374, 0.0969981495786018, 0.0969981495786018, -0.7636648162452683, -0.7636648162452683, 0.0}, + {0.1666666666666666, 0.1666666666666666, 0.1666666666666666, 0.1666666666666666, 1.1454972243679027, -0.3333333333333333, -0.1454972243679028, -0.3333333333333333, 0.0}, + {0.1666666666666666, 0.1666666666666666, 0.1666666666666666, 0.1666666666666666, -0.3333333333333333, 1.1454972243679027, -0.3333333333333333, -0.1454972243679028, 0.0}, + {0.1666666666666666, 0.1666666666666666, 0.1666666666666666, 0.1666666666666666, -0.1454972243679028, -0.3333333333333333, 1.1454972243679027, -0.3333333333333333, 0.0}, + {0.1666666666666666, 0.1666666666666666, 0.1666666666666666, 0.1666666666666666, -0.3333333333333333, -0.1454972243679028, -0.3333333333333333, 1.1454972243679027, 0.0}}; + + int p, l; + for (int i = 0; i < nnodes; i++) { + for (int k = 0; k < 3; k++) { + p = 3*i + k; + for (int j = 0; j < nip; j++) { + l = 3*j + k; + stressAtNodes(p) += We[i][j] * stressGP(l); + // opserr << "stressAtNodes(" << p << ") = We[" << i << "][" << j << "] * stressGP(" << l << ") = " << We[i][j] << " * " << stressGP(l) << " = " << stressAtNodes(p) << "\n"; + } + } + } + + return eleInfo.setVector(stressAtNodes); + + } else if (responseID == 4) { + + // Loop over the integration points + static Vector stresses(3*nip); + int cnt = 0; + for (int i = 0; i < nip; i++) { + + // Get material stress response + const Vector &sigma = theMaterial[i]->getStrain(); + stresses(cnt) = sigma(0); + stresses(cnt+1) = sigma(1); + stresses(cnt+2) = sigma(2); + cnt += 3; + } + + return eleInfo.setVector(stresses); + + } else + + return -1; +} + +int +EightNodeQuad::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc < 1) + return -1; + + int res = -1; + + // quad pressure loading + if (strcmp(argv[0],"pressure") == 0) { + return param.addObject(2, this); + } + // a material parameter + else if ((strstr(argv[0],"material") != 0) && (strcmp(argv[0],"materialState") != 0)) { + + if (argc < 3) + return -1; + + int pointNum = atoi(argv[1]); + if (pointNum > 0 && pointNum <= nip) + return theMaterial[pointNum-1]->setParameter(&argv[2], argc-2, param); + else + return -1; + } + + // otherwise it could be just a forall material parameter + else { + + int matRes = res; + for (int i=0; isetParameter(argv, argc, param); + + if (matRes != -1) + res = matRes; + } + } + + return res; +} + +int +EightNodeQuad::updateParameter(int parameterID, Information &info) +{ + int res = -1; + int matRes = res; + switch (parameterID) { + case -1: + return -1; + + case 1: + + for (int i = 0; iupdateParameter(parameterID, info); + } + if (matRes != -1) { + res = matRes; + } + return res; + + case 2: + pressure = info.theDouble; + this->setPressureLoadAtNodes(); // update consistent nodal loads + return 0; + + default: + /* + if (parameterID >= 100) { // material parameter + int pointNum = parameterID/100; + if (pointNum > 0 && pointNum <= 4) + return theMaterial[pointNum-1]->updateParameter(parameterID-100*pointNum, info); + else + return -1; + } else // unknown + */ + return -1; + } +} + +double EightNodeQuad::shapeFunction(double s, double t) +{ + const Vector &nd1Crds = theNodes[0]->getCrds(); + const Vector &nd2Crds = theNodes[1]->getCrds(); + const Vector &nd3Crds = theNodes[2]->getCrds(); + const Vector &nd4Crds = theNodes[3]->getCrds(); + const Vector &nd5Crds = theNodes[4]->getCrds(); + const Vector &nd6Crds = theNodes[5]->getCrds(); + const Vector &nd7Crds = theNodes[6]->getCrds(); + const Vector &nd8Crds = theNodes[7]->getCrds(); + + double N1 = -(1-s)*(1-t)*(1+s+t)/4; + double N2 = -(1+s)*(1-t)*(1-s+t)/4; + double N3 = -(1+s)*(1+t)*(1-s-t)/4; + double N4 = -(1-s)*(1+t)*(1+s-t)/4; + + double N5 = (1-s*s)*(1-t)/2; + double N6 = (1+s)*(1-t*t)/2; + double N7 = (1-s*s)*(1+t)/2; + double N8 = (1-s)*(1-t*t)/2; + + shp[2][0] = N1; + shp[2][1] = N2; + shp[2][2] = N3; + shp[2][3] = N4; + shp[2][4] = N5; + shp[2][5] = N6; + shp[2][6] = N7; + shp[2][7] = N8; + + // derivatives + double N11 = -1*(-(1-t)*(1+s+t)+(1-s)*(1-t))/4; + double N21 = -1*((1-t)*(1-s+t)-(1+s)*(1-t))/4; + double N31 = -1*((1+t)*(1-s-t)-(1+s)*(1+t))/4; + double N41 = -1*(-(1+t)*(1+s-t)+(1-s)*(1+t))/4; + double N51 = -s*(1-t); + double N61 = (1-t*t)/2; + double N71 = -s*(1+t); + double N81 = -1*(1-t*t)/2; + double N12 = -1*(-(1-s)*(1+s+t)+(1-s)*(1-t))/4; + double N22 = -1*(-(1+s)*(1-s+t)+(1+s)*(1-t))/4; + double N32 = -1*((1+s)*(1-s-t)-(1+s)*(1+t))/4; + double N42 = -1*((1-s)*(1+s-t)-(1-s)*(1+t))/4; + double N52 = -1*(1-s*s)/2; + double N62 = -t*(1+s); + double N72 = (1-s*s)/2; + double N82 = -t*(1-s); + + // remains the same 2x2 matrix Cook Malkus Plesha 6.6, p. 180 + double J[2][2]; + + J[0][0] = nd1Crds(0)*N11 + nd2Crds(0)*N21 + nd3Crds(0)*N31 + nd4Crds(0)*N41 + + nd5Crds(0)*N51 + nd6Crds(0)*N61 + nd7Crds(0)*N71 + nd8Crds(0)*N81; + + J[0][1] = nd1Crds(0)*N12 + nd2Crds(0)*N22 + nd3Crds(0)*N32 + nd4Crds(0)*N42 + + nd5Crds(0)*N52 + nd6Crds(0)*N62 + nd7Crds(0)*N72 + nd8Crds(0)*N82; + + J[1][0] = nd1Crds(1)*N11 + nd2Crds(1)*N21 + nd3Crds(1)*N31 + nd4Crds(1)*N41 + + nd5Crds(1)*N51 + nd6Crds(1)*N61 + nd7Crds(1)*N71 + nd8Crds(1)*N81; + + J[1][1] = nd1Crds(1)*N12 + nd2Crds(1)*N22 + nd3Crds(1)*N32 + nd4Crds(1)*N42 + + nd5Crds(1)*N52 + nd6Crds(1)*N62 + nd7Crds(1)*N72 + nd8Crds(1)*N82; + + double detJ = J[0][0]*J[1][1] - J[0][1]*J[1][0]; + + double L[2][2]; + + // L = inv(J) + L[0][0] = J[1][1]/detJ; + L[1][0] = -J[0][1]/detJ; + L[0][1] = -J[1][0]/detJ; + L[1][1] = J[0][0]/detJ; + + double L00 = L[0][0]; + double L10 = L[1][0]; + double L01 = L[0][1]; + double L11 = L[1][1]; + + shp[0][0] = L00*N11 + L01*N12; + shp[0][1] = L00*N21 + L01*N22; + shp[0][2] = L00*N31 + L01*N32; + shp[0][3] = L00*N41 + L01*N42; + shp[0][4] = L00*N51 + L01*N52; + shp[0][5] = L00*N61 + L01*N62; + shp[0][6] = L00*N71 + L01*N72; + shp[0][7] = L00*N81 + L01*N82; + + shp[1][0] = L10*N11 + L11*N12; + shp[1][1] = L10*N21 + L11*N22; + shp[1][2] = L10*N31 + L11*N32; + shp[1][3] = L10*N41 + L11*N42; + shp[1][4] = L10*N51 + L11*N52; + shp[1][5] = L10*N61 + L11*N62; + shp[1][6] = L10*N71 + L11*N72; + shp[1][7] = L10*N81 + L11*N82; + + return detJ; +} + +void +EightNodeQuad::setPressureLoadAtNodes(void) +{ + pressureLoad.Zero(); + + if (pressure == 0.0) + return; + + const Vector &node1 = theNodes[0]->getCrds(); + const Vector &node2 = theNodes[1]->getCrds(); + const Vector &node3 = theNodes[2]->getCrds(); + const Vector &node4 = theNodes[3]->getCrds(); + const Vector &node5 = theNodes[4]->getCrds(); + const Vector &node6 = theNodes[5]->getCrds(); + const Vector &node7 = theNodes[6]->getCrds(); + const Vector &node8 = theNodes[7]->getCrds(); + + double x1 = node1(0); + double y1 = node1(1); + double x2 = node2(0); + double y2 = node2(1); + double x3 = node3(0); + double y3 = node3(1); + double x4 = node4(0); + double y4 = node4(1); + double x5 = node5(0); + double y5 = node5(1); + double x6 = node6(0); + double y6 = node6(1); + double x7 = node7(0); + double y7 = node7(1); + double x8 = node8(0); + double y8 = node8(1); + + double dx15 = x5-x1; + double dy15 = y5-y1; + double dx52 = x2-x5; + double dy52 = y2-y5; + double dx26 = x6-x2; + double dy26 = y6-y2; + double dx63 = x3-x6; + double dy63 = y3-y6; + double dx37 = x7-x3; + double dy37 = y7-y3; + double dx74 = x4-x7; + double dy74 = y4-y7; + double dx48 = x8-x4; + double dy48 = y8-y4; + double dx81 = x1-x8; + double dy81 = y1-y8; + + double fac1 = 0.3333333333333333; + double fac2 = 0.6666666666666667; + + // Contribution from side 15 + pressureLoad(0) += pressure*fac1*dy15; + pressureLoad(8) += pressure*fac2*dy15; + pressureLoad(1) += pressure*fac1*-dx15; + pressureLoad(9) += pressure*fac2*-dx15; + + // Contribution from side 52 + pressureLoad(8) += pressure*fac2*dy52; + pressureLoad(2) += pressure*fac1*dy52; + pressureLoad(9) += pressure*fac2*-dx52; + pressureLoad(3) += pressure*fac1*-dx52; + + // Contribution from side 26 + pressureLoad(2) += pressure*fac1*dy26; + pressureLoad(10) += pressure*fac2*dy26; + pressureLoad(3) += pressure*fac1*-dx26; + pressureLoad(11) += pressure*fac2*-dx26; + + // Contribution from side 63 + pressureLoad(10) += pressure*fac2*dy63; + pressureLoad(4) += pressure*fac1*dy63; + pressureLoad(11) += pressure*fac2*-dx63; + pressureLoad(5) += pressure*fac1*-dx63; + + // Contribution from side 37 + pressureLoad(4) += pressure*fac1*dy37; + pressureLoad(12) += pressure*fac2*dy37; + pressureLoad(5) += pressure*fac1*-dx37; + pressureLoad(13) += pressure*fac2*-dx37; + + // Contribution from side 74 + pressureLoad(12) += pressure*fac2*dy74; + pressureLoad(6) += pressure*fac1*dy74; + pressureLoad(13) += pressure*fac2*-dx74; + pressureLoad(7) += pressure*fac1*-dx74; + + // Contribution from side 48 + pressureLoad(6) += pressure*fac1*dy48; + pressureLoad(14) += pressure*fac2*dy48; + pressureLoad(7) += pressure*fac1*-dx48; + pressureLoad(15) += pressure*fac2*-dx48; + + // Contribution from side 81 + pressureLoad(14) += pressure*fac2*dy81; + pressureLoad(0) += pressure*fac1*dy81; + pressureLoad(15) += pressure*fac2*-dx81; + pressureLoad(1) += pressure*fac1*-dx81; + + //pressureLoad = pressureLoad*thickness; +} diff --git a/SRC/element/fourNodeQuad/EightNodeQuad.h b/SRC/element/fourNodeQuad/EightNodeQuad.h new file mode 100644 index 0000000000..a87debf66a --- /dev/null +++ b/SRC/element/fourNodeQuad/EightNodeQuad.h @@ -0,0 +1,139 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// based on FourNodeQuad by MHS +// Written: Seweryn Kokot, Opole University of Technology, Poland +// Created: Aug 2020 +// +// Description: This file contains the class definition for EightNodeQuad. + +#ifndef EightNodeQuad_h +#define EightNodeQuad_h + +#ifndef _bool_h +#include "bool.h" +#endif + +#include +#include +#include +#include + +class Node; +class NDMaterial; +class Response; + +class EightNodeQuad : public Element { +public: + EightNodeQuad(int tag, int nd1, int nd2, int nd3, int nd4, int nd5, int nd6, + int nd7, int nd8, NDMaterial &m, const char *type, double t, + double pressure = 0.0, double rho = 0.0, double b1 = 0.0, + double b2 = 0.0); + EightNodeQuad(); + ~EightNodeQuad(); + + const char *getClassType(void) const { return "EightNodeQuad"; }; + + int getNumExternalNodes(void) const; + const ID &getExternalNodes(void); + Node **getNodePtrs(void); + + int getNumDOF(void); + void setDomain(Domain *theDomain); + + // public methods to set the state of the element + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + int update(void); + + // public methods to obtain stiffness, mass, damping and residual information + const Matrix &getTangentStiff(void); + const Matrix &getInitialStiff(void); + const Matrix &getMass(void); + + void zeroLoad(); + int addLoad(ElementalLoad *theLoad, double loadFactor); + int addInertiaLoadToUnbalance(const Vector &accel); + + const Vector &getResistingForce(void); + const Vector &getResistingForceIncInertia(void); + + // public methods for element output + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + + int displaySelf(Renderer &, int mode, float fact, + const char **displayModes = 0, int numModes = 0); + void Print(OPS_Stream &s, int flag = 0); + + Response *setResponse(const char **argv, int argc, OPS_Stream &s); + + int getResponse(int responseID, Information &eleInformation); + + int setParameter(const char **argv, int argc, Parameter ¶m); + int updateParameter(int parameterID, Information &info); + + // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial + // stresses. + friend class PyLiq1; + friend class TzLiq1; + +protected: +private: + // private attributes - a copy for each object of the class + + static constexpr int nip = 9; // number of integration/Gauss points + static constexpr int nnodes = 8; // number of nodes + + NDMaterial **theMaterial; // pointer to the ND material objects + + ID connectedExternalNodes; // Tags of quad nodes + + Node *theNodes[nnodes]; + + static double matrixData[(nnodes*2)*(nnodes*2)]; // array data for matrix + static Matrix K; // Element stiffness, damping, and mass Matrix + static Vector P; // Element resisting force vector + Vector Q; // Applied nodal loads + double b[2]; // Body forces + + double appliedB[2]; // Body forces applied with load pattern, C.McGann, + // U.Washington + int applyLoad; // flag for body force in load, C.McGann, U.Washington + + Vector pressureLoad; // Pressure load at nodes + + double thickness; // Element thickness + double pressure; // Normal surface traction (pressure) over entire element + // Note: positive for outward normal + double rho; + static double shp[3][nnodes]; // Stores shape functions and derivatives (overwritten) + static double pts[nip][2]; // Stores quadrature points + static double wts[nip]; // Stores quadrature weights + + // private member functions - only objects of this class can call these + double shapeFunction(double xi, double eta); + void setPressureLoadAtNodes(void); + + Matrix *Ki; +}; + +#endif diff --git a/SRC/element/fourNodeQuad/FourNodeQuad.cpp b/SRC/element/fourNodeQuad/FourNodeQuad.cpp index db751fe308..0d544e7165 100644 --- a/SRC/element/fourNodeQuad/FourNodeQuad.cpp +++ b/SRC/element/fourNodeQuad/FourNodeQuad.cpp @@ -900,7 +900,7 @@ FourNodeQuad::Print(OPS_Stream &s, int flag) for (i=0; igetCrds(); - const Vector &nodeDisp = theNodes[i]->getDisp(); + // const Vector &nodeDisp = theNodes[i]->getDisp(); s << "#NODE " << nodeCrd(0) << " " << nodeCrd(1) << " " << endln; } @@ -1095,6 +1095,27 @@ FourNodeQuad::setResponse(const char **argv, int argc, theResponse = new ElementResponse(this, 3, Vector(12)); } + else if ((strcmp(argv[0],"stressesAtNodes") ==0) || (strcmp(argv[0],"stressAtNodes") ==0)) { + for (int i=0; i<4; i++) { // nnodes + output.tag("NodalPoint"); + output.attr("number",i+1); + // output.attr("eta",pts[i][0]); + // output.attr("neta",pts[i][1]); + + // output.tag("NdMaterialOutput"); + // output.attr("classType", theMaterial[i]->getClassTag()); + // output.attr("tag", theMaterial[i]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma12"); + + output.endTag(); // GaussPoint + // output.endTag(); // NdMaterialOutput + } + theResponse = new ElementResponse(this, 11, Vector(12)); // 3 * nnodes + } + else if ((strcmp(argv[0],"strain") ==0) || (strcmp(argv[0],"strains") ==0)) { for (int i=0; i<4; i++) { output.tag("GaussPoint"); @@ -1145,6 +1166,43 @@ FourNodeQuad::getResponse(int responseID, Information &eleInfo) return eleInfo.setVector(stresses); + } else if (responseID == 11) { + + // extrapolate stress from Gauss points to element nodes + static Vector stressGP(12); // 3*nip + static Vector stressAtNodes(12); // 3*nnodes + stressAtNodes.Zero(); + int cnt = 0; + // first get stress components (xx, yy, xy) at Gauss points + for (int i = 0; i < 4; i++) { // nip + // Get material stress response + const Vector &sigma = theMaterial[i]->getStress(); + stressGP(cnt) = sigma(0); + stressGP(cnt+1) = sigma(1); + stressGP(cnt+2) = sigma(2); + cnt += 3; + } + + // [nnodes][nip] + const double We[4][4] = {{1.8660254037844386, -0.5, 0.1339745962155614, -0.5}, + {-0.5, 1.8660254037844386, -0.5, 0.1339745962155614}, + {0.1339745962155614, -0.5, 1.8660254037844386, -0.5}, + {-0.5, 0.1339745962155614, -0.5, 1.8660254037844386}}; + + int p, l; + for (int i = 0; i < 4; i++) { // nnodes + for (int k = 0; k < 3; k++) { // number of stress components + p = 3*i + k; + for (int j = 0; j < 4; j++) { // nip + l = 3*j + k; + stressAtNodes(p) += We[i][j] * stressGP(l); + // opserr << "stressAtNodes(" << p << ") = We[" << i << "][" << j << "] * stressGP(" << l << ") = " << We[i][j] << " * " << stressGP(l) << " = " << stressAtNodes(p) << "\n"; + } + } + } + + return eleInfo.setVector(stressAtNodes); + } else if (responseID == 4) { // Loop over the integration points diff --git a/SRC/element/fourNodeQuad/Makefile b/SRC/element/fourNodeQuad/Makefile index d17294c399..21b8305e9e 100644 --- a/SRC/element/fourNodeQuad/Makefile +++ b/SRC/element/fourNodeQuad/Makefile @@ -6,6 +6,9 @@ OBJS = FourNodeQuad.o \ EnhancedQuad.o \ FourNodeQuad3d.o \ NineNodeMixedQuad.o \ + NineNodeQuad.o \ + EightNodeQuad.o \ + SixNodeTri.o \ FourNodeQuadWithSensitivity.o all: $(OBJS) diff --git a/SRC/element/fourNodeQuad/NineNodeQuad.cpp b/SRC/element/fourNodeQuad/NineNodeQuad.cpp new file mode 100644 index 0000000000..8d5700fc9d --- /dev/null +++ b/SRC/element/fourNodeQuad/NineNodeQuad.cpp @@ -0,0 +1,1698 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// based on FourNodeQuad by MHS +// Written: Seweryn Kokot, Opole University of Technology, Poland +// Created: Aug 2020 +// +// Description: This file contains the class definition for NineNodeQuad. + +#include "NineNodeQuad.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void* OPS_NineNodeQuad() +{ + int ndm = OPS_GetNDM(); + int ndf = OPS_GetNDF(); + + if (ndm != 2 || ndf != 2) { + opserr << "WARNING -- model dimensions and/or nodal DOF not compatible with quad element\n"; + return 0; + } + + if (OPS_GetNumRemainingInputArgs() < 13) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element NineNodeQuad eleTag? Node1? Node2? Node3? Node4? Node5? Node6? Node7? Node8? Node9? thk? type? matTag? \n"; + return 0; + } + + // NineNodeQuadId, iNode, jNode, kNode, lNode + // nNode, mNode, pNode, qNode, cNode + int idata[10]; + int num = 10; + if (OPS_GetIntInput(&num,idata) < 0) { + opserr<<"WARNING: invalid integer inputs\n"; + return 0; + } + + double thk = 1.0; + num = 1; + if (OPS_GetDoubleInput(&num,&thk) < 0) { + opserr<<"WARNING: invalid double inputs\n"; + return 0; + } + + const char* type = OPS_GetString(); + + int matTag; + num = 1; + if (OPS_GetIntInput(&num,&matTag) < 0) { + opserr<<"WARNING: invalid matTag\n"; + return 0; + } + + NDMaterial* mat = OPS_getNDMaterial(matTag); + if (mat == 0) { + opserr << "WARNING material not found\n"; + opserr << "Material: " << matTag; + opserr << "\nNineNodeQuad element: " << idata[0] << endln; + return 0; + } + + // p, rho, b1, b2 + double data[4] = {0,0,0,0}; + num = OPS_GetNumRemainingInputArgs(); + if (num > 4) { + num = 4; + } + if (num > 0) { + if (OPS_GetDoubleInput(&num,data) < 0) { + opserr<<"WARNING: invalid integer data\n"; + return 0; + } + } + + return new NineNodeQuad(idata[0],idata[1],idata[2],idata[3],idata[4], + idata[5],idata[6],idata[7],idata[8],idata[9], + *mat,type,thk,data[0],data[1],data[2],data[3]); +} + + +double NineNodeQuad::matrixData[(nnodes*2)*(nnodes*2)]; +Matrix NineNodeQuad::K(matrixData, 2*nnodes, 2*nnodes); +Vector NineNodeQuad::P(2*nnodes); +double NineNodeQuad::shp[3][nnodes]; +double NineNodeQuad::pts[nip][2]; +double NineNodeQuad::wts[nip]; + +NineNodeQuad::NineNodeQuad(int tag, int nd1, int nd2, int nd3, int nd4, + int nd5, int nd6, int nd7, int nd8, int nd9, + NDMaterial &m, const char *type, double t, + double p, double r, double b1, double b2) +:Element (tag, ELE_TAG_NineNodeQuad), + theMaterial(0), connectedExternalNodes(nnodes), + Q(2*nnodes), applyLoad(0), pressureLoad(2*nnodes), thickness(t), pressure(p), rho(r), Ki(0) +{ + pts[0][0] = -0.7745966692414834; + pts[0][1] = -0.7745966692414834; + pts[1][0] = 0.7745966692414834; + pts[1][1] = -0.7745966692414834; + pts[2][0] = 0.7745966692414834; + pts[2][1] = 0.7745966692414834; + pts[3][0] = -0.7745966692414834; + pts[3][1] = 0.7745966692414834; + pts[4][0] = 0.0; + pts[4][1] = -0.7745966692414834; + pts[5][0] = 0.7745966692414834; + pts[5][1] = 0.0; + pts[6][0] = 0.0; + pts[6][1] = 0.7745966692414834; + pts[7][0] = -0.7745966692414834; + pts[7][1] = 0.0; + pts[8][0] = 0.0; + pts[8][1] = 0.0; + + wts[0] = 0.30864197530864196; + wts[1] = 0.30864197530864196; + wts[2] = 0.30864197530864196; + wts[3] = 0.30864197530864196; + wts[4] = 0.49382716049382713; + wts[5] = 0.49382716049382713; + wts[6] = 0.49382716049382713; + wts[7] = 0.49382716049382713; + wts[8] = 0.7901234567901234; + + if (strcmp(type,"PlaneStrain") != 0 && strcmp(type,"PlaneStress") != 0 + && strcmp(type,"PlaneStrain2D") != 0 && strcmp(type,"PlaneStress2D") != 0) { + opserr << "NineNodeQuad::NineNodeQuad -- improper material type: " << type << "for NineNodeQuad\n"; + exit(-1); + } + + // Body forces + b[0] = b1; + b[1] = b2; + + // Allocate arrays of pointers to NDMaterials + theMaterial = new NDMaterial *[nip]; + + if (theMaterial == 0) { + opserr << "NineNodeQuad::NineNodeQuad - failed allocate material model pointer\n"; + exit(-1); + } + + int i; + for (i = 0; i < nip; i++) { + + // Get copies of the material model for each integration point + theMaterial[i] = m.getCopy(type); + + // Check allocation + if (theMaterial[i] == 0) { + opserr << "NineNodeQuad::NineNodeQuad -- failed to get a copy of material model\n"; + exit(-1); + } + } + + // Set connected external node IDs + connectedExternalNodes(0) = nd1; + connectedExternalNodes(1) = nd2; + connectedExternalNodes(2) = nd3; + connectedExternalNodes(3) = nd4; + connectedExternalNodes(4) = nd5; + connectedExternalNodes(5) = nd6; + connectedExternalNodes(6) = nd7; + connectedExternalNodes(7) = nd8; + connectedExternalNodes(8) = nd9; + + for (i=0; igetNode(Nd1); + theNodes[1] = theDomain->getNode(Nd2); + theNodes[2] = theDomain->getNode(Nd3); + theNodes[3] = theDomain->getNode(Nd4); + theNodes[4] = theDomain->getNode(Nd5); + theNodes[5] = theDomain->getNode(Nd6); + theNodes[6] = theDomain->getNode(Nd7); + theNodes[7] = theDomain->getNode(Nd8); + theNodes[8] = theDomain->getNode(Nd9); + + if (theNodes[0] == 0 || theNodes[1] == 0 || theNodes[2] == 0 || theNodes[3] == 0 || + theNodes[4] == 0 || theNodes[5] == 0 || theNodes[6] == 0 || theNodes[7] == 0 || + theNodes[8] == 0) { + //opserr << "FATAL ERROR NineNodeQuad (tag: %d), node not found in domain", + // this->getTag()); + + return; + } + + int dofNd1 = theNodes[0]->getNumberDOF(); + int dofNd2 = theNodes[1]->getNumberDOF(); + int dofNd3 = theNodes[2]->getNumberDOF(); + int dofNd4 = theNodes[3]->getNumberDOF(); + int dofNd5 = theNodes[4]->getNumberDOF(); + int dofNd6 = theNodes[5]->getNumberDOF(); + int dofNd7 = theNodes[6]->getNumberDOF(); + int dofNd8 = theNodes[7]->getNumberDOF(); + int dofNd9 = theNodes[8]->getNumberDOF(); + + if (dofNd1 != 2 || dofNd2 != 2 || dofNd3 != 2 || dofNd4 != 2 || + dofNd5 != 2 || dofNd6 != 2 || dofNd7 != 2 || dofNd8 != 2 || dofNd9 != 2) { + //opserr << "FATAL ERROR NineNodeQuad (tag: %d), has differing number of DOFs at its nodes", + // this->getTag()); + + return; + } + this->DomainComponent::setDomain(theDomain); + + // Compute consistent nodal loads due to pressure + this->setPressureLoadAtNodes(); +} + +int +NineNodeQuad::commitState() +{ + int retVal = 0; + + // call element commitState to do any base class stuff + if ((retVal = this->Element::commitState()) != 0) { + opserr << "NineNodeQuad::commitState () - failed in base class"; + } + + // Loop over the integration points and commit the material states + for (int i = 0; i < nip; i++) + retVal += theMaterial[i]->commitState(); + + return retVal; +} + +int +NineNodeQuad::revertToLastCommit() +{ + int retVal = 0; + + // Loop over the integration points and revert to last committed state + for (int i = 0; i < nip; i++) + retVal += theMaterial[i]->revertToLastCommit(); + + return retVal; +} + +int +NineNodeQuad::revertToStart() +{ + int retVal = 0; + + // Loop over the integration points and revert states to start + for (int i = 0; i < nip; i++) + retVal += theMaterial[i]->revertToStart(); + + return retVal; +} + + +int +NineNodeQuad::update() +{ + const Vector &disp1 = theNodes[0]->getTrialDisp(); + const Vector &disp2 = theNodes[1]->getTrialDisp(); + const Vector &disp3 = theNodes[2]->getTrialDisp(); + const Vector &disp4 = theNodes[3]->getTrialDisp(); + const Vector &disp5 = theNodes[4]->getTrialDisp(); + const Vector &disp6 = theNodes[5]->getTrialDisp(); + const Vector &disp7 = theNodes[6]->getTrialDisp(); + const Vector &disp8 = theNodes[7]->getTrialDisp(); + const Vector &disp9 = theNodes[8]->getTrialDisp(); + + static double u[2][nnodes]; + + u[0][0] = disp1(0); + u[1][0] = disp1(1); + u[0][1] = disp2(0); + u[1][1] = disp2(1); + u[0][2] = disp3(0); + u[1][2] = disp3(1); + u[0][3] = disp4(0); + u[1][3] = disp4(1); + u[0][4] = disp5(0); + u[1][4] = disp5(1); + u[0][5] = disp6(0); + u[1][5] = disp6(1); + u[0][6] = disp7(0); + u[1][6] = disp7(1); + u[0][7] = disp8(0); + u[1][7] = disp8(1); + u[0][8] = disp9(0); + u[1][8] = disp9(1); + + static Vector eps(3); + + int ret = 0; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + this->shapeFunction(pts[i][0], pts[i][1]); + + // Interpolate strains + //eps = B*u; + //eps.addMatrixVector(0.0, B, u, 1.0); + eps.Zero(); + for (int beta = 0; beta < nnodes; beta++) { + eps(0) += shp[0][beta]*u[0][beta]; + eps(1) += shp[1][beta]*u[1][beta]; + eps(2) += shp[0][beta]*u[1][beta] + shp[1][beta]*u[0][beta]; + } + + // Set the material strain + ret += theMaterial[i]->setTrialStrain(eps); + } + + return ret; +} + + +const Matrix& +NineNodeQuad::getTangentStiff() +{ + + K.Zero(); + + double dvol; + double DB[3][2]; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + dvol = this->shapeFunction(pts[i][0], pts[i][1]); + dvol *= (thickness*wts[i]); + + // Get the material tangent + const Matrix &D = theMaterial[i]->getTangent(); + + // Perform numerical integration + //K = K + (B^ D * B) * intWt(i)*intWt(j) * detJ; + //K.addMatrixTripleProduct(1.0, B, D, intWt(i)*intWt(j)*detJ); + + double D00 = D(0,0); double D01 = D(0,1); double D02 = D(0,2); + double D10 = D(1,0); double D11 = D(1,1); double D12 = D(1,2); + double D20 = D(2,0); double D21 = D(2,1); double D22 = D(2,2); + + // for (int beta = 0, ib = 0, colIb =0, colIbP1 = 8; + // beta < 4; + // beta++, ib += 2, colIb += 16, colIbP1 += 16) { + + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia += 2) { + for (int beta = 0, ib = 0; beta < nnodes; beta++, ib += 2) { + + DB[0][0] = dvol * (D00 * shp[0][beta] + D02 * shp[1][beta]); + DB[1][0] = dvol * (D10 * shp[0][beta] + D12 * shp[1][beta]); + DB[2][0] = dvol * (D20 * shp[0][beta] + D22 * shp[1][beta]); + DB[0][1] = dvol * (D01 * shp[1][beta] + D02 * shp[0][beta]); + DB[1][1] = dvol * (D11 * shp[1][beta] + D12 * shp[0][beta]); + DB[2][1] = dvol * (D21 * shp[1][beta] + D22 * shp[0][beta]); + + K(ia,ib) += shp[0][alpha]*DB[0][0] + shp[1][alpha]*DB[2][0]; + K(ia,ib+1) += shp[0][alpha]*DB[0][1] + shp[1][alpha]*DB[2][1]; + K(ia+1,ib) += shp[1][alpha]*DB[1][0] + shp[0][alpha]*DB[2][0]; + K(ia+1,ib+1) += shp[1][alpha]*DB[1][1] + shp[0][alpha]*DB[2][1]; + // matrixData[colIb + ia] += shp[0][alpha]*DB[0][0] + shp[1][alpha]*DB[2][0]; + //matrixData[colIbP1 + ia] += shp[0][alpha]*DB[0][1] + shp[1][alpha]*DB[2][1]; + //matrixData[colIb + ia+1] += shp[1][alpha]*DB[1][0] + shp[0][alpha]*DB[2][0]; + //matrixData[colIbP1 + ia+1] += shp[1][alpha]*DB[1][1] + shp[0][alpha]*DB[2][1]; + + } + } + } + + return K; +} + + +const Matrix& +NineNodeQuad::getInitialStiff() +{ + if (Ki != 0) + return *Ki; + + K.Zero(); + + double dvol; + double DB[3][2]; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + dvol = this->shapeFunction(pts[i][0], pts[i][1]); + dvol *= (thickness*wts[i]); + + // Get the material tangent + const Matrix &D = theMaterial[i]->getInitialTangent(); + + double D00 = D(0,0); double D01 = D(0,1); double D02 = D(0,2); + double D10 = D(1,0); double D11 = D(1,1); double D12 = D(1,2); + double D20 = D(2,0); double D21 = D(2,1); double D22 = D(2,2); + + // Perform numerical integration + //K = K + (B^ D * B) * intWt(i)*intWt(j) * detJ; + //K.addMatrixTripleProduct(1.0, B, D, intWt(i)*intWt(j)*detJ); + for (int beta = 0, ib = 0, colIb =0, colIbP1 = 8; + beta < nnodes; + beta++, ib += 2, colIb += 16, colIbP1 += 16) { + + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia += 2) { + + DB[0][0] = dvol * (D00 * shp[0][beta] + D02 * shp[1][beta]); + DB[1][0] = dvol * (D10 * shp[0][beta] + D12 * shp[1][beta]); + DB[2][0] = dvol * (D20 * shp[0][beta] + D22 * shp[1][beta]); + DB[0][1] = dvol * (D01 * shp[1][beta] + D02 * shp[0][beta]); + DB[1][1] = dvol * (D11 * shp[1][beta] + D12 * shp[0][beta]); + DB[2][1] = dvol * (D21 * shp[1][beta] + D22 * shp[0][beta]); + + matrixData[colIb + ia] += shp[0][alpha]*DB[0][0] + shp[1][alpha]*DB[2][0]; + matrixData[colIbP1 + ia] += shp[0][alpha]*DB[0][1] + shp[1][alpha]*DB[2][1]; + matrixData[colIb + ia+1] += shp[1][alpha]*DB[1][0] + shp[0][alpha]*DB[2][0]; + matrixData[colIbP1 + ia+1] += shp[1][alpha]*DB[1][1] + shp[0][alpha]*DB[2][1]; + } + } + } + + Ki = new Matrix(K); + return K; +} + +const Matrix& +NineNodeQuad::getMass() +{ + K.Zero(); + + int i; + static double rhoi[nip]; + double sum = 0.0; + for (i = 0; i < nip; i++) { + if (rho == 0) + rhoi[i] = theMaterial[i]->getRho(); + else + rhoi[i] = rho; + sum += rhoi[i]; + } + + if (sum == 0.0) + return K; + + double rhodvol, Nrho; + + // Compute a lumped mass matrix + for (i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + rhodvol = this->shapeFunction(pts[i][0], pts[i][1]); + + // Element plus material density ... MAY WANT TO REMOVE ELEMENT DENSITY + rhodvol *= (rhoi[i]*thickness*wts[i]); + + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia++) { + Nrho = shp[2][alpha]*rhodvol; + K(ia,ia) += Nrho; + ia++; + K(ia,ia) += Nrho; + } + } + + return K; +} + +void +NineNodeQuad::zeroLoad(void) +{ + Q.Zero(); + + applyLoad = 0; + + appliedB[0] = 0.0; + appliedB[1] = 0.0; + + return; +} + +int +NineNodeQuad::addLoad(ElementalLoad *theLoad, double loadFactor) +{ + // Added option for applying body forces in load pattern: C.McGann, U.Washington + int type; + const Vector &data = theLoad->getData(type, loadFactor); + + if (type == LOAD_TAG_SelfWeight) { + applyLoad = 1; + appliedB[0] += loadFactor*data(0)*b[0]; + appliedB[1] += loadFactor*data(1)*b[1]; + return 0; + } else { + opserr << "NineNodeQuad::addLoad - load type unknown for ele with tag: " << this->getTag() << endln; + return -1; + } + + return -1; +} + +int +NineNodeQuad::addInertiaLoadToUnbalance(const Vector &accel) +{ + int i; + static double rhoi[nip]; + double sum = 0.0; + for (i = 0; i < nip; i++) { + rhoi[i] = theMaterial[i]->getRho(); + sum += rhoi[i]; + } + + if (sum == 0.0) + return 0; + + // Get R * accel from the nodes + const Vector &Raccel1 = theNodes[0]->getRV(accel); + const Vector &Raccel2 = theNodes[1]->getRV(accel); + const Vector &Raccel3 = theNodes[2]->getRV(accel); + const Vector &Raccel4 = theNodes[3]->getRV(accel); + const Vector &Raccel5 = theNodes[4]->getRV(accel); + const Vector &Raccel6 = theNodes[5]->getRV(accel); + const Vector &Raccel7 = theNodes[6]->getRV(accel); + const Vector &Raccel8 = theNodes[7]->getRV(accel); + const Vector &Raccel9 = theNodes[8]->getRV(accel); + + if (2 != Raccel1.Size() || 2 != Raccel2.Size() || 2 != Raccel3.Size() || + 2 != Raccel4.Size() || 2 != Raccel5.Size() || 2 != Raccel6.Size() || + 2 != Raccel7.Size() || 2 != Raccel8.Size() || 2 != Raccel9.Size()) { + opserr << "NineNodeQuad::addInertiaLoadToUnbalance matrix and vector sizes are incompatible\n"; + return -1; + } + + static double ra[2*nnodes]; + + ra[0] = Raccel1(0); + ra[1] = Raccel1(1); + ra[2] = Raccel2(0); + ra[3] = Raccel2(1); + ra[4] = Raccel3(0); + ra[5] = Raccel3(1); + ra[6] = Raccel4(0); + ra[7] = Raccel4(1); + ra[8] = Raccel5(0); + ra[9] = Raccel5(1); + ra[10] = Raccel6(0); + ra[11] = Raccel6(1); + ra[12] = Raccel7(0); + ra[13] = Raccel7(1); + ra[14] = Raccel8(0); + ra[15] = Raccel8(1); + ra[16] = Raccel9(0); + ra[17] = Raccel9(1); + + // Compute mass matrix + this->getMass(); + + // Want to add ( - fact * M R * accel ) to unbalance + // Take advantage of lumped mass matrix + for (i = 0; i < 2*nnodes; i++) + Q(i) += -K(i,i)*ra[i]; + + return 0; +} + +const Vector& +NineNodeQuad::getResistingForce() +{ + P.Zero(); + + double dvol; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + dvol = this->shapeFunction(pts[i][0], pts[i][1]); + dvol *= (thickness*wts[i]); + + // Get material stress response + const Vector &sigma = theMaterial[i]->getStress(); + + // Perform numerical integration on internal force + //P = P + (B^ sigma) * intWt(i)*intWt(j) * detJ; + //P.addMatrixTransposeVector(1.0, B, sigma, intWt(i)*intWt(j)*detJ); + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia += 2) { + + P(ia) += dvol*(shp[0][alpha]*sigma(0) + shp[1][alpha]*sigma(2)); + + P(ia+1) += dvol*(shp[1][alpha]*sigma(1) + shp[0][alpha]*sigma(2)); + + // Subtract equiv. body forces from the nodes + //P = P - (N^ b) * intWt(i)*intWt(j) * detJ; + //P.addMatrixTransposeVector(1.0, N, b, -intWt(i)*intWt(j)*detJ); + if (applyLoad == 0) { + P(ia) -= dvol*(shp[2][alpha]*b[0]); + P(ia+1) -= dvol*(shp[2][alpha]*b[1]); + } else { + P(ia) -= dvol*(shp[2][alpha]*appliedB[0]); + P(ia+1) -= dvol*(shp[2][alpha]*appliedB[1]); + } + } + } + + // Subtract pressure loading from resisting force + if (pressure != 0.0) { + //P = P - pressureLoad; + P.addVector(1.0, pressureLoad, -1.0); + } + + // Subtract other external nodal loads ... P_res = P_int - P_ext + //P = P - Q; + P.addVector(1.0, Q, -1.0); + + return P; +} + +const Vector& +NineNodeQuad::getResistingForceIncInertia() +{ + int i; + static double rhoi[nip]; + double sum = 0.0; + for (i = 0; i < nip; i++) { + rhoi[i] = theMaterial[i]->getRho(); + sum += rhoi[i]; + } + + // if no mass terms .. just add damping terms + if (sum == 0.0) { + this->getResistingForce(); + + // add the damping forces if rayleigh damping + if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P += this->getRayleighDampingForces(); + + return P; + } + + const Vector &accel1 = theNodes[0]->getTrialAccel(); + const Vector &accel2 = theNodes[1]->getTrialAccel(); + const Vector &accel3 = theNodes[2]->getTrialAccel(); + const Vector &accel4 = theNodes[3]->getTrialAccel(); + const Vector &accel5 = theNodes[4]->getTrialAccel(); + const Vector &accel6 = theNodes[5]->getTrialAccel(); + const Vector &accel7 = theNodes[6]->getTrialAccel(); + const Vector &accel8 = theNodes[7]->getTrialAccel(); + const Vector &accel9 = theNodes[8]->getTrialAccel(); + + static double a[2*nnodes]; + + a[0] = accel1(0); + a[1] = accel1(1); + a[2] = accel2(0); + a[3] = accel2(1); + a[4] = accel3(0); + a[5] = accel3(1); + a[6] = accel4(0); + a[7] = accel4(1); + a[8] = accel5(0); + a[9] = accel5(1); + a[10] = accel6(0); + a[11] = accel6(1); + a[12] = accel7(0); + a[13] = accel7(1); + a[14] = accel8(0); + a[15] = accel8(1); + a[16] = accel9(0); + a[17] = accel9(1); + + // Compute the current resisting force + this->getResistingForce(); + + // Compute the mass matrix + this->getMass(); + + // Take advantage of lumped mass matrix + for (i = 0; i < 2*nnodes; i++) + P(i) += K(i,i)*a[i]; + + // add the damping forces if rayleigh damping + if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P += this->getRayleighDampingForces(); + + return P; +} + +int +NineNodeQuad::sendSelf(int commitTag, Channel &theChannel) +{ + int res = 0; + + // note: we don't check for dataTag == 0 for Element + // objects as that is taken care of in a commit by the Domain + // object - don't want to have to do the check if sending data + int dataTag = this->getDbTag(); + + // Quad packs its data into a Vector and sends this to theChannel + // along with its dbTag and the commitTag passed in the arguments + static Vector data(9); + data(0) = this->getTag(); + data(1) = thickness; + data(2) = b[0]; + data(3) = b[1]; + data(4) = pressure; + + data(5) = alphaM; + data(6) = betaK; + data(7) = betaK0; + data(8) = betaKc; + + res += theChannel.sendVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING NineNodeQuad::sendSelf() - " << this->getTag() << " failed to send Vector\n"; + return res; + } + + + // Now quad sends the ids of its materials + int matDbTag; + + static ID idData(2*nip+nnodes); + + int i; + for (i = 0; i < nip; i++) { + idData(i) = theMaterial[i]->getClassTag(); + matDbTag = theMaterial[i]->getDbTag(); + // NOTE: we do have to ensure that the material has a database + // tag if we are sending to a database channel. + if (matDbTag == 0) { + matDbTag = theChannel.getDbTag(); + if (matDbTag != 0) + theMaterial[i]->setDbTag(matDbTag); + } + idData(i+nip) = matDbTag; + } + + for( i = 0; i < nnodes; i++) + idData(2*nip+i) = connectedExternalNodes(i); + + res += theChannel.sendID(dataTag, commitTag, idData); + if (res < 0) { + opserr << "WARNING NineNodeQuad::sendSelf() - " << this->getTag() << " failed to send ID\n"; + return res; + } + + // Finally, quad asks its material objects to send themselves + for (i = 0; i < nip; i++) { + res += theMaterial[i]->sendSelf(commitTag, theChannel); + if (res < 0) { + opserr << "WARNING NineNodeQuad::sendSelf() - " << this->getTag() << " failed to send its Material\n"; + return res; + } + } + + return res; +} + +int +NineNodeQuad::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + + int dataTag = this->getDbTag(); + + // Quad creates a Vector, receives the Vector and then sets the + // internal data with the data in the Vector + static Vector data(9); + res += theChannel.recvVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING NineNodeQuad::recvSelf() - failed to receive Vector\n"; + return res; + } + + this->setTag((int)data(0)); + thickness = data(1); + b[0] = data(2); + b[1] = data(3); + pressure = data(4); + + alphaM = data(5); + betaK = data(6); + betaK0 = data(7); + betaKc = data(8); + + static ID idData(2*nip+nnodes); + // Quad now receives the tags of its nine external nodes + res += theChannel.recvID(dataTag, commitTag, idData); + if (res < 0) { + opserr << "WARNING NineNodeQuad::recvSelf() - " << this->getTag() << " failed to receive ID\n"; + return res; + } + + for( int i = 0; i < nnodes; i++) + connectedExternalNodes(i) = idData(2*nip+i); + + if (theMaterial == 0) { + // Allocate new materials + theMaterial = new NDMaterial *[nip]; + if (theMaterial == 0) { + opserr << "NineNodeQuad::recvSelf() - Could not allocate NDMaterial* array\n"; + return -1; + } + for (int i = 0; i < nip; i++) { + int matClassTag = idData(i); + int matDbTag = idData(i+nip); + // Allocate new material with the sent class tag + theMaterial[i] = theBroker.getNewNDMaterial(matClassTag); + if (theMaterial[i] == 0) { + opserr << "NineNodeQuad::recvSelf() - Broker could not create NDMaterial of class type " << matClassTag << endln; + return -1; + } + // Now receive materials into the newly allocated space + theMaterial[i]->setDbTag(matDbTag); + res += theMaterial[i]->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "NineNodeQuad::recvSelf() - material " << i << "failed to recv itself\n"; + return res; + } + } + } + + // materials exist , ensure materials of correct type and recvSelf on them + else { + for (int i = 0; i < nip; i++) { + int matClassTag = idData(i); + int matDbTag = idData(i+nip); + // Check that material is of the right type; if not, + // delete it and create a new one of the right type + if (theMaterial[i]->getClassTag() != matClassTag) { + delete theMaterial[i]; + theMaterial[i] = theBroker.getNewNDMaterial(matClassTag); + if (theMaterial[i] == 0) { + opserr << "NineNodeQuad::recvSelf() - material " << i << "failed to create\n"; + return -1; + } + } + // Receive the material + theMaterial[i]->setDbTag(matDbTag); + res += theMaterial[i]->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "NineNodeQuad::recvSelf() - material " << i << "failed to recv itself\n"; + return res; + } + } + } + + return res; +} + +void +NineNodeQuad::Print(OPS_Stream &s, int flag) +{ + if (flag == 2) { + + s << "#NineNodeQuad\n"; + + int i; + const int numNodes = nnodes; + const int nstress = nip ; + + for (i=0; igetCrds(); + // const Vector &nodeDisp = theNodes[i]->getDisp(); + s << "#NODE " << nodeCrd(0) << " " << nodeCrd(1) << " " << endln; + } + + // spit out the section location & invoke print on the scetion + const int numMaterials = nip; + + static Vector avgStress(nstress); + static Vector avgStrain(nstress); + avgStress.Zero(); + avgStrain.Zero(); + for (i=0; igetStress(); + avgStrain += theMaterial[i]->getStrain(); + } + avgStress /= numMaterials; + avgStrain /= numMaterials; + + s << "#AVERAGE_STRESS "; + for (i=0; igetTag() << endln; + s << "\tConnected external nodes: " << connectedExternalNodes; + s << "\tthickness: " << thickness << endln; + s << "\tsurface pressure: " << pressure << endln; + s << "\tmass density: " << rho << endln; + s << "\tbody forces: " << b[0] << " " << b[1] << endln; + theMaterial[0]->Print(s,flag); + s << "\tStress (xx yy xy)" << endln; + for (int i = 0; i < nip; i++) + s << "\t\tGauss point " << i+1 << ": " << theMaterial[i]->getStress(); + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << "\t\t\t{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"NineNodeQuad\", "; + s << "\"nodes\": [" << connectedExternalNodes(0) << ", "; + s << connectedExternalNodes(1) << ", "; + s << connectedExternalNodes(2) << ", "; + s << connectedExternalNodes(3) << ", "; + s << connectedExternalNodes(4) << ", "; + s << connectedExternalNodes(5) << ", "; + s << connectedExternalNodes(6) << ", "; + s << connectedExternalNodes(7) << ", "; + s << connectedExternalNodes(8) << "], "; + s << "\"thickness\": " << thickness << ", "; + s << "\"surfacePressure\": " << pressure << ", "; + s << "\"masspervolume\": " << rho << ", "; + s << "\"bodyForces\": [" << b[0] << ", " << b[1] << "], "; + s << "\"material\": \"" << theMaterial[0]->getTag() << "\"}"; + } +} + +int +NineNodeQuad::displaySelf(Renderer &theViewer, int displayMode, float fact, const char **modes, int numMode) +{ + + // first set the quantity to be displayed at the nodes; + // if displayMode is 1 through 3 we will plot material stresses otherwise 0.0 + + static Vector values(nip); + + for (int j=0; j 0) { + for (int i=0; igetStress(); + values(i) = stress(displayMode-1); + } + } + + // now determine the end points of the quad based on + // the display factor (a measure of the distorted image) + // store this information in 4 3d vectors v1 through v4 + const Vector &end1Crd = theNodes[0]->getCrds(); + const Vector &end2Crd = theNodes[1]->getCrds(); + const Vector &end3Crd = theNodes[2]->getCrds(); + const Vector &end4Crd = theNodes[3]->getCrds(); + const Vector &end5Crd = theNodes[4]->getCrds(); + const Vector &end6Crd = theNodes[5]->getCrds(); + const Vector &end7Crd = theNodes[6]->getCrds(); + const Vector &end8Crd = theNodes[7]->getCrds(); + const Vector &end9Crd = theNodes[8]->getCrds(); + + static Matrix coords(nnodes,3); + + if (displayMode >= 0) { + + const Vector &end1Disp = theNodes[0]->getDisp(); + const Vector &end2Disp = theNodes[1]->getDisp(); + const Vector &end3Disp = theNodes[2]->getDisp(); + const Vector &end4Disp = theNodes[3]->getDisp(); + const Vector &end5Disp = theNodes[4]->getDisp(); + const Vector &end6Disp = theNodes[5]->getDisp(); + const Vector &end7Disp = theNodes[6]->getDisp(); + const Vector &end8Disp = theNodes[7]->getDisp(); + const Vector &end9Disp = theNodes[8]->getDisp(); + + for (int i = 0; i < 2; i++) { + coords(0,i) = end1Crd(i) + end1Disp(i)*fact; + coords(1,i) = end2Crd(i) + end2Disp(i)*fact; + coords(2,i) = end3Crd(i) + end3Disp(i)*fact; + coords(3,i) = end4Crd(i) + end4Disp(i)*fact; + coords(4,i) = end5Crd(i) + end5Disp(i)*fact; + coords(5,i) = end6Crd(i) + end6Disp(i)*fact; + coords(6,i) = end7Crd(i) + end7Disp(i)*fact; + coords(7,i) = end8Crd(i) + end8Disp(i)*fact; + coords(8,i) = end9Crd(i) + end9Disp(i)*fact; + } + } else { + int mode = displayMode * -1; + const Matrix &eigen1 = theNodes[0]->getEigenvectors(); + const Matrix &eigen2 = theNodes[1]->getEigenvectors(); + const Matrix &eigen3 = theNodes[2]->getEigenvectors(); + const Matrix &eigen4 = theNodes[3]->getEigenvectors(); + const Matrix &eigen5 = theNodes[4]->getEigenvectors(); + const Matrix &eigen6 = theNodes[5]->getEigenvectors(); + const Matrix &eigen7 = theNodes[6]->getEigenvectors(); + const Matrix &eigen8 = theNodes[7]->getEigenvectors(); + const Matrix &eigen9 = theNodes[8]->getEigenvectors(); + if (eigen1.noCols() >= mode) { + for (int i = 0; i < 2; i++) { + coords(0,i) = end1Crd(i) + eigen1(i,mode-1)*fact; + coords(1,i) = end2Crd(i) + eigen2(i,mode-1)*fact; + coords(2,i) = end3Crd(i) + eigen3(i,mode-1)*fact; + coords(3,i) = end4Crd(i) + eigen4(i,mode-1)*fact; + coords(4,i) = end5Crd(i) + eigen5(i,mode-1)*fact; + coords(5,i) = end6Crd(i) + eigen6(i,mode-1)*fact; + coords(6,i) = end7Crd(i) + eigen7(i,mode-1)*fact; + coords(7,i) = end8Crd(i) + eigen8(i,mode-1)*fact; + coords(8,i) = end9Crd(i) + eigen9(i,mode-1)*fact; + } + } else { + for (int i = 0; i < 2; i++) { + coords(0,i) = end1Crd(i); + coords(1,i) = end2Crd(i); + coords(2,i) = end3Crd(i); + coords(3,i) = end4Crd(i); + coords(4,i) = end5Crd(i); + coords(5,i) = end6Crd(i); + coords(6,i) = end7Crd(i); + coords(7,i) = end8Crd(i); + coords(8,i) = end9Crd(i); + } + } + } + + int error = 0; + + // finally we the element using drawPolygon + error += theViewer.drawPolygon (coords, values, this->getTag()); + + return error; +} + +Response* +NineNodeQuad::setResponse(const char **argv, int argc, + OPS_Stream &output) +{ + Response *theResponse =0; + + output.tag("ElementOutput"); + output.attr("eleType","NineNodeQuad"); + output.attr("eleTag",this->getTag()); + output.attr("node1",connectedExternalNodes[0]); + output.attr("node2",connectedExternalNodes[1]); + output.attr("node3",connectedExternalNodes[2]); + output.attr("node4",connectedExternalNodes[3]); + output.attr("node5",connectedExternalNodes[4]); + output.attr("node6",connectedExternalNodes[5]); + output.attr("node7",connectedExternalNodes[6]); + output.attr("node8",connectedExternalNodes[7]); + output.attr("node9",connectedExternalNodes[8]); + + char dataOut[10]; + if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) { + + for (int i=1; i<=nip; i++) { + sprintf(dataOut,"P1_%d",i); + output.tag("ResponseType",dataOut); + sprintf(dataOut,"P2_%d",i); + output.tag("ResponseType",dataOut); + } + + theResponse = new ElementResponse(this, 1, P); + } + + else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"integrPoint") == 0) { + + int pointNum = atoi(argv[1]); + if (pointNum > 0 && pointNum <= nip) { + + output.tag("GaussPoint"); + output.attr("number",pointNum); + output.attr("eta",pts[pointNum-1][0]); + output.attr("neta",pts[pointNum-1][1]); + + theResponse = theMaterial[pointNum-1]->setResponse(&argv[2], argc-2, output); + + output.endTag(); + + } + } + else if ((strcmp(argv[0],"stresses") ==0) || (strcmp(argv[0],"stress") ==0)) { + for (int i=0; igetClassTag()); + output.attr("tag", theMaterial[i]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma12"); + + output.endTag(); // GaussPoint + output.endTag(); // NdMaterialOutput + } + theResponse = new ElementResponse(this, 3, Vector(3*nip)); + } + + else if ((strcmp(argv[0],"stressesAtNodes") ==0) || (strcmp(argv[0],"stressAtNodes") ==0)) { + for (int i=0; igetClassTag()); + // output.attr("tag", theMaterial[i]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma12"); + + output.endTag(); // GaussPoint + // output.endTag(); // NdMaterialOutput + } + theResponse = new ElementResponse(this, 11, Vector(3*nnodes)); + } + + else if ((strcmp(argv[0],"strain") ==0) || (strcmp(argv[0],"strains") ==0)) { + for (int i=0; igetClassTag()); + output.attr("tag", theMaterial[i]->getTag()); + + output.tag("ResponseType","eta11"); + output.tag("ResponseType","eta22"); + output.tag("ResponseType","eta12"); + + output.endTag(); // GaussPoint + output.endTag(); // NdMaterialOutput + } + theResponse = new ElementResponse(this, 4, Vector(3*nip)); + } + + output.endTag(); // ElementOutput + + return theResponse; +} + +int +NineNodeQuad::getResponse(int responseID, Information &eleInfo) +{ + if (responseID == 1) { + + return eleInfo.setVector(this->getResistingForce()); + + } else if (responseID == 3) { + + // Loop over the integration points + static Vector stresses(3*nip); + int cnt = 0; + for (int i = 0; i < nip; i++) { + + // Get material stress response + const Vector &sigma = theMaterial[i]->getStress(); + stresses(cnt) = sigma(0); + stresses(cnt+1) = sigma(1); + stresses(cnt+2) = sigma(2); + cnt += 3; + } + + return eleInfo.setVector(stresses); + + } else if (responseID == 11) { + + // extrapolate stress from Gauss points to element nodes + static Vector stressGP(3*nip); + static Vector stressAtNodes(3*nnodes); + stressAtNodes.Zero(); + int cnt = 0; + // first get stress components (xx, yy, xy) at Gauss points + for (int i = 0; i < nip; i++) { + // Get material stress response + const Vector &sigma = theMaterial[i]->getStress(); + stressGP(cnt) = sigma(0); + stressGP(cnt+1) = sigma(1); + stressGP(cnt+2) = sigma(2); + cnt += 3; + } + + const double We[nnodes][nip] = {{2.1869398183909485, 0.2777777777777778, 0.0352824038312731, 0.2777777777777778, -0.9858870384674904, -0.1252240726436203, -0.1252240726436203, -0.9858870384674904, 0.4444444444444444}, + {0.2777777777777778, 2.1869398183909485, 0.2777777777777778, 0.0352824038312731, -0.9858870384674904, -0.9858870384674904, -0.1252240726436203, -0.1252240726436203, 0.4444444444444444}, + {0.0352824038312731, 0.2777777777777778, 2.1869398183909485, 0.2777777777777778, -0.1252240726436203, -0.9858870384674904, -0.9858870384674904, -0.1252240726436203, 0.4444444444444444}, + {0.2777777777777778, 0.0352824038312731, 0.2777777777777778, 2.1869398183909485, -0.1252240726436203, -0.1252240726436203, -0.9858870384674904, -0.9858870384674904, 0.4444444444444444}, + {0.0, 0.0, 0.0, 0.0, 1.478830557701236, 0.0, 0.1878361089654305, 0.0, -0.6666666666666667}, + {0.0, 0.0, 0.0, 0.0, 0.0, 1.478830557701236, 0.0, 0.1878361089654305, -0.6666666666666667}, + {0.0, 0.0, 0.0, 0.0, 0.1878361089654305, 0.0, 1.478830557701236, 0.0, -0.6666666666666667}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.1878361089654305, 0.0, 1.478830557701236, -0.6666666666666667}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}}; + + int p, l; + for (int i = 0; i < nnodes; i++) { + for (int k = 0; k < 3; k++) { + p = 3*i + k; + for (int j = 0; j < nip; j++) { + l = 3*j + k; + stressAtNodes(p) += We[i][j] * stressGP(l); + // opserr << "stressAtNodes(" << p << ") = We[" << i << "][" << j << "] * stressGP(" << l << ") = " << We[i][j] << " * " << stressGP(l) << " = " << stressAtNodes(p) << "\n"; + } + } + } + + return eleInfo.setVector(stressAtNodes); + + } else if (responseID == 4) { + + // Loop over the integration points + static Vector stresses(3*nip); + int cnt = 0; + for (int i = 0; i < nip; i++) { + + // Get material stress response + const Vector &sigma = theMaterial[i]->getStrain(); + stresses(cnt) = sigma(0); + stresses(cnt+1) = sigma(1); + stresses(cnt+2) = sigma(2); + cnt += 3; + } + + return eleInfo.setVector(stresses); + + } else + + return -1; +} + +int +NineNodeQuad::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc < 1) + return -1; + + int res = -1; + + // quad pressure loading + if (strcmp(argv[0],"pressure") == 0) { + return param.addObject(2, this); + } + // a material parameter + else if ((strstr(argv[0],"material") != 0) && (strcmp(argv[0],"materialState") != 0)) { + + if (argc < 3) + return -1; + + int pointNum = atoi(argv[1]); + if (pointNum > 0 && pointNum <= nip) + return theMaterial[pointNum-1]->setParameter(&argv[2], argc-2, param); + else + return -1; + } + + // otherwise it could be just a forall material parameter + else { + + int matRes = res; + for (int i=0; isetParameter(argv, argc, param); + + if (matRes != -1) + res = matRes; + } + } + + return res; +} + +int +NineNodeQuad::updateParameter(int parameterID, Information &info) +{ + int res = -1; + int matRes = res; + switch (parameterID) { + case -1: + return -1; + + case 1: + + for (int i = 0; iupdateParameter(parameterID, info); + } + if (matRes != -1) { + res = matRes; + } + return res; + + case 2: + pressure = info.theDouble; + this->setPressureLoadAtNodes(); // update consistent nodal loads + return 0; + + default: + /* + if (parameterID >= 100) { // material parameter + int pointNum = parameterID/100; + if (pointNum > 0 && pointNum <= 4) + return theMaterial[pointNum-1]->updateParameter(parameterID-100*pointNum, info); + else + return -1; + } else // unknown + */ + return -1; + } +} + +double NineNodeQuad::shapeFunction(double s, double t) +{ + const Vector &nd1Crds = theNodes[0]->getCrds(); + const Vector &nd2Crds = theNodes[1]->getCrds(); + const Vector &nd3Crds = theNodes[2]->getCrds(); + const Vector &nd4Crds = theNodes[3]->getCrds(); + const Vector &nd5Crds = theNodes[4]->getCrds(); + const Vector &nd6Crds = theNodes[5]->getCrds(); + const Vector &nd7Crds = theNodes[6]->getCrds(); + const Vector &nd8Crds = theNodes[7]->getCrds(); + const Vector &nd9Crds = theNodes[8]->getCrds(); + + double N1 = (1-s)*(1-t)*s*t/4; + double N2 = -(1+s)*(1-t)*s*t/4; + double N3 = (1+s)*(1+t)*s*t/4; + double N4 = -(1-s)*(1+t)*s*t/4; + + double N5 = -(1-s*s)*(1-t)*t/2; + double N6 = (1+s)*(1-t*t)*s/2; + double N7 = (1-s*s)*(1+t)*t/2; + double N8 = -(1-s)*(1-t*t)*s/2; + + double N9 = (1-s*s)*(1-t*t); + + // alternative + // double N9 = (1-s*s)*(1-t*t); + // double N1 = -(1-s)*(1-t)*(1+s+t)/4 + N9/4; + // double N2 = -(1+s)*(1-t)*(1-s+t)/4 + N9/4; + // double N3 = -(1+s)*(1+t)*(1-s-t)/4 + N9/4; + // double N4 = -(1-s)*(1+t)*(1+s-t)/4 + N9/4; + + // double N5 = (1-s*s)*(1-t)/2 - N9/2; + // double N6 = (1+s)*(1-t*t)/2 - N9/2; + // double N7 = (1-s*s)*(1+t)/2 - N9/2; + // double N8 = (1-s)*(1-t*t)/2 - N9/2; + + shp[2][0] = N1; + shp[2][1] = N2; + shp[2][2] = N3; + shp[2][3] = N4; + shp[2][4] = N5; + shp[2][5] = N6; + shp[2][6] = N7; + shp[2][7] = N8; + shp[2][8] = N9; + + // derivatives + double N91 = -2*s*(1-t*t); + double N92 = -2*t*(1-s*s); + + double N11 = t*(1-t)*(1-2*s)/4; + double N12 = s*(1-s)*(1-2*t)/4; + double N21 = -t*(1-t)*(1+2*s)/4; + double N22 = -s*(1+s)*(1-2*t)/4; + double N31 = t*(1+t)*(1+2*s)/4; + double N32 = s*(1+s)*(1+2*t)/4; + double N41 = -t*(1+t)*(1-2*s)/4; + double N42 = -s*(1-s)*(1+2*t)/4; + double N51 = s*t*(1-t); + double N52 = -(1-s*s)*(1-2*t)/2; + double N61 = (1-t*t)*(1+2*s)/2; + double N62 = -s*t*(1+s); + double N71 = -s*t*(1+t); + double N72 = (1-s*s)*(1+2*t)/2; + double N81 = -(1-t*t)*(1-2*s)/2; + double N82 = s*t*(1-s); + + // alternative + // double N11 = -1*(-(1-t)*(1+s+t)+(1-s)*(1-t))/4 - s*(1-t*t)/2; + // double N21 = -1*((1-t)*(1-s+t)-(1+s)*(1-t))/4 - s*(1-t*t)/2; + // double N31 = -1*((1+t)*(1-s-t)-(1+s)*(1+t))/4 - s*(1-t*t)/2; + // double N41 = -1*(-(1+t)*(1+s-t)+(1-s)*(1+t))/4 - s*(1-t*t)/2; + // double N51 = -s*(1-t) + s*(1-t*t); + // double N61 = (1-t*t)/2 + s*(1-t*t); + // double N71 = -s*(1+t) + s*(1-t*t); + // double N81 = -1*(1-t*t)/2 + s*(1-t*t); + // double N91 = -2*s*(1-t*t); + + // double N12 = -1*(-(1-s)*(1+s+t)+(1-s)*(1-t))/4 - t*(1-s*s)/2; + // double N22 = -1*(-(1+s)*(1-s+t)+(1+s)*(1-t))/4 - t*(1-s*s)/2; + // double N32 = -1*((1+s)*(1-s-t)-(1+s)*(1+t))/4 - t*(1-s*s)/2; + // double N42 = -1*((1-s)*(1+s-t)-(1-s)*(1+t))/4 - t*(1-s*s)/2; + // double N52 = -1*(1-s*s)/2 + t*(1-s*s); + // double N62 = -t*(1+s) + t*(1-s*s); + // double N72 = (1-s*s)/2 + t*(1-s*s); + // double N82 = -t*(1-s) + t*(1-s*s); + // double N92 = -2*t*(1-s*s); + + // remains the same 2x2 matrix Cook Malkus Plesha 6.6, p. 180 + double J[2][2]; + + J[0][0] = nd1Crds(0)*N11 + nd2Crds(0)*N21 + nd3Crds(0)*N31 + nd4Crds(0)*N41 + + nd5Crds(0)*N51 + nd6Crds(0)*N61 + nd7Crds(0)*N71 + nd8Crds(0)*N81 + nd9Crds(0)*N91; + + J[0][1] = nd1Crds(0)*N12 + nd2Crds(0)*N22 + nd3Crds(0)*N32 + nd4Crds(0)*N42 + + nd5Crds(0)*N52 + nd6Crds(0)*N62 + nd7Crds(0)*N72 + nd8Crds(0)*N82 + nd9Crds(0)*N92; + + J[1][0] = nd1Crds(1)*N11 + nd2Crds(1)*N21 + nd3Crds(1)*N31 + nd4Crds(1)*N41 + + nd5Crds(1)*N51 + nd6Crds(1)*N61 + nd7Crds(1)*N71 + nd8Crds(1)*N81 + nd9Crds(1)*N91; + + J[1][1] = nd1Crds(1)*N12 + nd2Crds(1)*N22 + nd3Crds(1)*N32 + nd4Crds(1)*N42 + + nd5Crds(1)*N52 + nd6Crds(1)*N62 + nd7Crds(1)*N72 + nd8Crds(1)*N82 + nd9Crds(1)*N92; + + double detJ = J[0][0]*J[1][1] - J[0][1]*J[1][0]; + + double oneOverdetJ = 1/detJ; + double L[2][2]; + + // L = inv(J) + L[0][0] = J[1][1]*oneOverdetJ; + L[1][0] = -J[0][1]*oneOverdetJ; + L[0][1] = -J[1][0]*oneOverdetJ; + L[1][1] = J[0][0]*oneOverdetJ; + + double L00 = L[0][0]; + double L10 = L[1][0]; + double L01 = L[0][1]; + double L11 = L[1][1]; + + shp[0][0] = L00*N11 + L01*N12; + shp[0][1] = L00*N21 + L01*N22; + shp[0][2] = L00*N31 + L01*N32; + shp[0][3] = L00*N41 + L01*N42; + shp[0][4] = L00*N51 + L01*N52; + shp[0][5] = L00*N61 + L01*N62; + shp[0][6] = L00*N71 + L01*N72; + shp[0][7] = L00*N81 + L01*N82; + shp[0][8] = L00*N91 + L01*N92; + + shp[1][0] = L10*N11 + L11*N12; + shp[1][1] = L10*N21 + L11*N22; + shp[1][2] = L10*N31 + L11*N32; + shp[1][3] = L10*N41 + L11*N42; + shp[1][4] = L10*N51 + L11*N52; + shp[1][5] = L10*N61 + L11*N62; + shp[1][6] = L10*N71 + L11*N72; + shp[1][7] = L10*N81 + L11*N82; + shp[1][8] = L10*N91 + L11*N92; + + return detJ; +} + +void +NineNodeQuad::setPressureLoadAtNodes(void) +{ + pressureLoad.Zero(); + + if (pressure == 0.0) + return; + + const Vector &node1 = theNodes[0]->getCrds(); + const Vector &node2 = theNodes[1]->getCrds(); + const Vector &node3 = theNodes[2]->getCrds(); + const Vector &node4 = theNodes[3]->getCrds(); + const Vector &node5 = theNodes[4]->getCrds(); + const Vector &node6 = theNodes[5]->getCrds(); + const Vector &node7 = theNodes[6]->getCrds(); + const Vector &node8 = theNodes[7]->getCrds(); + // center node has no pressure commponents + // const Vector &node9 = theNodes[8]->getCrds(); + + double x1 = node1(0); + double y1 = node1(1); + double x2 = node2(0); + double y2 = node2(1); + double x3 = node3(0); + double y3 = node3(1); + double x4 = node4(0); + double y4 = node4(1); + double x5 = node5(0); + double y5 = node5(1); + double x6 = node6(0); + double y6 = node6(1); + double x7 = node7(0); + double y7 = node7(1); + double x8 = node8(0); + double y8 = node8(1); + // double x9 = node9(0); + // double y9 = node9(1); + + double dx15 = x5-x1; + double dy15 = y5-y1; + double dx52 = x2-x5; + double dy52 = y2-y5; + double dx26 = x6-x2; + double dy26 = y6-y2; + double dx63 = x3-x6; + double dy63 = y3-y6; + double dx37 = x7-x3; + double dy37 = y7-y3; + double dx74 = x4-x7; + double dy74 = y4-y7; + double dx48 = x8-x4; + double dy48 = y8-y4; + double dx81 = x1-x8; + double dy81 = y1-y8; + + double fac1 = 0.3333333333333333; + double fac2 = 0.6666666666666667; + + // Contribution from side 15 + pressureLoad(0) += pressure*fac1*dy15; + pressureLoad(8) += pressure*fac2*dy15; + pressureLoad(1) += pressure*fac1*-dx15; + pressureLoad(9) += pressure*fac2*-dx15; + + // Contribution from side 52 + pressureLoad(8) += pressure*fac2*dy52; + pressureLoad(2) += pressure*fac1*dy52; + pressureLoad(9) += pressure*fac2*-dx52; + pressureLoad(3) += pressure*fac1*-dx52; + + // Contribution from side 26 + pressureLoad(2) += pressure*fac1*dy26; + pressureLoad(10) += pressure*fac2*dy26; + pressureLoad(3) += pressure*fac1*-dx26; + pressureLoad(11) += pressure*fac2*-dx26; + + // Contribution from side 63 + pressureLoad(10) += pressure*fac2*dy63; + pressureLoad(4) += pressure*fac1*dy63; + pressureLoad(11) += pressure*fac2*-dx63; + pressureLoad(5) += pressure*fac1*-dx63; + + // Contribution from side 37 + pressureLoad(4) += pressure*fac1*dy37; + pressureLoad(12) += pressure*fac2*dy37; + pressureLoad(5) += pressure*fac1*-dx37; + pressureLoad(13) += pressure*fac2*-dx37; + + // Contribution from side 74 + pressureLoad(12) += pressure*fac2*dy74; + pressureLoad(6) += pressure*fac1*dy74; + pressureLoad(13) += pressure*fac2*-dx74; + pressureLoad(7) += pressure*fac1*-dx74; + + // Contribution from side 48 + pressureLoad(6) += pressure*fac1*dy48; + pressureLoad(14) += pressure*fac2*dy48; + pressureLoad(7) += pressure*fac1*-dx48; + pressureLoad(15) += pressure*fac2*-dx48; + + // Contribution from side 81 + pressureLoad(14) += pressure*fac2*dy81; + pressureLoad(0) += pressure*fac1*dy81; + pressureLoad(15) += pressure*fac2*-dx81; + pressureLoad(1) += pressure*fac1*-dx81; + + //pressureLoad = pressureLoad*thickness; +} diff --git a/SRC/element/fourNodeQuad/NineNodeQuad.h b/SRC/element/fourNodeQuad/NineNodeQuad.h new file mode 100644 index 0000000000..3beac28e3c --- /dev/null +++ b/SRC/element/fourNodeQuad/NineNodeQuad.h @@ -0,0 +1,139 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// based on FourNodeQuad by MHS +// Written: Seweryn Kokot, Opole University of Technology, Poland +// Created: Aug 2020 +// +// Description: This file contains the class definition for NineNodeQuad. + +#ifndef NineNodeQuad_h +#define NineNodeQuad_h + +#ifndef _bool_h +#include "bool.h" +#endif + +#include +#include +#include +#include + +class Node; +class NDMaterial; +class Response; + +class NineNodeQuad : public Element { +public: + NineNodeQuad(int tag, int nd1, int nd2, int nd3, int nd4, int nd5, int nd6, + int nd7, int nd8, int nd9, NDMaterial &m, const char *type, double t, + double pressure = 0.0, double rho = 0.0, double b1 = 0.0, + double b2 = 0.0); + NineNodeQuad(); + ~NineNodeQuad(); + + const char *getClassType(void) const { return "NineNodeQuad"; }; + + int getNumExternalNodes(void) const; + const ID &getExternalNodes(void); + Node **getNodePtrs(void); + + int getNumDOF(void); + void setDomain(Domain *theDomain); + + // public methods to set the state of the element + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + int update(void); + + // public methods to obtain stiffness, mass, damping and residual information + const Matrix &getTangentStiff(void); + const Matrix &getInitialStiff(void); + const Matrix &getMass(void); + + void zeroLoad(); + int addLoad(ElementalLoad *theLoad, double loadFactor); + int addInertiaLoadToUnbalance(const Vector &accel); + + const Vector &getResistingForce(void); + const Vector &getResistingForceIncInertia(void); + + // public methods for element output + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + + int displaySelf(Renderer &, int mode, float fact, + const char **displayModes = 0, int numModes = 0); + void Print(OPS_Stream &s, int flag = 0); + + Response *setResponse(const char **argv, int argc, OPS_Stream &s); + + int getResponse(int responseID, Information &eleInformation); + + int setParameter(const char **argv, int argc, Parameter ¶m); + int updateParameter(int parameterID, Information &info); + + // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial + // stresses. + friend class PyLiq1; + friend class TzLiq1; + +protected: +private: + // private attributes - a copy for each object of the class + + static constexpr int nip = 9; // number of integration/Gauss points + static constexpr int nnodes = 9; // number of nodes + + NDMaterial **theMaterial; // pointer to the ND material objects + + ID connectedExternalNodes; // Tags of quad nodes + + Node *theNodes[nnodes]; + + static double matrixData[(nnodes*2)*(nnodes*2)]; // array data for matrix + static Matrix K; // Element stiffness, damping, and mass Matrix + static Vector P; // Element resisting force vector + Vector Q; // Applied nodal loads + double b[2]; // Body forces + + double appliedB[2]; // Body forces applied with load pattern, C.McGann, + // U.Washington + int applyLoad; // flag for body force in load, C.McGann, U.Washington + + Vector pressureLoad; // Pressure load at nodes + + double thickness; // Element thickness + double pressure; // Normal surface traction (pressure) over entire element + // Note: positive for outward normal + double rho; + static double shp[3][nnodes]; // Stores shape functions and derivatives (overwritten) + static double pts[nip][2]; // Stores quadrature points + static double wts[nip]; // Stores quadrature weights + + // private member functions - only objects of this class can call these + double shapeFunction(double xi, double eta); + void setPressureLoadAtNodes(void); + + Matrix *Ki; +}; + +#endif diff --git a/SRC/element/fourNodeQuad/SixNodeTri.cpp b/SRC/element/fourNodeQuad/SixNodeTri.cpp new file mode 100644 index 0000000000..5f265e802b --- /dev/null +++ b/SRC/element/fourNodeQuad/SixNodeTri.cpp @@ -0,0 +1,1510 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// based on FourNodeQuad by MHS +// Written: Seweryn Kokot, Opole University of Technology, Poland +// Created: Sep 2020 +// +// Description: This file contains the class definition for SixNodeTri. + +#include "SixNodeTri.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void* OPS_SixNodeTri() +{ + int ndm = OPS_GetNDM(); + int ndf = OPS_GetNDF(); + + if (ndm != 2 || ndf != 2) { + opserr << "WARNING -- model dimensions and/or nodal DOF not compatible with quad element\n"; + return 0; + } + + if (OPS_GetNumRemainingInputArgs() < 10) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: element SixNodeTri eleTag? iNode? jNode? kNode? lNode? nNode5 mNode6 thk? type? matTag? \n"; + return 0; + } + + // SixNodeTriId, iNode, jNode, kNode, lNode + // nNode, mNode + int idata[7]; + int num = 7; + if (OPS_GetIntInput(&num,idata) < 0) { + opserr<<"WARNING: invalid integer inputs\n"; + return 0; + } + + double thk = 1.0; + num = 1; + if (OPS_GetDoubleInput(&num,&thk) < 0) { + opserr<<"WARNING: invalid double inputs\n"; + return 0; + } + + const char* type = OPS_GetString(); + + int matTag; + num = 1; + if (OPS_GetIntInput(&num,&matTag) < 0) { + opserr<<"WARNING: invalid matTag\n"; + return 0; + } + + NDMaterial* mat = OPS_getNDMaterial(matTag); + if (mat == 0) { + opserr << "WARNING material not found\n"; + opserr << "Material: " << matTag; + opserr << "\nSixNodeTri element: " << idata[0] << endln; + return 0; + } + + // p, rho, b1, b2 + double data[4] = {0,0,0,0}; + num = OPS_GetNumRemainingInputArgs(); + if (num > 4) { + num = 4; + } + if (num > 0) { + if (OPS_GetDoubleInput(&num,data) < 0) { + opserr<<"WARNING: invalid integer data\n"; + return 0; + } + } + + return new SixNodeTri(idata[0],idata[1],idata[2],idata[3],idata[4], + idata[5],idata[6], + *mat,type,thk,data[0],data[1],data[2],data[3]); +} + + +double SixNodeTri::matrixData[(nnodes*2)*(nnodes*2)]; +Matrix SixNodeTri::K(matrixData, 2*nnodes, 2*nnodes); +Vector SixNodeTri::P(2*nnodes); +double SixNodeTri::shp[3][nnodes]; +double SixNodeTri::pts[nip][2]; +double SixNodeTri::wts[nip]; + +SixNodeTri::SixNodeTri(int tag, int nd1, int nd2, int nd3, int nd4, + int nd5, int nd6, + NDMaterial &m, const char *type, double t, + double p, double r, double b1, double b2) +:Element (tag, ELE_TAG_SixNodeTri), + theMaterial(0), connectedExternalNodes(nnodes), + Q(2*nnodes), applyLoad(0), pressureLoad(2*nnodes), thickness(t), pressure(p), rho(r), Ki(0) +{ + pts[0][0] = 0.666666666666666667; + pts[0][1] = 0.166666666666666667; + pts[1][0] = 0.166666666666666667; + pts[1][1] = 0.666666666666666667; + pts[2][0] = 0.166666666666666667; + pts[2][1] = 0.166666666666666667; + // pts[0][0] = 0.5; + // pts[0][1] = 0.5; + // pts[1][0] = 0.0; + // pts[1][1] = 0.5; + // pts[2][0] = 0.5; + // pts[2][1] = 0.0; + + wts[0] = 0.166666666666666667; + wts[1] = 0.166666666666666667; + wts[2] = 0.166666666666666667; + + if (strcmp(type,"PlaneStrain") != 0 && strcmp(type,"PlaneStress") != 0 + && strcmp(type,"PlaneStrain2D") != 0 && strcmp(type,"PlaneStress2D") != 0) { + opserr << "SixNodeTri::SixNodeTri -- improper material type: " << type << "for SixNodeTri\n"; + exit(-1); + } + + // Body forces + b[0] = b1; + b[1] = b2; + + // Allocate arrays of pointers to NDMaterials + theMaterial = new NDMaterial *[nip]; + + if (theMaterial == 0) { + opserr << "SixNodeTri::SixNodeTri - failed allocate material model pointer\n"; + exit(-1); + } + + int i; + for (i = 0; i < nip; i++) { + + // Get copies of the material model for each integration point + theMaterial[i] = m.getCopy(type); + + // Check allocation + if (theMaterial[i] == 0) { + opserr << "SixNodeTri::SixNodeTri -- failed to get a copy of material model\n"; + exit(-1); + } + } + + // Set connected external node IDs + connectedExternalNodes(0) = nd1; + connectedExternalNodes(1) = nd2; + connectedExternalNodes(2) = nd3; + connectedExternalNodes(3) = nd4; + connectedExternalNodes(4) = nd5; + connectedExternalNodes(5) = nd6; + + for (i=0; igetNode(Nd1); + theNodes[1] = theDomain->getNode(Nd2); + theNodes[2] = theDomain->getNode(Nd3); + theNodes[3] = theDomain->getNode(Nd4); + theNodes[4] = theDomain->getNode(Nd5); + theNodes[5] = theDomain->getNode(Nd6); + + if (theNodes[0] == 0 || theNodes[1] == 0 || theNodes[2] == 0 || theNodes[3] == 0 || + theNodes[4] == 0 || theNodes[5] == 0) { + //opserr << "FATAL ERROR SixNodeTri (tag: %d), node not found in domain", + // this->getTag()); + + return; + } + + int dofNd1 = theNodes[0]->getNumberDOF(); + int dofNd2 = theNodes[1]->getNumberDOF(); + int dofNd3 = theNodes[2]->getNumberDOF(); + int dofNd4 = theNodes[3]->getNumberDOF(); + int dofNd5 = theNodes[4]->getNumberDOF(); + int dofNd6 = theNodes[5]->getNumberDOF(); + + if (dofNd1 != 2 || dofNd2 != 2 || dofNd3 != 2 || dofNd4 != 2 || + dofNd5 != 2 || dofNd6 != 2) { + //opserr << "FATAL ERROR SixNodeTri (tag: %d), has differing number of DOFs at its nodes", + // this->getTag()); + + return; + } + this->DomainComponent::setDomain(theDomain); + + // Compute consistent nodal loads due to pressure + this->setPressureLoadAtNodes(); +} + +int +SixNodeTri::commitState() +{ + int retVal = 0; + + // call element commitState to do any base class stuff + if ((retVal = this->Element::commitState()) != 0) { + opserr << "SixNodeTri::commitState () - failed in base class"; + } + + // Loop over the integration points and commit the material states + for (int i = 0; i < nip; i++) + retVal += theMaterial[i]->commitState(); + + return retVal; +} + +int +SixNodeTri::revertToLastCommit() +{ + int retVal = 0; + + // Loop over the integration points and revert to last committed state + for (int i = 0; i < nip; i++) + retVal += theMaterial[i]->revertToLastCommit(); + + return retVal; +} + +int +SixNodeTri::revertToStart() +{ + int retVal = 0; + + // Loop over the integration points and revert states to start + for (int i = 0; i < nip; i++) + retVal += theMaterial[i]->revertToStart(); + + return retVal; +} + + +int +SixNodeTri::update() +{ + const Vector &disp1 = theNodes[0]->getTrialDisp(); + const Vector &disp2 = theNodes[1]->getTrialDisp(); + const Vector &disp3 = theNodes[2]->getTrialDisp(); + const Vector &disp4 = theNodes[3]->getTrialDisp(); + const Vector &disp5 = theNodes[4]->getTrialDisp(); + const Vector &disp6 = theNodes[5]->getTrialDisp(); + + static double u[2][nnodes]; + + u[0][0] = disp1(0); + u[1][0] = disp1(1); + u[0][1] = disp2(0); + u[1][1] = disp2(1); + u[0][2] = disp3(0); + u[1][2] = disp3(1); + u[0][3] = disp4(0); + u[1][3] = disp4(1); + u[0][4] = disp5(0); + u[1][4] = disp5(1); + u[0][5] = disp6(0); + u[1][5] = disp6(1); + + static Vector eps(3); + + int ret = 0; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + this->shapeFunction(pts[i][0], pts[i][1]); + + // Interpolate strains + //eps = B*u; + //eps.addMatrixVector(0.0, B, u, 1.0); + eps.Zero(); + for (int beta = 0; beta < nnodes; beta++) { + eps(0) += shp[0][beta]*u[0][beta]; + eps(1) += shp[1][beta]*u[1][beta]; + eps(2) += shp[0][beta]*u[1][beta] + shp[1][beta]*u[0][beta]; + } + + // Set the material strain + ret += theMaterial[i]->setTrialStrain(eps); + } + + return ret; +} + + +const Matrix& +SixNodeTri::getTangentStiff() +{ + + K.Zero(); + + double dvol; + double DB[3][2]; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + dvol = this->shapeFunction(pts[i][0], pts[i][1]); + dvol *= (thickness*wts[i]); + + // Get the material tangent + const Matrix &D = theMaterial[i]->getTangent(); + + // Perform numerical integration + //K = K + (B^ D * B) * intWt(i)*intWt(j) * detJ; + //K.addMatrixTripleProduct(1.0, B, D, intWt(i)*intWt(j)*detJ); + + double D00 = D(0,0); double D01 = D(0,1); double D02 = D(0,2); + double D10 = D(1,0); double D11 = D(1,1); double D12 = D(1,2); + double D20 = D(2,0); double D21 = D(2,1); double D22 = D(2,2); + + // for (int beta = 0, ib = 0, colIb =0, colIbP1 = 8; + // beta < 4; + // beta++, ib += 2, colIb += 16, colIbP1 += 16) { + + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia += 2) { + for (int beta = 0, ib = 0; beta < nnodes; beta++, ib += 2) { + + DB[0][0] = dvol * (D00 * shp[0][beta] + D02 * shp[1][beta]); + DB[1][0] = dvol * (D10 * shp[0][beta] + D12 * shp[1][beta]); + DB[2][0] = dvol * (D20 * shp[0][beta] + D22 * shp[1][beta]); + DB[0][1] = dvol * (D01 * shp[1][beta] + D02 * shp[0][beta]); + DB[1][1] = dvol * (D11 * shp[1][beta] + D12 * shp[0][beta]); + DB[2][1] = dvol * (D21 * shp[1][beta] + D22 * shp[0][beta]); + + K(ia,ib) += shp[0][alpha]*DB[0][0] + shp[1][alpha]*DB[2][0]; + K(ia,ib+1) += shp[0][alpha]*DB[0][1] + shp[1][alpha]*DB[2][1]; + K(ia+1,ib) += shp[1][alpha]*DB[1][0] + shp[0][alpha]*DB[2][0]; + K(ia+1,ib+1) += shp[1][alpha]*DB[1][1] + shp[0][alpha]*DB[2][1]; + // matrixData[colIb + ia] += shp[0][alpha]*DB[0][0] + shp[1][alpha]*DB[2][0]; + //matrixData[colIbP1 + ia] += shp[0][alpha]*DB[0][1] + shp[1][alpha]*DB[2][1]; + //matrixData[colIb + ia+1] += shp[1][alpha]*DB[1][0] + shp[0][alpha]*DB[2][0]; + //matrixData[colIbP1 + ia+1] += shp[1][alpha]*DB[1][1] + shp[0][alpha]*DB[2][1]; + + } + } + } + + return K; +} + + +const Matrix& +SixNodeTri::getInitialStiff() +{ + if (Ki != 0) + return *Ki; + + K.Zero(); + + double dvol; + double DB[3][2]; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + dvol = this->shapeFunction(pts[i][0], pts[i][1]); + dvol *= (thickness*wts[i]); + + // Get the material tangent + const Matrix &D = theMaterial[i]->getInitialTangent(); + + double D00 = D(0,0); double D01 = D(0,1); double D02 = D(0,2); + double D10 = D(1,0); double D11 = D(1,1); double D12 = D(1,2); + double D20 = D(2,0); double D21 = D(2,1); double D22 = D(2,2); + + // Perform numerical integration + //K = K + (B^ D * B) * intWt(i)*intWt(j) * detJ; + //K.addMatrixTripleProduct(1.0, B, D, intWt(i)*intWt(j)*detJ); + for (int beta = 0, ib = 0, colIb =0, colIbP1 = 8; + beta < nnodes; + beta++, ib += 2, colIb += 16, colIbP1 += 16) { + + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia += 2) { + + DB[0][0] = dvol * (D00 * shp[0][beta] + D02 * shp[1][beta]); + DB[1][0] = dvol * (D10 * shp[0][beta] + D12 * shp[1][beta]); + DB[2][0] = dvol * (D20 * shp[0][beta] + D22 * shp[1][beta]); + DB[0][1] = dvol * (D01 * shp[1][beta] + D02 * shp[0][beta]); + DB[1][1] = dvol * (D11 * shp[1][beta] + D12 * shp[0][beta]); + DB[2][1] = dvol * (D21 * shp[1][beta] + D22 * shp[0][beta]); + + matrixData[colIb + ia] += shp[0][alpha]*DB[0][0] + shp[1][alpha]*DB[2][0]; + matrixData[colIbP1 + ia] += shp[0][alpha]*DB[0][1] + shp[1][alpha]*DB[2][1]; + matrixData[colIb + ia+1] += shp[1][alpha]*DB[1][0] + shp[0][alpha]*DB[2][0]; + matrixData[colIbP1 + ia+1] += shp[1][alpha]*DB[1][1] + shp[0][alpha]*DB[2][1]; + } + } + } + + Ki = new Matrix(K); + return K; +} + +const Matrix& +SixNodeTri::getMass() +{ + K.Zero(); + + int i; + static double rhoi[3]; // nip + double sum = 0.0; + for (i = 0; i < nip; i++) { + if (rho == 0) + rhoi[i] = theMaterial[i]->getRho(); + else + rhoi[i] = rho; + sum += rhoi[i]; + } + + if (sum == 0.0) + return K; + + double rhodvol, Nrho; + + // Compute a lumped mass matrix + for (i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + rhodvol = this->shapeFunction(pts[i][0], pts[i][1]); + + // Element plus material density ... MAY WANT TO REMOVE ELEMENT DENSITY + rhodvol *= (rhoi[i]*thickness*wts[i]); + + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia++) { + Nrho = shp[2][alpha]*rhodvol; + K(ia,ia) += Nrho; + ia++; + K(ia,ia) += Nrho; + } + } + + return K; +} + +void +SixNodeTri::zeroLoad(void) +{ + Q.Zero(); + + applyLoad = 0; + + appliedB[0] = 0.0; + appliedB[1] = 0.0; + + return; +} + +int +SixNodeTri::addLoad(ElementalLoad *theLoad, double loadFactor) +{ + // Added option for applying body forces in load pattern: C.McGann, U.Washington + int type; + const Vector &data = theLoad->getData(type, loadFactor); + + if (type == LOAD_TAG_SelfWeight) { + applyLoad = 1; + appliedB[0] += loadFactor*data(0)*b[0]; + appliedB[1] += loadFactor*data(1)*b[1]; + return 0; + } else { + opserr << "SixNodeTri::addLoad - load type unknown for ele with tag: " << this->getTag() << endln; + return -1; + } + + return -1; +} + +int +SixNodeTri::addInertiaLoadToUnbalance(const Vector &accel) +{ + int i; + static double rhoi[nip]; + double sum = 0.0; + for (i = 0; i < nip; i++) { + rhoi[i] = theMaterial[i]->getRho(); + sum += rhoi[i]; + } + + if (sum == 0.0) + return 0; + + // Get R * accel from the nodes + const Vector &Raccel1 = theNodes[0]->getRV(accel); + const Vector &Raccel2 = theNodes[1]->getRV(accel); + const Vector &Raccel3 = theNodes[2]->getRV(accel); + const Vector &Raccel4 = theNodes[3]->getRV(accel); + const Vector &Raccel5 = theNodes[4]->getRV(accel); + const Vector &Raccel6 = theNodes[5]->getRV(accel); + + if (2 != Raccel1.Size() || 2 != Raccel2.Size() || 2 != Raccel3.Size() || + 2 != Raccel4.Size() || 2 != Raccel5.Size() || 2 != Raccel6.Size()) { + opserr << "SixNodeTri::addInertiaLoadToUnbalance matrix and vector sizes are incompatible\n"; + return -1; + } + + static double ra[2*nnodes]; + + ra[0] = Raccel1(0); + ra[1] = Raccel1(1); + ra[2] = Raccel2(0); + ra[3] = Raccel2(1); + ra[4] = Raccel3(0); + ra[5] = Raccel3(1); + ra[6] = Raccel4(0); + ra[7] = Raccel4(1); + ra[8] = Raccel5(0); + ra[9] = Raccel5(1); + ra[10] = Raccel6(0); + ra[11] = Raccel6(1); + + // Compute mass matrix + this->getMass(); + + // Want to add ( - fact * M R * accel ) to unbalance + // Take advantage of lumped mass matrix + for (i = 0; i < 2*nnodes; i++) + Q(i) += -K(i,i)*ra[i]; + + return 0; +} + +const Vector& +SixNodeTri::getResistingForce() +{ + P.Zero(); + + double dvol; + + // Loop over the integration points + for (int i = 0; i < nip; i++) { + + // Determine Jacobian for this integration point + dvol = this->shapeFunction(pts[i][0], pts[i][1]); + dvol *= (thickness*wts[i]); + + // Get material stress response + const Vector &sigma = theMaterial[i]->getStress(); + + // Perform numerical integration on internal force + //P = P + (B^ sigma) * intWt(i)*intWt(j) * detJ; + //P.addMatrixTransposeVector(1.0, B, sigma, intWt(i)*intWt(j)*detJ); + for (int alpha = 0, ia = 0; alpha < nnodes; alpha++, ia += 2) { + + P(ia) += dvol*(shp[0][alpha]*sigma(0) + shp[1][alpha]*sigma(2)); + + P(ia+1) += dvol*(shp[1][alpha]*sigma(1) + shp[0][alpha]*sigma(2)); + + // Subtract equiv. body forces from the nodes + //P = P - (N^ b) * intWt(i)*intWt(j) * detJ; + //P.addMatrixTransposeVector(1.0, N, b, -intWt(i)*intWt(j)*detJ); + if (applyLoad == 0) { + P(ia) -= dvol*(shp[2][alpha]*b[0]); + P(ia+1) -= dvol*(shp[2][alpha]*b[1]); + } else { + P(ia) -= dvol*(shp[2][alpha]*appliedB[0]); + P(ia+1) -= dvol*(shp[2][alpha]*appliedB[1]); + } + } + } + + // Subtract pressure loading from resisting force + if (pressure != 0.0) { + //P = P - pressureLoad; + P.addVector(1.0, pressureLoad, -1.0); + } + + // Subtract other external nodal loads ... P_res = P_int - P_ext + //P = P - Q; + P.addVector(1.0, Q, -1.0); + + return P; +} + +const Vector& +SixNodeTri::getResistingForceIncInertia() +{ + int i; + static double rhoi[nip]; + double sum = 0.0; + for (i = 0; i < nip; i++) { + rhoi[i] = theMaterial[i]->getRho(); + sum += rhoi[i]; + } + + // if no mass terms .. just add damping terms + if (sum == 0.0) { + this->getResistingForce(); + + // add the damping forces if rayleigh damping + if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P += this->getRayleighDampingForces(); + + return P; + } + + const Vector &accel1 = theNodes[0]->getTrialAccel(); + const Vector &accel2 = theNodes[1]->getTrialAccel(); + const Vector &accel3 = theNodes[2]->getTrialAccel(); + const Vector &accel4 = theNodes[3]->getTrialAccel(); + const Vector &accel5 = theNodes[4]->getTrialAccel(); + const Vector &accel6 = theNodes[5]->getTrialAccel(); + + static double a[2*nnodes]; + + a[0] = accel1(0); + a[1] = accel1(1); + a[2] = accel2(0); + a[3] = accel2(1); + a[4] = accel3(0); + a[5] = accel3(1); + a[6] = accel4(0); + a[7] = accel4(1); + a[8] = accel5(0); + a[9] = accel5(1); + a[10] = accel6(0); + a[11] = accel6(1); + + // Compute the current resisting force + this->getResistingForce(); + + // Compute the mass matrix + this->getMass(); + + // Take advantage of lumped mass matrix + for (i = 0; i < 2*nnodes; i++) + P(i) += K(i,i)*a[i]; + + // add the damping forces if rayleigh damping + if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P += this->getRayleighDampingForces(); + + return P; +} + +int +SixNodeTri::sendSelf(int commitTag, Channel &theChannel) +{ + int res = 0; + + // note: we don't check for dataTag == 0 for Element + // objects as that is taken care of in a commit by the Domain + // object - don't want to have to do the check if sending data + int dataTag = this->getDbTag(); + + // Quad packs its data into a Vector and sends this to theChannel + // along with its dbTag and the commitTag passed in the arguments + static Vector data(9); + data(0) = this->getTag(); + data(1) = thickness; + data(2) = b[0]; + data(3) = b[1]; + data(4) = pressure; + + data(5) = alphaM; + data(6) = betaK; + data(7) = betaK0; + data(8) = betaKc; + + res += theChannel.sendVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING SixNodeTri::sendSelf() - " << this->getTag() << " failed to send Vector\n"; + return res; + } + + + // Now quad sends the ids of its materials + int matDbTag; + + static ID idData(2*nip+nnodes); + + int i; + for (i = 0; i < nip; i++) { + idData(i) = theMaterial[i]->getClassTag(); + matDbTag = theMaterial[i]->getDbTag(); + // NOTE: we do have to ensure that the material has a database + // tag if we are sending to a database channel. + if (matDbTag == 0) { + matDbTag = theChannel.getDbTag(); + if (matDbTag != 0) + theMaterial[i]->setDbTag(matDbTag); + } + // idData(i+4) = matDbTag; + idData(i+nip) = matDbTag; + } + + for( i = 0; i < nnodes; i++) + idData(2*nip+i) = connectedExternalNodes(i); + + res += theChannel.sendID(dataTag, commitTag, idData); + if (res < 0) { + opserr << "WARNING SixNodeTri::sendSelf() - " << this->getTag() << " failed to send ID\n"; + return res; + } + + // Finally, quad asks its material objects to send themselves + for (i = 0; i < nip; i++) { + res += theMaterial[i]->sendSelf(commitTag, theChannel); + if (res < 0) { + opserr << "WARNING SixNodeTri::sendSelf() - " << this->getTag() << " failed to send its Material\n"; + return res; + } + } + + return res; +} + +int +SixNodeTri::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + + int dataTag = this->getDbTag(); + + // Quad creates a Vector, receives the Vector and then sets the + // internal data with the data in the Vector + static Vector data(9); + res += theChannel.recvVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING SixNodeTri::recvSelf() - failed to receive Vector\n"; + return res; + } + + this->setTag((int)data(0)); + thickness = data(1); + b[0] = data(2); + b[1] = data(3); + pressure = data(4); + + alphaM = data(5); + betaK = data(6); + betaK0 = data(7); + betaKc = data(8); + + static ID idData(18); // 2*3 + 6 + // Quad now receives the tags of its nine external nodes + res += theChannel.recvID(dataTag, commitTag, idData); + if (res < 0) { + opserr << "WARNING SixNodeTri::recvSelf() - " << this->getTag() << " failed to receive ID\n"; + return res; + } + + for( int i = 0; i < nnodes; i++) + connectedExternalNodes(i) = idData(2*nip+i); + + if (theMaterial == 0) { + // Allocate new materials + theMaterial = new NDMaterial *[nip]; + if (theMaterial == 0) { + opserr << "SixNodeTri::recvSelf() - Could not allocate NDMaterial* array\n"; + return -1; + } + for (int i = 0; i < nip; i++) { + int matClassTag = idData(i); + int matDbTag = idData(i+nip); + // Allocate new material with the sent class tag + theMaterial[i] = theBroker.getNewNDMaterial(matClassTag); + if (theMaterial[i] == 0) { + opserr << "SixNodeTri::recvSelf() - Broker could not create NDMaterial of class type " << matClassTag << endln; + return -1; + } + // Now receive materials into the newly allocated space + theMaterial[i]->setDbTag(matDbTag); + res += theMaterial[i]->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "SixNodeTri::recvSelf() - material " << i << "failed to recv itself\n"; + return res; + } + } + } + + // materials exist , ensure materials of correct type and recvSelf on them + else { + for (int i = 0; i < nip; i++) { + int matClassTag = idData(i); + int matDbTag = idData(i+nip); + // Check that material is of the right type; if not, + // delete it and create a new one of the right type + if (theMaterial[i]->getClassTag() != matClassTag) { + delete theMaterial[i]; + theMaterial[i] = theBroker.getNewNDMaterial(matClassTag); + if (theMaterial[i] == 0) { + opserr << "SixNodeTri::recvSelf() - material " << i << "failed to create\n"; + return -1; + } + } + // Receive the material + theMaterial[i]->setDbTag(matDbTag); + res += theMaterial[i]->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "SixNodeTri::recvSelf() - material " << i << "failed to recv itself\n"; + return res; + } + } + } + + return res; +} + +void +SixNodeTri::Print(OPS_Stream &s, int flag) +{ + if (flag == 2) { + + s << "#SixNodeTri\n"; + + int i; + const int numNodes = nnodes; + const int nstress = nip ; + + for (i=0; igetCrds(); + // const Vector &nodeDisp = theNodes[i]->getDisp(); + s << "#NODE " << nodeCrd(0) << " " << nodeCrd(1) << " " << endln; + } + + // spit out the section location & invoke print on the scetion + const int numMaterials = nip; + + static Vector avgStress(nstress); + static Vector avgStrain(nstress); + avgStress.Zero(); + avgStrain.Zero(); + for (i=0; igetStress(); + avgStrain += theMaterial[i]->getStrain(); + } + avgStress /= numMaterials; + avgStrain /= numMaterials; + + s << "#AVERAGE_STRESS "; + for (i=0; igetTag() << endln; + s << "\tConnected external nodes: " << connectedExternalNodes; + s << "\tthickness: " << thickness << endln; + s << "\tsurface pressure: " << pressure << endln; + s << "\tmass density: " << rho << endln; + s << "\tbody forces: " << b[0] << " " << b[1] << endln; + theMaterial[0]->Print(s,flag); + s << "\tStress (xx yy xy)" << endln; + for (int i = 0; i < nip; i++) + s << "\t\tGauss point " << i+1 << ": " << theMaterial[i]->getStress(); + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << "\t\t\t{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"SixNodeTri\", "; + s << "\"nodes\": [" << connectedExternalNodes(0) << ", "; + s << connectedExternalNodes(1) << ", "; + s << connectedExternalNodes(2) << ", "; + s << connectedExternalNodes(3) << ", "; + s << connectedExternalNodes(4) << ", "; + s << connectedExternalNodes(5) << "], "; + s << "\"thickness\": " << thickness << ", "; + s << "\"surfacePressure\": " << pressure << ", "; + s << "\"masspervolume\": " << rho << ", "; + s << "\"bodyForces\": [" << b[0] << ", " << b[1] << "], "; + s << "\"material\": \"" << theMaterial[0]->getTag() << "\"}"; + } +} + +int +SixNodeTri::displaySelf(Renderer &theViewer, int displayMode, float fact, const char **modes, int numMode) +{ + + // first set the quantity to be displayed at the nodes; + // if displayMode is 1 through 3 we will plot material stresses otherwise 0.0 + + static Vector values(nip); + + for (int j=0; j 0) { + for (int i=0; igetStress(); + values(i) = stress(displayMode-1); + } + } + + // now determine the end points of the quad based on + // the display factor (a measure of the distorted image) + // store this information in 4 3d vectors v1 through v4 + const Vector &end1Crd = theNodes[0]->getCrds(); + const Vector &end2Crd = theNodes[1]->getCrds(); + const Vector &end3Crd = theNodes[2]->getCrds(); + const Vector &end4Crd = theNodes[3]->getCrds(); + const Vector &end5Crd = theNodes[4]->getCrds(); + const Vector &end6Crd = theNodes[5]->getCrds(); + + static Matrix coords(nnodes,3); + + if (displayMode >= 0) { + + const Vector &end1Disp = theNodes[0]->getDisp(); + const Vector &end2Disp = theNodes[1]->getDisp(); + const Vector &end3Disp = theNodes[2]->getDisp(); + const Vector &end4Disp = theNodes[3]->getDisp(); + const Vector &end5Disp = theNodes[4]->getDisp(); + const Vector &end6Disp = theNodes[5]->getDisp(); + + for (int i = 0; i < 2; i++) { + coords(0,i) = end1Crd(i) + end1Disp(i)*fact; + coords(1,i) = end2Crd(i) + end2Disp(i)*fact; + coords(2,i) = end3Crd(i) + end3Disp(i)*fact; + coords(3,i) = end4Crd(i) + end4Disp(i)*fact; + coords(4,i) = end5Crd(i) + end5Disp(i)*fact; + coords(5,i) = end6Crd(i) + end6Disp(i)*fact; + } + } else { + int mode = displayMode * -1; + const Matrix &eigen1 = theNodes[0]->getEigenvectors(); + const Matrix &eigen2 = theNodes[1]->getEigenvectors(); + const Matrix &eigen3 = theNodes[2]->getEigenvectors(); + const Matrix &eigen4 = theNodes[3]->getEigenvectors(); + const Matrix &eigen5 = theNodes[4]->getEigenvectors(); + const Matrix &eigen6 = theNodes[5]->getEigenvectors(); + if (eigen1.noCols() >= mode) { + for (int i = 0; i < 2; i++) { + coords(0,i) = end1Crd(i) + eigen1(i,mode-1)*fact; + coords(1,i) = end2Crd(i) + eigen2(i,mode-1)*fact; + coords(2,i) = end3Crd(i) + eigen3(i,mode-1)*fact; + coords(3,i) = end4Crd(i) + eigen4(i,mode-1)*fact; + coords(4,i) = end5Crd(i) + eigen5(i,mode-1)*fact; + coords(5,i) = end6Crd(i) + eigen6(i,mode-1)*fact; + } + } else { + for (int i = 0; i < 2; i++) { + coords(0,i) = end1Crd(i); + coords(1,i) = end2Crd(i); + coords(2,i) = end3Crd(i); + coords(3,i) = end4Crd(i); + coords(4,i) = end5Crd(i); + coords(5,i) = end6Crd(i); + } + } + } + + int error = 0; + + // finally we the element using drawPolygon + error += theViewer.drawPolygon (coords, values, this->getTag()); + + return error; +} + +Response* +SixNodeTri::setResponse(const char **argv, int argc, + OPS_Stream &output) +{ + Response *theResponse =0; + + output.tag("ElementOutput"); + output.attr("eleType","SixNodeTri"); + output.attr("eleTag",this->getTag()); + output.attr("node1",connectedExternalNodes[0]); + output.attr("node2",connectedExternalNodes[1]); + output.attr("node3",connectedExternalNodes[2]); + output.attr("node4",connectedExternalNodes[3]); + output.attr("node5",connectedExternalNodes[4]); + output.attr("node6",connectedExternalNodes[5]); + + char dataOut[20]; + if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) { + + for (int i=1; i<=nip; i++) { + sprintf(dataOut,"P1_%d",i); + output.tag("ResponseType",dataOut); + sprintf(dataOut,"P2_%d",i); + output.tag("ResponseType",dataOut); + } + + theResponse = new ElementResponse(this, 1, P); + } + + else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"integrPoint") == 0) { + + int pointNum = atoi(argv[1]); + if (pointNum > 0 && pointNum <= nip) { + + output.tag("GaussPoint"); + output.attr("number",pointNum); + output.attr("eta",pts[pointNum-1][0]); + output.attr("neta",pts[pointNum-1][1]); + + theResponse = theMaterial[pointNum-1]->setResponse(&argv[2], argc-2, output); + + output.endTag(); + + } + } + else if ((strcmp(argv[0],"stresses") ==0) || (strcmp(argv[0],"stress") ==0)) { + for (int i=0; igetClassTag()); + output.attr("tag", theMaterial[i]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma12"); + + output.endTag(); // GaussPoint + output.endTag(); // NdMaterialOutput + } + theResponse = new ElementResponse(this, 3, Vector(3*nip)); + } + + else if ((strcmp(argv[0],"stressesAtNodes") ==0) || (strcmp(argv[0],"stressAtNodes") ==0)) { + for (int i=0; igetClassTag()); + // output.attr("tag", theMaterial[i]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma12"); + + output.endTag(); // GaussPoint + // output.endTag(); // NdMaterialOutput + } + theResponse = new ElementResponse(this, 11, Vector(3*nnodes)); + } + + else if ((strcmp(argv[0],"strain") ==0) || (strcmp(argv[0],"strains") ==0)) { + for (int i=0; igetClassTag()); + output.attr("tag", theMaterial[i]->getTag()); + + output.tag("ResponseType","eta11"); + output.tag("ResponseType","eta22"); + output.tag("ResponseType","eta12"); + + output.endTag(); // GaussPoint + output.endTag(); // NdMaterialOutput + } + theResponse = new ElementResponse(this, 4, Vector(3*nip)); + } + + output.endTag(); // ElementOutput + + return theResponse; +} + +int +SixNodeTri::getResponse(int responseID, Information &eleInfo) +{ + if (responseID == 1) { + + return eleInfo.setVector(this->getResistingForce()); + + } else if (responseID == 3) { + + // Loop over the integration points + static Vector stresses(3*nip); + int cnt = 0; + for (int i = 0; i < nip; i++) { + + // Get material stress response + const Vector &sigma = theMaterial[i]->getStress(); + stresses(cnt) = sigma(0); + stresses(cnt+1) = sigma(1); + stresses(cnt+2) = sigma(2); + cnt += 3; + } + + return eleInfo.setVector(stresses); + + } else if (responseID == 11) { + + // extrapolate stress from Gauss points to element nodes + static Vector stressGP(3*nip); + static Vector stressAtNodes(3*nnodes); + stressAtNodes.Zero(); + int cnt = 0; + // first get stress components (xx, yy, xy) at Gauss points + for (int i = 0; i < nip; i++) { + // Get material stress response + const Vector &sigma = theMaterial[i]->getStress(); + stressGP(cnt) = sigma(0); + stressGP(cnt+1) = sigma(1); + stressGP(cnt+2) = sigma(2); + cnt += 3; + } + + const double We[nnodes][nip] = {{1.6666666666666667, -0.3333333333333333, -0.3333333333333333}, + {-0.3333333333333333, 1.6666666666666667, -0.3333333333333333}, + {-0.3333333333333333, -0.3333333333333333, 1.6666666666666667}, + {0.6666666666666667, 0.6666666666666667, -0.3333333333333333}, + {-0.3333333333333333, 0.6666666666666667, 0.6666666666666667}, + {0.6666666666666667, -0.3333333333333333, 0.6666666666666667}}; + int p, l; + for (int i = 0; i < nnodes; i++) { + for (int k = 0; k < 3; k++) { + p = 3*i + k; + for (int j = 0; j < nip; j++) { + l = 3*j + k; + stressAtNodes(p) += We[i][j] * stressGP(l); + // opserr << "stressAtNodes(" << p << ") = We[" << i << "][" << j << "] * stressGP(" << l << ") = " << We[i][j] << " * " << stressGP(l) << " = " << stressAtNodes(p) << "\n"; + } + } + } + + return eleInfo.setVector(stressAtNodes); + + } else if (responseID == 4) { + + // Loop over the integration points + static Vector stresses(3*nip); + int cnt = 0; + for (int i = 0; i < nip; i++) { + + // Get material stress response + const Vector &sigma = theMaterial[i]->getStrain(); + stresses(cnt) = sigma(0); + stresses(cnt+1) = sigma(1); + stresses(cnt+2) = sigma(2); + cnt += 3; + } + + return eleInfo.setVector(stresses); + + } else + + return -1; +} + +int +SixNodeTri::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc < 1) + return -1; + + int res = -1; + + // quad pressure loading + if (strcmp(argv[0],"pressure") == 0) { + return param.addObject(2, this); + } + // a material parameter + else if ((strstr(argv[0],"material") != 0) && (strcmp(argv[0],"materialState") != 0)) { + + if (argc < 3) + return -1; + + int pointNum = atoi(argv[1]); + if (pointNum > 0 && pointNum <= nip) + return theMaterial[pointNum-1]->setParameter(&argv[2], argc-2, param); + else + return -1; + } + + // otherwise it could be just a forall material parameter + else { + + int matRes = res; + for (int i=0; isetParameter(argv, argc, param); + + if (matRes != -1) + res = matRes; + } + } + + return res; +} + +int +SixNodeTri::updateParameter(int parameterID, Information &info) +{ + int res = -1; + int matRes = res; + switch (parameterID) { + case -1: + return -1; + + case 1: + + for (int i = 0; iupdateParameter(parameterID, info); + } + if (matRes != -1) { + res = matRes; + } + return res; + + case 2: + pressure = info.theDouble; + this->setPressureLoadAtNodes(); // update consistent nodal loads + return 0; + + default: + /* + if (parameterID >= 100) { // material parameter + int pointNum = parameterID/100; + if (pointNum > 0 && pointNum <= 4) + return theMaterial[pointNum-1]->updateParameter(parameterID-100*pointNum, info); + else + return -1; + } else // unknown + */ + return -1; + } +} + +double SixNodeTri::shapeFunction(double s, double t) +{ + const Vector &nd1Crds = theNodes[0]->getCrds(); + const Vector &nd2Crds = theNodes[1]->getCrds(); + const Vector &nd3Crds = theNodes[2]->getCrds(); + const Vector &nd4Crds = theNodes[3]->getCrds(); + const Vector &nd5Crds = theNodes[4]->getCrds(); + const Vector &nd6Crds = theNodes[5]->getCrds(); + + shp[2][0] = s*(2*s-1); + shp[2][1] = t*(2*t-1); + shp[2][2] = (1-s-t)*(1-2*s-2*t); + // shp[2][2] = 1 - 3*s - 3*t + 2*s*s + 2*t*t + 4*s*t; + shp[2][3] = 4*s*t; + shp[2][4] = 4*t*(1-s-t); + shp[2][5] = 4*s*(1-s-t); + + // derivatives + double N11 = 4*s-1; + double N12 = 0; + double N21 = 0; + double N22 = 4*t-1; + double N31 = -3+4*s+4*t; + double N32 = -3+4*t+4*s; + double N41 = 4*t; + double N42 = 4*s; + double N51 = -4*t; + double N52 = 4-4*s-8*t; + double N61 = 4-4*t-8*s; + double N62 = -4*s; + + double J[2][2]; + + J[0][0] = nd1Crds(0)*N11 + nd2Crds(0)*N21 + nd3Crds(0)*N31 + nd4Crds(0)*N41 + + nd5Crds(0)*N51 + nd6Crds(0)*N61; + J[0][1] = nd1Crds(0)*N12 + nd2Crds(0)*N22 + nd3Crds(0)*N32 + nd4Crds(0)*N42 + + nd5Crds(0)*N52 + nd6Crds(0)*N62; + J[1][0] = nd1Crds(1)*N11 + nd2Crds(1)*N21 + nd3Crds(1)*N31 + nd4Crds(1)*N41 + + nd5Crds(1)*N51 + nd6Crds(1)*N61; + J[1][1] = nd1Crds(1)*N12 + nd2Crds(1)*N22 + nd3Crds(1)*N32 + nd4Crds(1)*N42 + + nd5Crds(1)*N52 + nd6Crds(1)*N62; + + double detJ = J[0][0]*J[1][1] - J[0][1]*J[1][0]; + + double oneOverdetJ = 1/detJ; + double L[2][2]; + + // L = inv(J) + L[0][0] = J[1][1]*oneOverdetJ; + L[1][0] = -J[0][1]*oneOverdetJ; + L[0][1] = -J[1][0]*oneOverdetJ; + L[1][1] = J[0][0]*oneOverdetJ; + + double L00 = L[0][0]; + double L10 = L[1][0]; + double L01 = L[0][1]; + double L11 = L[1][1]; + + shp[0][0] = L00*N11 + L01*N12; + shp[0][1] = L00*N21 + L01*N22; + shp[0][2] = L00*N31 + L01*N32; + shp[0][3] = L00*N41 + L01*N42; + shp[0][4] = L00*N51 + L01*N52; + shp[0][5] = L00*N61 + L01*N62; + + shp[1][0] = L10*N11 + L11*N12; + shp[1][1] = L10*N21 + L11*N22; + shp[1][2] = L10*N31 + L11*N32; + shp[1][3] = L10*N41 + L11*N42; + shp[1][4] = L10*N51 + L11*N52; + shp[1][5] = L10*N61 + L11*N62; + + return detJ; +} + +void +SixNodeTri::setPressureLoadAtNodes(void) +{ + pressureLoad.Zero(); + + if (pressure == 0.0) + return; + + const Vector &node1 = theNodes[0]->getCrds(); + const Vector &node2 = theNodes[1]->getCrds(); + const Vector &node3 = theNodes[2]->getCrds(); + const Vector &node4 = theNodes[3]->getCrds(); + const Vector &node5 = theNodes[4]->getCrds(); + const Vector &node6 = theNodes[5]->getCrds(); + + double x1 = node1(0); + double y1 = node1(1); + double x2 = node2(0); + double y2 = node2(1); + double x3 = node3(0); + double y3 = node3(1); + double x4 = node4(0); + double y4 = node4(1); + double x5 = node5(0); + double y5 = node5(1); + double x6 = node6(0); + double y6 = node6(1); + + double dx14 = x4-x1; + double dy14 = y4-y1; + double dx42 = x2-x4; + double dy42 = y2-y4; + double dx25 = x5-x2; + double dy25 = y5-y2; + double dx53 = x3-x5; + double dy53 = y3-y5; + double dx36 = x6-x3; + double dy36 = y6-y3; + double dx61 = x4-x6; + double dy61 = y4-y6; + + double fac1 = 0.3333333333333333; + double fac2 = 0.6666666666666667; + + // Contribution from side 14 + pressureLoad(0) += pressure*fac1*dy14; + pressureLoad(6) += pressure*fac2*dy14; + pressureLoad(1) += pressure*fac1*-dx14; + pressureLoad(7) += pressure*fac2*-dx14; + + // Contribution from side 42 + pressureLoad(6) += pressure*fac2*dy42; + pressureLoad(2) += pressure*fac1*dy42; + pressureLoad(7) += pressure*fac2*-dx42; + pressureLoad(3) += pressure*fac1*-dx42; + + // Contribution from side 25 + pressureLoad(2) += pressure*fac1*dy25; + pressureLoad(8) += pressure*fac2*dy25; + pressureLoad(3) += pressure*fac1*-dx25; + pressureLoad(9) += pressure*fac2*-dx25; + + // Contribution from side 53 + pressureLoad(8) += pressure*fac2*dy53; + pressureLoad(4) += pressure*fac1*dy53; + pressureLoad(9) += pressure*fac2*-dx53; + pressureLoad(5) += pressure*fac1*-dx53; + + // Contribution from side 36 + pressureLoad(4) += pressure*fac1*dy36; + pressureLoad(10) += pressure*fac2*dy36; + pressureLoad(5) += pressure*fac1*-dx36; + pressureLoad(11) += pressure*fac2*-dx36; + + // Contribution from side 61 + pressureLoad(10) += pressure*fac2*dy61; + pressureLoad(0) += pressure*fac1*dy61; + pressureLoad(11) += pressure*fac2*-dx61; + pressureLoad(1) += pressure*fac1*-dx61; + + //pressureLoad = pressureLoad*thickness; +} diff --git a/SRC/element/fourNodeQuad/SixNodeTri.h b/SRC/element/fourNodeQuad/SixNodeTri.h new file mode 100644 index 0000000000..bcae2bf2df --- /dev/null +++ b/SRC/element/fourNodeQuad/SixNodeTri.h @@ -0,0 +1,139 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ +// +// based on FourNodeQuad by MHS +// Written: Seweryn Kokot, Opole University of Technology, Poland +// Created: Sep 2020 +// +// Description: This file contains the class definition for SixNodeTri. + +#ifndef SixNodeTri_h +#define SixNodeTri_h + +#ifndef _bool_h +#include "bool.h" +#endif + +#include +#include +#include +#include + +class Node; +class NDMaterial; +class Response; + +class SixNodeTri : public Element { +public: + SixNodeTri(int tag, int nd1, int nd2, int nd3, int nd4, int nd5, int nd6, + NDMaterial &m, const char *type, double t, + double pressure = 0.0, double rho = 0.0, double b1 = 0.0, + double b2 = 0.0); + SixNodeTri(); + ~SixNodeTri(); + + const char *getClassType(void) const { return "SixNodeTri"; }; + + int getNumExternalNodes(void) const; + const ID &getExternalNodes(void); + Node **getNodePtrs(void); + + int getNumDOF(void); + void setDomain(Domain *theDomain); + + // public methods to set the state of the element + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + int update(void); + + // public methods to obtain stiffness, mass, damping and residual information + const Matrix &getTangentStiff(void); + const Matrix &getInitialStiff(void); + const Matrix &getMass(void); + + void zeroLoad(); + int addLoad(ElementalLoad *theLoad, double loadFactor); + int addInertiaLoadToUnbalance(const Vector &accel); + + const Vector &getResistingForce(void); + const Vector &getResistingForceIncInertia(void); + + // public methods for element output + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + + int displaySelf(Renderer &, int mode, float fact, + const char **displayModes = 0, int numModes = 0); + void Print(OPS_Stream &s, int flag = 0); + + Response *setResponse(const char **argv, int argc, OPS_Stream &s); + + int getResponse(int responseID, Information &eleInformation); + + int setParameter(const char **argv, int argc, Parameter ¶m); + int updateParameter(int parameterID, Information &info); + + // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial + // stresses. + friend class PyLiq1; + friend class TzLiq1; + +protected: +private: + // private attributes - a copy for each object of the class + + static constexpr int nip = 3; // number of integration/Gauss points + static constexpr int nnodes = 6; // number of nodes + + NDMaterial **theMaterial; // pointer to the ND material objects + + ID connectedExternalNodes; // Tags of quad nodes + + Node *theNodes[nnodes]; + + static double matrixData[(nnodes*2)*(nnodes*2)]; // array data for matrix + static Matrix K; // Element stiffness, damping, and mass Matrix + static Vector P; // Element resisting force vector + Vector Q; // Applied nodal loads + double b[2]; // Body forces + + double appliedB[2]; // Body forces applied with load pattern, C.McGann, + // U.Washington + int applyLoad; // flag for body force in load, C.McGann, U.Washington + + Vector pressureLoad; // Pressure load at nodes + + double thickness; // Element thickness + double pressure; // Normal surface traction (pressure) over entire element + // Note: positive for outward normal + double rho; + static double shp[3][nnodes]; // Stores shape functions and derivatives (overwritten) + static double pts[nip][2]; // Stores quadrature points + static double wts[nip]; // Stores quadrature weights + + // private member functions - only objects of this class can call these + double shapeFunction(double xi, double eta); + void setPressureLoadAtNodes(void); + + Matrix *Ki; +}; + +#endif diff --git a/SRC/element/fourNodeQuad/TclFourNodeQuadCommand.cpp b/SRC/element/fourNodeQuad/TclFourNodeQuadCommand.cpp index a2087694e7..d5294dd719 100644 --- a/SRC/element/fourNodeQuad/TclFourNodeQuadCommand.cpp +++ b/SRC/element/fourNodeQuad/TclFourNodeQuadCommand.cpp @@ -42,6 +42,9 @@ #include #include #include +#include +#include +#include #include @@ -678,3 +681,475 @@ TclModelBuilder_addFourNodeQuadWithSensitivity(ClientData clientData, Tcl_Interp // if get here we have successfully created the element and added it to the domain return TCL_OK; } + +// Regular nine node quad + +int +TclModelBuilder_addNineNodeQuad(ClientData clientData, Tcl_Interp *interp, + int argc, + TCL_Char **argv, + Domain*theTclDomain, + TclModelBuilder *theTclBuilder) +{ + // ensure the destructor has not been called - + if (theTclBuilder == 0) { + opserr << "WARNING builder has been destroyed\n"; + return TCL_ERROR; + } + + if (theTclBuilder->getNDM() != 2 || theTclBuilder->getNDF() != 2) { + opserr << "WARNING -- model dimensions and/or nodal DOF not compatible with quad element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc-argStart) < 13) { + opserr << "WARNING insufficient arguments\n"; + printCommand(argc, argv); + opserr << "Want: element NineNodeQuad eleTag? iNode? jNode? kNode? lNode? nNode? mNode? pNode? qNode? cNode? thk? type? matTag? \n"; + return TCL_ERROR; + } + + // get the id and end nodes + int NineNodeQuadId, iNode, jNode, kNode, lNode; + int nNode, mNode, pNode, qNode, cNode, matID; + double thickness = 1.0; + double p = 0.0; // uniform normal traction (pressure) + double rho = 0.0; // mass density + double b1 = 0.0; + double b2 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &NineNodeQuadId) != TCL_OK) { + opserr << "WARNING invalid NineNodeQuad eleTag" << endln; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[1+argStart], &iNode) != TCL_OK) { + opserr << "WARNING invalid iNode\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2+argStart], &jNode) != TCL_OK) { + opserr << "WARNING invalid jNode\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3+argStart], &kNode) != TCL_OK) { + opserr << "WARNING invalid kNode\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4+argStart], &lNode) != TCL_OK) { + opserr << "WARNING invalid lNode\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[5+argStart], &nNode) != TCL_OK) { + opserr << "WARNING invalid nNode\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[6+argStart], &mNode) != TCL_OK) { + opserr << "WARNING invalid mNode\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[7+argStart], &pNode) != TCL_OK) { + opserr << "WARNING invalid pNode\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[8+argStart], &qNode) != TCL_OK) { + opserr << "WARNING invalid qNode\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[9+argStart], &cNode) != TCL_OK) { + opserr << "WARNING invalid cNode\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[10+argStart], &thickness) != TCL_OK) { + opserr << "WARNING invalid thickness\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + TCL_Char *type = argv[11+argStart]; + + if (Tcl_GetInt(interp, argv[12+argStart], &matID) != TCL_OK) { + opserr << "WARNING invalid matID\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + if ((argc-argStart) > 16) { + if (Tcl_GetDouble(interp, argv[13+argStart], &p) != TCL_OK) { + opserr << "WARNING invalid pressure\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[14+argStart], &rho) != TCL_OK) { + opserr << "WARNING invalid b1\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[15+argStart], &b1) != TCL_OK) { + opserr << "WARNING invalid b1\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[16+argStart], &b2) != TCL_OK) { + opserr << "WARNING invalid b2\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = OPS_getNDMaterial(matID); + + if (theMaterial == 0) { + opserr << "WARNING material not found\n"; + opserr << "Material: " << matID; + opserr << "\nNineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + // now create the NineNodeQuad and add it to the Domain + NineNodeQuad *theNineNodeQuad = + new NineNodeQuad(NineNodeQuadId,iNode,jNode,kNode,lNode, + nNode,mNode,pNode,qNode,cNode, + *theMaterial, type, thickness, p, rho, b1, b2); + if (theNineNodeQuad == 0) { + opserr << "WARNING ran out of memory creating element\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + return TCL_ERROR; + } + + if (theTclDomain->addElement(theNineNodeQuad) == false) { + opserr << "WARNING could not add element to the domain\n"; + opserr << "NineNodeQuad element: " << NineNodeQuadId << endln; + delete theNineNodeQuad; + return TCL_ERROR; + } + + // if get here we have successfully created the element and added it to the domain + return TCL_OK; +} + + +// Regular eight node quad + +int +TclModelBuilder_addEightNodeQuad(ClientData clientData, Tcl_Interp *interp, + int argc, + TCL_Char **argv, + Domain*theTclDomain, + TclModelBuilder *theTclBuilder) +{ + // ensure the destructor has not been called - + if (theTclBuilder == 0) { + opserr << "WARNING builder has been destroyed\n"; + return TCL_ERROR; + } + + if (theTclBuilder->getNDM() != 2 || theTclBuilder->getNDF() != 2) { + opserr << "WARNING -- model dimensions and/or nodal DOF not compatible with quad element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc-argStart) < 12) { + opserr << "WARNING insufficient arguments\n"; + printCommand(argc, argv); + opserr << "Want: element EightNodeQuad eleTag? iNode? jNode? kNode? lNode? nNode? mNode? pNode? qNode? thk? type? matTag? \n"; + return TCL_ERROR; + } + + // get the id and end nodes + int EightNodeQuadId, iNode, jNode, kNode, lNode; + int nNode, mNode, pNode, qNode, matID; + double thickness = 1.0; + double p = 0.0; // uniform normal traction (pressure) + double rho = 0.0; // mass density + double b1 = 0.0; + double b2 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &EightNodeQuadId) != TCL_OK) { + opserr << "WARNING invalid EightNodeQuad eleTag" << endln; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[1+argStart], &iNode) != TCL_OK) { + opserr << "WARNING invalid iNode\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2+argStart], &jNode) != TCL_OK) { + opserr << "WARNING invalid jNode\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3+argStart], &kNode) != TCL_OK) { + opserr << "WARNING invalid kNode\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4+argStart], &lNode) != TCL_OK) { + opserr << "WARNING invalid lNode\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[5+argStart], &nNode) != TCL_OK) { + opserr << "WARNING invalid nNode\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[6+argStart], &mNode) != TCL_OK) { + opserr << "WARNING invalid mNode\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[7+argStart], &pNode) != TCL_OK) { + opserr << "WARNING invalid pNode\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[8+argStart], &qNode) != TCL_OK) { + opserr << "WARNING invalid qNode\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[9+argStart], &thickness) != TCL_OK) { + opserr << "WARNING invalid thickness\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + TCL_Char *type = argv[10+argStart]; + + if (Tcl_GetInt(interp, argv[11+argStart], &matID) != TCL_OK) { + opserr << "WARNING invalid matID\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + if ((argc-argStart) > 15) { + if (Tcl_GetDouble(interp, argv[12+argStart], &p) != TCL_OK) { + opserr << "WARNING invalid pressure\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[13+argStart], &rho) != TCL_OK) { + opserr << "WARNING invalid b1\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[14+argStart], &b1) != TCL_OK) { + opserr << "WARNING invalid b1\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[15+argStart], &b2) != TCL_OK) { + opserr << "WARNING invalid b2\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = OPS_getNDMaterial(matID); + + if (theMaterial == 0) { + opserr << "WARNING material not found\n"; + opserr << "Material: " << matID; + opserr << "\nEightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + // now create the EightNodeQuad and add it to the Domain + EightNodeQuad *theEightNodeQuad = + new EightNodeQuad(EightNodeQuadId,iNode,jNode,kNode,lNode, + nNode,mNode,pNode,qNode, + *theMaterial, type, thickness, p, rho, b1, b2); + if (theEightNodeQuad == 0) { + opserr << "WARNING ran out of memory creating element\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + return TCL_ERROR; + } + + if (theTclDomain->addElement(theEightNodeQuad) == false) { + opserr << "WARNING could not add element to the domain\n"; + opserr << "EightNodeQuad element: " << EightNodeQuadId << endln; + delete theEightNodeQuad; + return TCL_ERROR; + } + + // if get here we have successfully created the element and added it to the domain + return TCL_OK; +} + +// Six node tri + +int +TclModelBuilder_addSixNodeTri(ClientData clientData, Tcl_Interp *interp, + int argc, + TCL_Char **argv, + Domain*theTclDomain, + TclModelBuilder *theTclBuilder) +{ + // ensure the destructor has not been called - + if (theTclBuilder == 0) { + opserr << "WARNING builder has been destroyed\n"; + return TCL_ERROR; + } + + if (theTclBuilder->getNDM() != 2 || theTclBuilder->getNDF() != 2) { + opserr << "WARNING -- model dimensions and/or nodal DOF not compatible with quad element\n"; + return TCL_ERROR; + } + + // check the number of arguments is correct + int argStart = 2; + + if ((argc-argStart) < 10) { + opserr << "WARNING insufficient arguments\n"; + printCommand(argc, argv); + opserr << "Want: element SixNodeTri eleTag? iNode? jNode? kNode? lNode? nNode? mNode? pNode? qNode? thk? type? matTag? \n"; + return TCL_ERROR; + } + + // get the id and end nodes + int SixNodeTriId, iNode, jNode, kNode, lNode; + int nNode, mNode, matID; + double thickness = 1.0; + double p = 0.0; // uniform normal traction (pressure) + double rho = 0.0; // mass density + double b1 = 0.0; + double b2 = 0.0; + + if (Tcl_GetInt(interp, argv[argStart], &SixNodeTriId) != TCL_OK) { + opserr << "WARNING invalid SixNodeTri eleTag" << endln; + return TCL_ERROR; + } + if (Tcl_GetInt(interp, argv[1+argStart], &iNode) != TCL_OK) { + opserr << "WARNING invalid iNode\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[2+argStart], &jNode) != TCL_OK) { + opserr << "WARNING invalid jNode\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[3+argStart], &kNode) != TCL_OK) { + opserr << "WARNING invalid kNode\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[4+argStart], &lNode) != TCL_OK) { + opserr << "WARNING invalid lNode\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[5+argStart], &nNode) != TCL_OK) { + opserr << "WARNING invalid nNode\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + + if (Tcl_GetInt(interp, argv[6+argStart], &mNode) != TCL_OK) { + opserr << "WARNING invalid mNode\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + + if (Tcl_GetDouble(interp, argv[7+argStart], &thickness) != TCL_OK) { + opserr << "WARNING invalid thickness\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + + TCL_Char *type = argv[8+argStart]; + + if (Tcl_GetInt(interp, argv[9+argStart], &matID) != TCL_OK) { + opserr << "WARNING invalid matID\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + + if ((argc-argStart) > 13) { + if (Tcl_GetDouble(interp, argv[10+argStart], &p) != TCL_OK) { + opserr << "WARNING invalid pressure\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[11+argStart], &rho) != TCL_OK) { + opserr << "WARNING invalid b1\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[12+argStart], &b1) != TCL_OK) { + opserr << "WARNING invalid b1\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[13+argStart], &b2) != TCL_OK) { + opserr << "WARNING invalid b2\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + } + + NDMaterial *theMaterial = OPS_getNDMaterial(matID); + + if (theMaterial == 0) { + opserr << "WARNING material not found\n"; + opserr << "Material: " << matID; + opserr << "\nSixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + + // now create the SixNodeTri and add it to the Domain + SixNodeTri *theSixNodeTri = + new SixNodeTri(SixNodeTriId,iNode,jNode,kNode,lNode, + nNode,mNode, + *theMaterial, type, thickness, p, rho, b1, b2); + if (theSixNodeTri == 0) { + opserr << "WARNING ran out of memory creating element\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + return TCL_ERROR; + } + + if (theTclDomain->addElement(theSixNodeTri) == false) { + opserr << "WARNING could not add element to the domain\n"; + opserr << "SixNodeTri element: " << SixNodeTriId << endln; + delete theSixNodeTri; + return TCL_ERROR; + } + + // if get here we have successfully created the element and added it to the domain + return TCL_OK; +} diff --git a/SRC/element/frictionBearing/frictionModel/Coulomb.h b/SRC/element/frictionBearing/frictionModel/Coulomb.h index ef522fb931..002cb8095a 100755 --- a/SRC/element/frictionBearing/frictionModel/Coulomb.h +++ b/SRC/element/frictionBearing/frictionModel/Coulomb.h @@ -35,7 +35,7 @@ // normal force perpendicular to the sliding surface. If N is negative // the friction force is zero. -#include +#include "FrictionModel.h" class Coulomb : public FrictionModel { diff --git a/SRC/element/frictionBearing/frictionModel/TclModelBuilderFrictionModelCommand.cpp b/SRC/element/frictionBearing/frictionModel/TclModelBuilderFrictionModelCommand.cpp index 305afe7bb0..a3120e8e97 100755 --- a/SRC/element/frictionBearing/frictionModel/TclModelBuilderFrictionModelCommand.cpp +++ b/SRC/element/frictionBearing/frictionModel/TclModelBuilderFrictionModelCommand.cpp @@ -39,13 +39,6 @@ extern void *OPS_VelDepMultiLinear(); extern void *OPS_VelNormalFrcDep(); extern void *OPS_VelPressureDep(); -extern int OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain); - static void printCommand(int argc, TCL_Char **argv) { diff --git a/SRC/element/frictionBearing/frictionModel/VelDepMultiLinear.h b/SRC/element/frictionBearing/frictionModel/VelDepMultiLinear.h index 85b217c2f9..e98f6b78c9 100644 --- a/SRC/element/frictionBearing/frictionModel/VelDepMultiLinear.h +++ b/SRC/element/frictionBearing/frictionModel/VelDepMultiLinear.h @@ -35,7 +35,7 @@ // a number of non-negative velocity/friction pairs. If the normal force N is // negative the friction force is zero. -#include +#include "FrictionModel.h" class VelDepMultiLinear : public FrictionModel { diff --git a/SRC/element/frictionBearing/frictionModel/VelDependent.h b/SRC/element/frictionBearing/frictionModel/VelDependent.h index 69dbfbff1e..88d2a79ae1 100755 --- a/SRC/element/frictionBearing/frictionModel/VelDependent.h +++ b/SRC/element/frictionBearing/frictionModel/VelDependent.h @@ -35,7 +35,7 @@ // at low and high velocities and a constant describing the rate of transition. // If the normal force N is negative the friction force is zero. -#include +#include "FrictionModel.h" class VelDependent : public FrictionModel { diff --git a/SRC/element/frictionBearing/frictionModel/VelNormalFrcDep.h b/SRC/element/frictionBearing/frictionModel/VelNormalFrcDep.h index 333ede1ba3..cd646877b5 100644 --- a/SRC/element/frictionBearing/frictionModel/VelNormalFrcDep.h +++ b/SRC/element/frictionBearing/frictionModel/VelNormalFrcDep.h @@ -36,7 +36,7 @@ // coefficients at low and high velocities with both of them being a function of // the normal force. If the normal force N is negative the friction force is zero. -#include +#include "FrictionModel.h" class VelNormalFrcDep : public FrictionModel { diff --git a/SRC/element/frictionBearing/frictionModel/VelPressureDep.h b/SRC/element/frictionBearing/frictionModel/VelPressureDep.h index e1826ed48e..c5e8c21b71 100755 --- a/SRC/element/frictionBearing/frictionModel/VelPressureDep.h +++ b/SRC/element/frictionBearing/frictionModel/VelPressureDep.h @@ -35,7 +35,7 @@ // coefficients at low and high velocities with the latter one being a function of // pressure. If the normal force N is negative the friction force is zero. -#include +#include "FrictionModel.h" class VelPressureDep : public FrictionModel { diff --git a/SRC/element/gradientInelasticBeamColumn/Makefile b/SRC/element/gradientInelasticBeamColumn/Makefile index 7f1f261498..65ce5cc642 100644 --- a/SRC/element/gradientInelasticBeamColumn/Makefile +++ b/SRC/element/gradientInelasticBeamColumn/Makefile @@ -2,7 +2,8 @@ include ../../../Makefile.def OBJS = \ GradientInelasticBeamColumn2d.o \ - GradientInelasticBeamColumn3d.o + GradientInelasticBeamColumn3d.o \ + TclGradientInelasticBeamColumnCommand.o # Compilation control diff --git a/SRC/element/mixedBeamColumn/MixedBeamColumn2d.cpp b/SRC/element/mixedBeamColumn/MixedBeamColumn2d.cpp index 8ca3642880..1197f040ef 100644 --- a/SRC/element/mixedBeamColumn/MixedBeamColumn2d.cpp +++ b/SRC/element/mixedBeamColumn/MixedBeamColumn2d.cpp @@ -154,12 +154,12 @@ void * OPS_MixedBeamColumn2d() { } // Check for minimum number of arguments - if (OPS_GetNumRemainingInputArgs() < 6) { - opserr << "ERROR: MixedBeamColumn2d: too few arguments\n"; + if (OPS_GetNumRemainingInputArgs() < 5) { + opserr << "ERROR: MixedBeamColumn2d, too few arguments: eleTag,ndI,ndJ,transfTag,integrationTag\n"; return 0; } - numData = 6; + numData = 5; if (OPS_GetIntInput(&numData, iData) != 0) { opserr << "WARNING invalid element data - MixedBeamColumn2d\n"; return 0; @@ -168,21 +168,9 @@ void * OPS_MixedBeamColumn2d() { int eleTag = iData[0]; int nodeI = iData[1]; int nodeJ = iData[2]; - int numIntgrPts = iData[3]; - int secTag = iData[4]; - int transfTag = iData[5]; - - // Get the section - SectionForceDeformation *theSection = OPS_getSectionForceDeformation(secTag); - if (theSection == 0) { - opserr << "WARNING section with tag " << secTag << "not found for element " << eleTag << endln; - return 0; - } - - SectionForceDeformation **sections = new SectionForceDeformation *[numIntgrPts]; - for (int i = 0; i < numIntgrPts; i++) - sections[i] = theSection; - + int transfTag = iData[3]; + int beamIntTag = iData[4]; + // Get the coordinate transformation CrdTransf *theTransf = OPS_getCrdTransf(transfTag); if (theTransf == 0) { @@ -190,21 +178,38 @@ void * OPS_MixedBeamColumn2d() { return 0; } - + // Get beam integrataion + BeamIntegrationRule* theRule = OPS_getBeamIntegrationRule(beamIntTag); + if(theRule == 0) { + opserr<<"beam integration not found\n"; + return 0; + } + BeamIntegration* bi = theRule->getBeamIntegration(); + if(bi == 0) { + opserr<<"beam integration is null\n"; + return 0; + } + + // check sections + const ID& secTags = theRule->getSectionTags(); + SectionForceDeformation** sections = new SectionForceDeformation *[secTags.Size()]; + for(int i=0; i 0 ) { const char *sData = OPS_GetString(); - //if ( OPS_GetStringCopy(&sData) != 0 ) { - // opserr << "WARNING invalid input"; - // return 0; - //} - if ( strcmp(sData,"-mass") == 0 ) { numData = 1; if (OPS_GetDoubleInput(&numData, dData) != 0) { @@ -213,40 +218,6 @@ void * OPS_MixedBeamColumn2d() { } massDens = dData[0]; - } else if ( strcmp(sData,"-integration") == 0 ) { - const char *sData2 = OPS_GetString(); - //if ( OPS_GetStringCopy(&sData2) != 0 ) { - // opserr << "WARNING invalid input, want: -integration $intType"; - // return 0; - //} - - if (strcmp(sData2,"Lobatto") == 0) { - beamIntegr = new LobattoBeamIntegration(); - } else if (strcmp(sData2,"Legendre") == 0) { - beamIntegr = new LegendreBeamIntegration(); - } else if (strcmp(sData2,"Radau") == 0) { - beamIntegr = new RadauBeamIntegration(); - } else if (strcmp(sData2,"NewtonCotes") == 0) { - beamIntegr = new NewtonCotesBeamIntegration(); - } else if (strcmp(sData2,"Trapezoidal") == 0) { - beamIntegr = new TrapezoidalBeamIntegration(); - } else if (strcmp(sData2,"RegularizedLobatto") == 0 || strcmp(sData2,"RegLobatto") == 0) { - numData = 4; - if (OPS_GetDoubleInput(&numData, dData) != 0) { - opserr << "WARNING invalid input, want: -integration RegularizedLobatto $lpI $lpJ $zetaI $zetaJ \n"; - return 0; - } - BeamIntegration *otherBeamInt = 0; - otherBeamInt = new LobattoBeamIntegration(); - beamIntegr = new RegularizedHingeIntegration(*otherBeamInt, dData[0], dData[1], dData[2], dData[3]); - if (otherBeamInt != 0) - delete otherBeamInt; - } else { - opserr << "WARNING invalid integration type, element: " << eleTag; - return 0; - } - //delete [] sData2; - } else if ( strcmp(sData,"-doRayleigh") == 0 ) { numData = 1; if (OPS_GetInt(&numData, &doRayleigh) != 0) { @@ -260,16 +231,10 @@ void * OPS_MixedBeamColumn2d() { } else { opserr << "WARNING unknown option " << sData << "\n"; } - //delete [] sData; - } - - // Set the beam integration object if not in options - if (beamIntegr == 0) { - beamIntegr = new LobattoBeamIntegration(); } // now create the element and add it to the Domain - Element *theElement = new MixedBeamColumn2d(eleTag, nodeI, nodeJ, numIntgrPts, sections, *beamIntegr, *theTransf, massDens, doRayleigh, geomLinear); + Element *theElement = new MixedBeamColumn2d(eleTag, nodeI, nodeJ, secTags.Size(), sections, *bi, *theTransf, massDens, doRayleigh, geomLinear); if (theElement == 0) { opserr << "WARNING ran out of memory creating element with tag " << eleTag << endln; diff --git a/SRC/element/mixedBeamColumn/MixedBeamColumn3d.cpp b/SRC/element/mixedBeamColumn/MixedBeamColumn3d.cpp index a4b2b0552e..87d06eac7e 100644 --- a/SRC/element/mixedBeamColumn/MixedBeamColumn3d.cpp +++ b/SRC/element/mixedBeamColumn/MixedBeamColumn3d.cpp @@ -137,13 +137,13 @@ void * OPS_MixedBeamColumn3d() { } // Check for minimum number of arguments - if (OPS_GetNumRemainingInputArgs() < 6) { - opserr << "ERROR: MixedBeamColumn3d: too few arguments\n"; + if (OPS_GetNumRemainingInputArgs() < 5) { + opserr << "ERROR: MixedBeamColumn3d, too few arguments: eleTag,ndI,ndJ,transfTag,integrationTag\n"; return 0; } // Get required input data - numData = 6; + numData = 5; if (OPS_GetIntInput(&numData, iData) != 0) { opserr << "WARNING invalid element data - MixedBeamColumn3d\n"; return 0; @@ -151,21 +151,8 @@ void * OPS_MixedBeamColumn3d() { int eleTag = iData[0]; int nodeI = iData[1]; int nodeJ = iData[2]; - int numIntgrPts = iData[3]; - int secTag = iData[4]; - int transfTag = iData[5]; - - // Get the section - SectionForceDeformation *theSection = OPS_getSectionForceDeformation(secTag); - if (theSection == 0) { - opserr << "WARNING section with tag " << secTag << "not found for element " << eleTag << endln; - return 0; - } - - SectionForceDeformation **sections = new SectionForceDeformation *[numIntgrPts]; - for (int i = 0; i < numIntgrPts; i++) { - sections[i] = theSection; - } + int transfTag = iData[3]; + int beamIntTag = iData[4]; // Get the coordinate transformation CrdTransf *theTransf = OPS_getCrdTransf(transfTag); @@ -174,20 +161,38 @@ void * OPS_MixedBeamColumn3d() { return 0; } + // Get beam integrataion + BeamIntegrationRule* theRule = OPS_getBeamIntegrationRule(beamIntTag); + if(theRule == 0) { + opserr<<"beam integration not found\n"; + return 0; + } + BeamIntegration* bi = theRule->getBeamIntegration(); + if(bi == 0) { + opserr<<"beam integration is null\n"; + return 0; + } + + // check sections + const ID& secTags = theRule->getSectionTags(); + SectionForceDeformation** sections = new SectionForceDeformation *[secTags.Size()]; + for(int i=0; i 0 ) { const char *sData = OPS_GetString(); - //if ( OPS_GetStringCopy(&sData) != 0 ) { - // opserr << "WARNING invalid input"; - // return 0; - //} - if ( strcmp(sData,"-mass") == 0 ) { numData = 1; if (OPS_GetDoubleInput(&numData, dData) != 0) { @@ -196,41 +201,6 @@ void * OPS_MixedBeamColumn3d() { } massDens = dData[0]; - } else if ( strcmp(sData,"-integration") == 0 ) { - const char *sData2 = OPS_GetString(); - //if ( OPS_GetStringCopy(&sData2) != 0 ) { - // opserr << "WARNING invalid input, want: -integration $intType"; - // return 0; - //} - - if (strcmp(sData2,"Lobatto") == 0) { - beamIntegr = new LobattoBeamIntegration(); - } else if (strcmp(sData2,"Legendre") == 0) { - beamIntegr = new LegendreBeamIntegration(); - } else if (strcmp(sData2,"Radau") == 0) { - beamIntegr = new RadauBeamIntegration(); - } else if (strcmp(sData2,"NewtonCotes") == 0) { - beamIntegr = new NewtonCotesBeamIntegration(); - } else if (strcmp(sData2,"Trapezoidal") == 0) { - beamIntegr = new TrapezoidalBeamIntegration(); - } else if (strcmp(sData2,"RegularizedLobatto") == 0 || strcmp(sData2,"RegLobatto") == 0) { - numData = 4; - if (OPS_GetDoubleInput(&numData, dData) != 0) { - opserr << "WARNING invalid input, want: -integration RegularizedLobatto $lpI $lpJ $zetaI $zetaJ \n"; - return 0; - } - BeamIntegration *otherBeamInt = 0; - otherBeamInt = new LobattoBeamIntegration(); - beamIntegr = new RegularizedHingeIntegration(*otherBeamInt, dData[0], dData[1], dData[2], dData[3]); - if (otherBeamInt != 0) { - delete otherBeamInt; - } - } else { - opserr << "WARNING invalid integration type, element: " << eleTag; - return 0; - } - //delete [] sData2; - } else if ( strcmp(sData,"-doRayleigh") == 0 ) { numData = 1; if (OPS_GetInt(&numData, &doRayleigh) != 0) { @@ -244,17 +214,10 @@ void * OPS_MixedBeamColumn3d() { } else { opserr << "WARNING unknown option " << sData << "\n"; } - //delete [] sData; - } - - - // Set the beam integration object if not in options - if (beamIntegr == 0) { - beamIntegr = new LobattoBeamIntegration(); } // now create the element and add it to the Domain - Element *theElement = new MixedBeamColumn3d(eleTag, nodeI, nodeJ, numIntgrPts, sections, *beamIntegr, *theTransf, massDens, doRayleigh, geomLinear); + Element *theElement = new MixedBeamColumn3d(eleTag, nodeI, nodeJ, secTags.Size(), sections, *bi, *theTransf, massDens, doRayleigh, geomLinear); if (theElement == 0) { opserr << "WARNING ran out of memory creating element with tag " << eleTag << endln; @@ -1448,7 +1411,18 @@ Response* MixedBeamColumn3d::setResponse(const char **argv, int argc, strcmp(argv[0],"numberOfSections") == 0 ) { theResponse = new ElementResponse(this, 103, Vector(1)); - } else if (strcmp(argv[0],"section") ==0) { + } + + else if (strcmp(argv[0],"xaxis") == 0 || strcmp(argv[0],"xlocal") == 0) + theResponse = new ElementResponse(this, 201, Vector(3)); + + else if (strcmp(argv[0],"yaxis") == 0 || strcmp(argv[0],"ylocal") == 0) + theResponse = new ElementResponse(this, 202, Vector(3)); + + else if (strcmp(argv[0],"zaxis") == 0 || strcmp(argv[0],"zlocal") == 0) + theResponse = new ElementResponse(this, 203, Vector(3)); + + else if (strcmp(argv[0],"section") ==0) { if (argc > 2) { int sectionNum = atoi(argv[1]); @@ -1581,9 +1555,25 @@ int MixedBeamColumn3d::getResponse(int responseID, Information &eleInfo) { tempVector(0) = numSections; return eleInfo.setVector(tempVector); - } else { - return -1; + } + else if (responseID >= 201 && responseID <= 203) { + static Vector xlocal(3); + static Vector ylocal(3); + static Vector zlocal(3); + + crdTransf->getLocalAxes(xlocal,ylocal,zlocal); + + if (responseID == 201) + return eleInfo.setVector(xlocal); + if (responseID == 202) + return eleInfo.setVector(ylocal); + if (responseID == 203) + return eleInfo.setVector(zlocal); + } + + else { + return -1; } } diff --git a/SRC/element/nonlinearBeamColumn/matrixutil/MatrixUtil.cpp b/SRC/element/nonlinearBeamColumn/matrixutil/MatrixUtil.cpp index cb668fabee..8d4749b0e9 100644 --- a/SRC/element/nonlinearBeamColumn/matrixutil/MatrixUtil.cpp +++ b/SRC/element/nonlinearBeamColumn/matrixutil/MatrixUtil.cpp @@ -138,15 +138,14 @@ void getCBDIinfluenceMatrix(int nIntegrPts, double *pts, double L, Matrix &ls) Matrix l(nIntegrPts, nIntegrPts); Matrix I(nIntegrPts,nIntegrPts); // an identity matrix for matrix inverse - for (i = 1; i <= nIntegrPts; i++) - for (j = 1; j <= nIntegrPts; j++) - { - i0 = i - 1; - j0 = j - 1; - xi = pts[i0]; - G(i0,j0) = pow(xi,j-1); - l(i0,j0) = (pow(xi,j+1)-xi)/(j*(j+1)); - } + for (i = 0; i < nIntegrPts; i++) { + xi = pts[i]; + for (j = 1; j <= nIntegrPts; j++) { + j0 = j - 1; + G(i,j0) = pow(xi,j-1); + l(i,j0) = (pow(xi,j+1)-xi)/(j*(j+1)); + } + } I.Zero(); for (i=0; i +#include + +/** \brief EICR Element Independent CoRotational formulation +* +* E.I.C.R. is a utility class containing static methods related to +* the Element Independent Corotational Formulation. +* This class implements methods that do not depend on the element type, +* and so they can be used by any implementation of a corotational coordinate transformation. +*/ +class EICR +{ + +public: + + typedef std::size_t size_t; + + typedef ASDVector3 Vector3Type; + + typedef std::vector NodeContainerType; + + typedef Vector VectorType; + + typedef Matrix MatrixType; + + typedef ASDQuaternion QuaternionType; + +public: + + /** + * Computes the Spin of the input vector V, and saves the result into the output matrix S. + * Note: no check is made on the size of the input-output arguments. + * @param V the input vector (assumed size: >= 3) + * @param S the output matrix (assumed size: >= 3x3) + */ + template< class TVec, class TMat> + inline static void Spin(const TVec& V, TMat& S) + { + S(0, 0) = 0.00; S(0, 1) = -V(2); S(0, 2) = V(1); + S(1, 0) = V(2); S(1, 1) = 0.00; S(1, 2) = -V(0); + S(2, 0) = -V(1); S(2, 1) = V(0); S(2, 2) = 0.00; + } + + /** + * Computes the Spin of the input vector V, and saves the result into the output matrix S, + * at the specified row index. + * Note: no check is made on the size of the input-output arguments. + * @param V the input vector (assumed size: >= 3) + * @param S the output matrix (assumed size: >= 3x3) + * @param row_index the index of the first row in the output matrix where the spin has to be saved + */ + template< class TVec, class TMat> + inline static void Spin_AtRow(const TVec& V, TMat& S, size_t row_index) + { + size_t i0 = row_index; + size_t i1 = 1 + row_index; + size_t i2 = 2 + row_index; + double v0 = V(i0); + double v1 = V(i1); + double v2 = V(i2); + S(i0, 0) = 0.00; S(i0, 1) = -v2; S(i0, 2) = v1; + S(i1, 0) = v2; S(i1, 1) = 0.00; S(i1, 2) = -v0; + S(i2, 0) = -v1; S(i2, 1) = v0; S(i2, 2) = 0.00; + } + + /** + * Computes the Spin of the input vector V, from the specified index, and saves the result into the output matrix S, + * at the specified row index. + * Note: no check is made on the size of the input-output arguments. + * @param V the input vector (assumed size: >= 3) + * @param S the output matrix (assumed size: >= 3x3) + * @param vector_index the index of the first component of the input vector to be used to compute the spin + * @param row_index the index of the first row in the output matrix where the spin has to be saved + */ + template< class TVec, class TMat> + inline static void Spin_AtRow(const TVec& V, TMat& S, size_t vector_index, size_t matrix_row_index) + { + size_t i0 = matrix_row_index; + size_t i1 = 1 + matrix_row_index; + size_t i2 = 2 + matrix_row_index; + double v0 = V(vector_index); + double v1 = V(vector_index + 1); + double v2 = V(vector_index + 2); + S(i0, 0) = 0.00; S(i0, 1) = -v2; S(i0, 2) = v1; + S(i1, 0) = v2; S(i1, 1) = 0.00; S(i1, 2) = -v0; + S(i2, 0) = -v1; S(i2, 1) = v0; S(i2, 2) = 0.00; + } + + /** + * Computes the Spin of the input vector V, and saves the result into the output matrix S. + * This version uses a multiplier for the output values. + * Note: no check is made on the size of the input-output arguments. + * @param V the input vector (assumed size: >= 3) + * @param S the output matrix (assumed size: >= 3x3) + * @param mult the multiplier for the output values + */ + template< class TVec, class TMat> + inline static void Spin(const TVec& V, TMat& S, double mult) + { + S(0, 0) = 0.00; S(0, 1) = -mult * V(2); S(0, 2) = mult * V(1); + S(1, 0) = mult * V(2); S(1, 1) = 0.00; S(1, 2) = -mult * V(0); + S(2, 0) = -mult * V(1); S(2, 1) = mult * V(0); S(2, 2) = 0.00; + } + + /** + * Computes the Spin of the input vector V, and saves the result into the output matrix S, + * at the specified row index. + * This version uses a multiplier for the output values. + * Note: no check is made on the size of the input-output arguments. + * @param V the input vector (assumed size: >= 3) + * @param S the output matrix (assumed size: >= 3x3) + * @param mult the multiplier for the output values + * @param row_index the index of the first row in the output matrix where the spin has to be saved + */ + template< class TVec, class TMat> + inline static void Spin_AtRow(const TVec& V, TMat& S, double mult, size_t row_index) + { + size_t i0 = row_index; + size_t i1 = 1 + row_index; + size_t i2 = 2 + row_index; + double v0 = mult * V(i0); + double v1 = mult * V(i1); + double v2 = mult * V(i2); + S(i0, 0) = 0.00; S(i0, 1) = -v2; S(i0, 2) = v1; + S(i1, 0) = v2; S(i1, 1) = 0.00; S(i1, 2) = -v0; + S(i2, 0) = -v1; S(i2, 1) = v0; S(i2, 2) = 0.00; + } + + /** + * Computes the Spin of the input vector V, from the specified index, and saves the result into the output matrix S, + * at the specified row index. + * This version uses a multiplier for the output values. + * Note: no check is made on the size of the input-output arguments. + * @param V the input vector (assumed size: >= 3) + * @param S the output matrix (assumed size: >= 3x3) + * @param mult the multiplier for the output values + * @param vector_index the index of the first component of the input vector to be used to compute the spin + * @param row_index the index of the first row in the output matrix where the spin has to be saved + */ + template< class TVec, class TMat> + inline static void Spin_AtRow(const TVec& V, TMat& S, double mult, size_t vector_index, size_t matrix_row_index) + { + size_t i0 = matrix_row_index; + size_t i1 = 1 + matrix_row_index; + size_t i2 = 2 + matrix_row_index; + double v0 = mult * V(vector_index); + double v1 = mult * V(vector_index + 1); + double v2 = mult * V(vector_index + 2); + S(i0, 0) = 0.00; S(i0, 1) = -v2; S(i0, 2) = v1; + S(i1, 0) = v2; S(i1, 1) = 0.00; S(i1, 2) = -v0; + S(i2, 0) = -v1; S(i2, 1) = v0; S(i2, 2) = 0.00; + } + + /** + * Sets the input matrix to the zero matrix of requested size. Resize is done if necessary + * @param n the number of rows + * @param n the number of columns + * @param I the input/output matrix + */ + inline static void SetZero(size_t n, size_t m, MatrixType& I) + { + if ((I.noRows() != n) || (I.noCols() != m)) + I.resize(n, m); + I.Zero(); + } + + /** + * Sets the input matrix to the identity of requested size. Resize is done if necessary + * @param n the number of rows and columns + * @param I the input/output matrix + * @param value (optional, default = 1) the value on the diagonal terms + */ + inline static void SetIdentity(size_t n, MatrixType& I, double value = 1.0) + { + SetZero(n, n, I); + for (size_t j = 0; j < n; ++j) + I(j, j) = value; + } + + /** + * Copies the block [begin:end[ from A to B. B size must be end-begin. + * Note: no size check is made! + * @param A the first vector + * @param begin the first index + * @param end the last+1 index + * @param B the second vector + */ + inline static void GetBlock(const VectorType& A, size_t begin, size_t end, VectorType& B) + { + size_t n = end - begin; + for (size_t i = 0; i < n; ++i) + B(i) = A(i + begin); + } + + /** + * Copies the block [begin:end[ from A to B. B size must be end-begin. + * Note: no size check is made! + * @param A the first matrix + * @param begin the first index + * @param end the last+1 index + * @param B the second matrix + */ + inline static void GetBlock(const MatrixType& A, size_t begin, size_t end, MatrixType& B) + { + size_t n = end - begin; + for (size_t i = 0; i < n; ++i) + for (size_t j = 0; j < n; ++j) + B(i, j) = A(i + begin, j + begin); + } + + /** + * Copies the block [begin:end[ from B to A. B size must be end-begin. + * Note: no size check is made! + * @param A the first vector + * @param begin the first index + * @param end the last+1 index + * @param B the second vector + */ + inline static void SetBlock(MatrixType& A, size_t begin, size_t end, const MatrixType& B) + { + size_t n = end - begin; + for (size_t i = 0; i < n; ++i) + for (size_t j = 0; j < n; ++j) + A(i + begin, j + begin) = B(i, j); + } + + /** + * computes the outer product A x B, in C. + * Note: no size check is made! + * @param A the first vector + * @param B the second vector + * @param C the output matrix + */ + inline static void OuterProd(const VectorType& A, const VectorType& B, MatrixType& C) + { + for (size_t i = 0; i < A.Size(); ++i) + for (size_t j = 0; j < B.Size(); ++j) + C(i, j) = A(i) * B(j); + } + +public: + + /** + * Computes the Translational Projector Matrix. + * The output is a square matrix of size num_nodes*6. + * Note that 6 Degrees Of Freedom are assumed for each node. + * @param num_nodes the number of nodes + * @param P the Translational Projector Matrix + */ + inline static void Compute_Pt(size_t num_nodes, MatrixType& P) + { + double a = double(num_nodes - 1) / double(num_nodes); + double b = -1.0 / double(num_nodes); + + size_t num_dofs = num_nodes * 6; + + SetIdentity(num_dofs, P); + + for (size_t i = 0; i < num_nodes; i++) + { + size_t j = i * 6; + + // diagonal block + P(j, j) = a; + P(j + 1, j + 1) = a; + P(j + 2, j + 2) = a; + + // out-of-diagonal block + for (size_t k = i + 1; k < num_nodes; k++) + { + size_t w = k * 6; + + P(j, w) = b; + P(j + 1, w + 1) = b; + P(j + 2, w + 2) = b; + + P(w, j) = b; + P(w + 1, j + 1) = b; + P(w + 2, j + 2) = b; + } + } + } + + /** + * Computes the Spin Lever Matrix. + * The output is a rectangular matrix of 3 columns and nodes.size()*6 rows. + * Note that 6 Degrees Of Freedom are assumed for each node. + * @param nodes the input nodes + * @param S the Spin Lever Matrix + */ + inline static void Compute_S(const NodeContainerType& nodes, MatrixType& S) + { + size_t num_nodes = nodes.size(); + size_t num_dofs = num_nodes * 6; + + SetZero(num_dofs, 3, S); + + for (size_t i = 0; i < num_nodes; i++) + { + size_t j = i * 6; + + Spin_AtRow(nodes[i], S, -1.0, 0, j); + + S(j + 3, 0) = 1.0; + S(j + 4, 1) = 1.0; + S(j + 5, 2) = 1.0; + } + } + + /** + * Computes the Axial Vector Jacobian. + * The output is a square matrix of size displacements.size() (which is num_nodes * 6). + * Note that 6 Degrees Of Freedom are assumed for each node. + * @param displacements the vector of nodal displacements and rotations in the local corotational coordinate system. (assumed size = num_nodes*6) + * @return the H matrix + */ + inline static void Compute_H(const VectorType& displacements, MatrixType& H) + { + size_t num_dofs = displacements.Size(); + size_t num_nodes = num_dofs / 6; + + SetIdentity(num_dofs, H); + + static MatrixType Omega(3, 3); + static MatrixType Omega2(3, 3); + static MatrixType Hi(3, 3); + static VectorType rv(3); + + for (size_t i = 0; i < num_nodes; i++) + { + size_t index = i * 6; + + GetBlock(displacements, index + 3, index + 6, rv); + + double angle = rv.Norm(); + + if (angle >= 2.0 * M_PI) + angle = std::fmod(angle, 2.0 * M_PI); + + double eta; + if (angle < 0.05) { + double angle2 = angle * angle; + double angle4 = angle2 * angle2; + double angle6 = angle4 * angle2; + eta = 1.0 / 12.0 + 1.0 / 270.0 * angle2 + 1.0 / 30240.0 * angle4 + 1.0 / 1209600.0 * angle6; + } + else { + eta = (1.0 - 0.5 * angle * std::tan(0.5 * M_PI - 0.5 * angle)) / (angle * angle); + } + + Spin(rv, Omega); + Omega2.addMatrixProduct(0.0, Omega, Omega, 1.0); + + // Hi = I - 0.5*Omega + eta*Omega*Omega + SetIdentity(3, Hi); + Hi.addMatrix(1.0, Omega, -0.5); + Hi.addMatrix(1.0, Omega2, eta); + + SetBlock(H, index + 3, index + 6, Hi); + } + } + + /** + * Computes the Spin derivative of (Axial Vector Jacobian)^T contracted with the nodal moment vector. + * The output is a square matrix of size displacements.size() (which is num_nodes * 6). + * Note that 6 Degrees Of Freedom are assumed for each node. + * @param displacements the vector of nodal displacements and rotations in the local corotational coordinate system. (assumed size = num_nodes*6) + * @param forces the vector of nodal forces and moments in the local corotational coordinate system. (assumed size = num_nodes*6) + * @param H the Axial Vector Jacobian Matrix computed with a previous call to EICR::Compute_H(displacements) + * @return the L matrix + */ + inline static void Compute_L(const VectorType& displacements, const VectorType& forces, const MatrixType& H, MatrixType& L) + { + size_t num_dofs = displacements.Size(); + size_t num_nodes = num_dofs / 6; + + SetZero(num_dofs, num_dofs, L); + + static VectorType rotationVector(3); + static VectorType momentVector(3); + static MatrixType Omega(3, 3); + static MatrixType Omega2(3, 3); + static MatrixType Li(3, 3); + static MatrixType LiTemp1(3, 3); + static MatrixType MxR(3, 3); + static MatrixType RxM(3, 3); + static MatrixType Hi(3, 3); + + for (size_t i = 0; i < num_nodes; i++) + { + size_t index = i * 6; + + GetBlock(displacements, index + 3, index + 6, rotationVector); + GetBlock(forces, index + 3, index + 6, momentVector); + + double angle = rotationVector.Norm(); + + if (angle >= 2.0 * M_PI) + angle = std::fmod(angle, 2.0 * M_PI); + + double angle2 = angle * angle; + double angle4 = angle2 * angle2; + double angle6 = angle4 * angle2; + + double eta; + double mu; + if (angle < 0.05) { + eta = 1.0 / 12.0 + angle2 / 270.0 + angle4 / 30240.0 + angle6 / 1209600.0; + mu = 1.0 / 360.0 + angle2 / 7560.0 + angle4 / 201600.0 + angle6 / 5987520.0; + } + else { + eta = (1.0 - 0.5 * angle * std::tan(0.5 * M_PI - 0.5 * angle)) / (angle * angle); + double sin_h_angle = std::sin(0.5 * angle); + mu = (angle2 + 4.0 * std::cos(angle) + angle * std::sin(angle) - 4.0) / (4.0 * angle4 * sin_h_angle * sin_h_angle); + } + + Spin(rotationVector, Omega); + Omega2.addMatrixProduct(0.0, Omega, Omega, 1.0); + + OuterProd(momentVector, rotationVector, MxR); + OuterProd(rotationVector, momentVector, RxM); + + SetIdentity(3, Li, (rotationVector ^ momentVector)); + Li.addMatrix(1.0, RxM, 1.0); + Li.addMatrix(1.0, MxR, -1.0); + + LiTemp1.addMatrixProduct(0.0, Omega2, MxR, mu); + Spin(momentVector, MxR, 0.5); + LiTemp1.addMatrix(1.0, MxR, -1.0); + + LiTemp1.addMatrix(1.0, Li, eta); + + GetBlock(H, index + 3, index + 6, Hi); + Li.addMatrixProduct(0.0, LiTemp1, Hi, 1.0); + + SetBlock(L, index + 3, index + 6, Li); + } + } + + +}; + +#endif // !ASDEICR_h diff --git a/SRC/element/shell/ASDMath.h b/SRC/element/shell/ASDMath.h new file mode 100644 index 0000000000..62b4ad07d8 --- /dev/null +++ b/SRC/element/shell/ASDMath.h @@ -0,0 +1,775 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.10 $ +// $Date: 2020/05/18 22:51:21 $ + +// Original implementation: Massimo Petracca (ASDEA) +// +// Implementation of a Quaternion for compact and robust representation +// of spatial rotations +// + +#ifndef ASDMath_h +#define ASDMath_h + +#include +#include +#include +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.1415926535897932384626433832795 +#endif // M_PI + +/** \brief ASDQuaternion +* A simple fixed size 3D vector +*/ +template +class ASDVector3 +{ +public: + + /** + Creates a Zero ASDVector3. + */ + ASDVector3() + { + mData[0] = mData[1] = mData[2] = 0.0; + } + + /** + Creates a ASDVector3 from its coefficients. + @param x x coefficient + @param y y coefficient + @param z z coefficient + */ + ASDVector3(T x, T y, T z) + { + mData[0] = x; + mData[1] = y; + mData[2] = z; + } + + /** + Creates a ASDVector3 from a Vector starting from index. + Note: no check is made on the input data size! + @param v the vector + @param index the index (optional, default = 0) + */ + ASDVector3(const Vector& v, size_t index = 0) + { + mData[0] = v(0 + index); + mData[1] = v(1 + index); + mData[2] = v(2 + index); + } + + /** + Creates a ASDVector3 from another ASDVector3. + @param other the other ASDVector3 + */ + ASDVector3(const ASDVector3& other) + { + mData[0] = other.mData[0]; + mData[1] = other.mData[1]; + mData[2] = other.mData[2]; + } + +public: + + /** + Copies a ASDVector3. + @param other the other ASDVector3 + */ + ASDVector3& operator= (const ASDVector3& other) + { + if (this != &other) { + mData[0] = other.mData[0]; + mData[1] = other.mData[1]; + mData[2] = other.mData[2]; + } + return *this; + } + +public: + + /** + Returns the X coefficient of this vector. + @return the X coefficient of this vector. + */ + inline const T x()const { return mData[0]; } + + /** + Returns the Y coefficient of this vector. + @return the Y coefficient of this vector. + */ + inline const T y()const { return mData[1]; } + + /** + Returns the Z coefficient of this vector. + @return the Z coefficient of this vector. + */ + inline const T z()const { return mData[2]; } + + /** + Returns the i-th coefficient of this vector. + @return the i-th coefficient of this vector. + */ + inline T operator()(size_t i) const { return mData[i]; } + + /** + Returns the i-th coefficient of this vector. + @return the i-th coefficient of this vector. + */ + inline T& operator()(size_t i) { return mData[i]; } + + /** + Returns the i-th coefficient of this vector. + @return the i-th coefficient of this vector. + */ + inline T operator[](size_t i) const { return mData[i]; } + + /** + Returns the i-th coefficient of this vector. + @return the i-th coefficient of this vector. + */ + inline T& operator[](size_t i) { return mData[i]; } + +public: + + /** + Returns the squared norm this vector. + @return the squared norm of this vector. + */ + inline T squaredNorm() const + { + return + mData[0] * mData[0] + + mData[1] * mData[1] + + mData[2] * mData[2]; + } + + /** + Returns the norm this vector. + @return the norm of this vector. + */ + inline T norm() const + { + return std::sqrt(squaredNorm()); + } + + /** + makes this vector a unit vector. + @return the norm of this vector. + */ + inline T normalize() + { + T n = norm(); + if (n > 0.0) { + mData[0] /= n; + mData[1] /= n; + mData[2] /= n; + } + return n; + } + + /** + Returns the dot product this vector with another vector. + @param b the other vector + @return the dot product. + */ + inline T dot(const ASDVector3& b) const + { + return + mData[0] * b.mData[0] + + mData[1] * b.mData[1] + + mData[2] * b.mData[2]; + } + + /** + Returns the cross product this vector with another vector. + @param b the other vector + @return the cross product. + */ + inline ASDVector3 cross(const ASDVector3& b) const + { + ASDVector3 c; + c.mData[0] = mData[1] * b.mData[2] - mData[2] * b.mData[1]; + c.mData[1] = mData[2] * b.mData[0] - mData[0] * b.mData[2]; + c.mData[2] = mData[0] * b.mData[1] - mData[1] * b.mData[0]; + return c; + } + +public: + + inline void operator += (const ASDVector3& b) + { + mData[0] += b.mData[0]; + mData[1] += b.mData[1]; + mData[2] += b.mData[2]; + } + + inline ASDVector3 operator + (const ASDVector3& b) const + { + ASDVector3 a(*this); + a += b; + return a; + } + + inline void operator -= (const ASDVector3& b) + { + mData[0] -= b.mData[0]; + mData[1] -= b.mData[1]; + mData[2] -= b.mData[2]; + } + + inline ASDVector3 operator - (const ASDVector3& b) const + { + ASDVector3 a(*this); + a -= b; + return a; + } + + inline void operator *= (T b) + { + mData[0] *= b; + mData[1] *= b; + mData[2] *= b; + } + + inline ASDVector3 operator * (T b) const + { + ASDVector3 a(*this); + a *= b; + return a; + } + + inline void operator /= (T b) + { + mData[0] /= b; + mData[1] /= b; + mData[2] /= b; + } + + inline ASDVector3 operator / (T b) const + { + ASDVector3 a(*this); + a /= b; + return a; + } + +private: + T mData[3]; +}; + +template +inline ASDVector3 operator * (T a, const ASDVector3& b) +{ + return b * a; +} + +/** +Prints this vector to a input stream +@param s the output stream +@param v the vector +@return the stream +*/ +template +inline TStream& operator << (TStream& s, const ASDVector3& v) +{ + return (s << "(" << v.x() << ", " << v.y() << ", " << v.z() << ")"); +} + +/** \brief ASDQuaternion +* A simple class that implements the main features of quaternion algebra +*/ +template +class ASDQuaternion +{ + +public: + + /** + Creates a Zero ASDQuaternion. + */ + ASDQuaternion() + : mX(0.0) + , mY(0.0) + , mZ(0.0) + , mW(0.0) + { + } + + /** + Creates a ASDQuaternion from its coefficients. + @param w w coefficient + @param x x coefficient + @param y y coefficient + @param z z coefficient + */ + ASDQuaternion(T w, T x, T y, T z) + : mX(x) + , mY(y) + , mZ(z) + , mW(w) + { + } + + /** + Creates a ASDQuaternion from another ASDQuaternion. + @param other the other ASDQuaternion + */ + ASDQuaternion(const ASDQuaternion& other) + : mX(other.mX) + , mY(other.mY) + , mZ(other.mZ) + , mW(other.mW) + { + } + +public: + + /** + Copies a ASDQuaternion. + @param other the other ASDQuaternion + */ + ASDQuaternion& operator= (const ASDQuaternion& other) + { + if (this != &other) { + mX = other.mX; + mY = other.mY; + mZ = other.mZ; + mW = other.mW; + } + return *this; + } + +public: + + /** + Returns the X coefficient of this quaternion. + @return the X coefficient of this quaternion. + */ + inline const T x()const { return mX; } + + /** + Returns the Y coefficient of this quaternion. + @return the Y coefficient of this quaternion. + */ + inline const T y()const { return mY; } + + /** + Returns the Z coefficient of this quaternion. + @return the Z coefficient of this quaternion. + */ + inline const T z()const { return mZ; } + + /** + Returns the W coefficient of this quaternion. + @return the W coefficient of this quaternion. + */ + inline const T w()const { return mW; } + +public: + + /** + Returns the squared norm of this quaternion. + x*x + y*y + z*z + w*w + @return the squared norm of this quaternion. + */ + inline const T squaredNorm()const + { + return mX * mX + mY * mY + mZ * mZ + mW * mW; + } + + /** + Returns the norm of this quaternion. + sqrt(x*x + y*y + z*z + w*w) + @return the norm of this quaternion. + */ + inline const T norm()const + { + return std::sqrt(squaredNorm()); + } + + /** + Makes this ASDQuaternion a Unit ASDQuaternion. + If this ASDQuaternion is already normalized this is a no-op + */ + inline void normalize() + { + T n = squaredNorm(); + if (n > 0.0 && n != 1.0) { + n = std::sqrt(n); + mX /= n; + mY /= n; + mZ /= n; + mW /= n; + } + } + + /** + Returns the Conjugate of this ASDQuaternion, which represents the opposite rotation + @return the Conjugate of this ASDQuaternion + */ + inline ASDQuaternion conjugate()const + { + return ASDQuaternion(mW, -mX, -mY, -mZ); + } + + /** + Constructs a Rotation Matrix from this ASDQuaternion. + The rotation matrix type is the template argument, no check is made on the type of + this matrix. + These assumptions are made: + The matrix should provide an indexed access like m(i, j) where i and j are indices + from 0 to 2. + This means that the input matrix is a C-Style 3x3 Matrix. + All the 9 coefficients are properly set so there's no need to set the matrix to Zero + before calling this function. + @param R the output rotation matrix + */ + template + inline void toRotationMatrix(TMatrix3x3& R)const + { + R(0, 0) = 2.0 * (mW * mW + mX * mX - 0.5); + R(0, 1) = 2.0 * (mX * mY - mW * mZ); + R(0, 2) = 2.0 * (mX * mZ + mW * mY); + + R(1, 0) = 2.0 * (mY * mX + mW * mZ); + R(1, 1) = 2.0 * (mW * mW + mY * mY - 0.5); + R(1, 2) = 2.0 * (mY * mZ - mX * mW); + + R(2, 0) = 2.0 * (mZ * mX - mW * mY); + R(2, 1) = 2.0 * (mZ * mY + mW * mX); + R(2, 2) = 2.0 * (mW * mW + mZ * mZ - 0.5); + } + + /** + Extracts the Rotation Vector from this ASDQuaternion + @param rx the output x component if the rotation vector + @param ry the output y component if the rotation vector + @param rz the output z component if the rotation vector + */ + inline void toRotationVector(T& rx, T& ry, T& rz)const + { + T xx, yy, zz, ww; + + if (mW < 0.0) { + xx = -mX; + yy = -mY; + zz = -mZ; + ww = -mW; + } + else { + xx = mX; + yy = mY; + zz = mZ; + ww = mW; + } + + T vNorm = xx * xx + yy * yy + zz * zz; + if (vNorm == 0.0) { + rx = 0.0; + ry = 0.0; + rz = 0.0; + return; + } + + if (vNorm != 1.0) + vNorm = std::sqrt(vNorm); + + T mult = (vNorm < ww) ? (2.0 / vNorm * std::asin(vNorm)) : (2.0 / vNorm * std::acos(ww)); + + rx = xx * mult; + ry = yy * mult; + rz = zz * mult; + } + + /** + Extracts the Rotation Vector from this ASDQuaternion + The vector type is the template parameter. No check is made on this type. + The following assumptions are made: + The vector type should provide indexing like vector(i) where i goes from 0 to 2. + (i.e. a C-Style vector of size 3) + @param v the output rotation vector + */ + template + inline void toRotationVector(TVector3& v)const + { + toRotationVector(v(0), v(1), v(2)); + } + + /** + Rotates a vector using this quaternion. + Note: this is faster than constructing the rotation matrix and perform the matrix + multiplication for a single vector. + The vector type is the template parameter. No check is made on this type. + The following assumptions are made: + The vector type should provide indexing like vector(i) where i goes from 0 to 2. + (i.e. a C-Style vector of size 3) + @param a the input source vector + @param b the output rotated vector + */ + template + inline void rotateVector(const TVector3_A& a, TVector3_B& b)const + { + // b = 2.0 * cross( this->VectorialPart, a ) + b(0) = 2.0 * (mY * a(2) - mZ * a(1)); + b(1) = 2.0 * (mZ * a(0) - mX * a(2)); + b(2) = 2.0 * (mX * a(1) - mY * a(0)); + + // c = cross( this->VectorialPart, b ) + T c0 = mY * b(2) - mZ * b(1); + T c1 = mZ * b(0) - mX * b(2); + T c2 = mX * b(1) - mY * b(0); + + // set results + b(0) = a(0) + b(0) * mW + c0; + b(1) = a(1) + b(1) * mW + c1; + b(2) = a(2) + b(2) * mW + c2; + } + + /** + Rotates a vector using this quaternion. + Note: this is faster than constructing the rotation matrix and perform the matrix + multiplication for a single vector. + The vector type is the template parameter. No check is made on this type. + The following assumptions are made: + The vector type should provide indexing like vector(i) where i goes from 0 to 2. + (i.e. a C-Style vector of size 3) + @param a the input source vector - rotated on exit + */ + template + inline void rotateVector(TVector3& a)const + { + // b = 2.0 * cross( this->VectorialPart, a ) + T b0 = 2.0 * (mY * a(2) - mZ * a(1)); + T b1 = 2.0 * (mZ * a(0) - mX * a(2)); + T b2 = 2.0 * (mX * a(1) - mY * a(0)); + + // c = cross( this->VectorialPart, b ) + T c0 = mY * b2 - mZ * b1; + T c1 = mZ * b0 - mX * b2; + T c2 = mX * b1 - mY * b0; + + // set results + a(0) += b0 * mW + c0; + a(1) += b1 * mW + c1; + a(2) += b2 * mW + c2; + } + +public: + + /** + Returns the Identity ASDQuaternion (i.e. a ASDQuaternion that represents a Zero rotation) + @return the Identity ASDQuaternion + */ + static inline ASDQuaternion Identity() + { + return ASDQuaternion(1.0, 0.0, 0.0, 0.0); + } + + /** + Returns a ASDQuaternion that represents a rotation of an angle 'radians' around the axis (x, y, z) + @param x the x component of the rotation axis + @param y the y component of the rotation axis + @param z the z component of the rotation axis + @param radians the rotation angle in radians + @return a ASDQuaternion that represents a rotation of an angle 'radians' around the axis (x, y, z) + */ + static inline ASDQuaternion FromAxisAngle(T x, T y, T z, T radians) + { + T sqnorm = x * x + y * y + z * z; + if (sqnorm == 0.0) + return ASDQuaternion::Identity(); + + if (sqnorm > 0.0 && sqnorm != 1.0) { + T norm = std::sqrt(sqnorm); + x /= norm; + y /= norm; + z /= norm; + } + + T halfAngle = radians * 0.5; + + T s = std::sin(halfAngle); + T q0 = std::cos(halfAngle); + + ASDQuaternion result(q0, s * x, s * y, s * z); + result.normalize(); + + return result; + } + + /** + Returns a ASDQuaternion from a rotation vector + @param rx the x component of the source rotation vector + @param ry the y component of the source rotation vector + @param rz the z component of the source rotation vector + @return a ASDQuaternion from a rotation vector + */ + static inline ASDQuaternion FromRotationVector(T rx, T ry, T rz) + { + T rModulus = rx * rx + ry * ry + rz * rz; + if (rModulus == 0.0) + return ASDQuaternion::Identity(); + + if (rModulus != 1.0) { + rModulus = std::sqrt(rModulus); + rx /= rModulus; + ry /= rModulus; + rz /= rModulus; + } + + T halfAngle = rModulus * 0.5; + + T q0 = std::cos(halfAngle); + T s = std::sin(halfAngle); + + ASDQuaternion result(q0, rx * s, ry * s, rz * s); + result.normalize(); + + return result; + } + + /** + Returns a ASDQuaternion from a rotation vector. + The vector type is the template parameter. No check is made on this type. + The following assumptions are made: + The vector type should provide indexing like vector(i) where i goes from 0 to 2. + (i.e. a C-Style vector of size 3) + @param v the source rotation vector + @return a ASDQuaternion from a rotation vector + */ + template + static inline ASDQuaternion FromRotationVector(const TVector3& v) + { + return ASDQuaternion::FromRotationVector(v(0), v(1), v(2)); + } + + /** + Returns a ASDQuaternion from a Rotation Matrix. + The rotation matrix type is the template argument, no check is made on the type of + this matrix. + These assumptions are made: + The matrix should provide an indexed access like m(i, j) where i and j are indices + from 0 to 2. + This means that the input matrix is a C-Style 3x3 Matrix. + @param m the source rotation matrix + @return a ASDQuaternion from a Rotation Matrix + */ + template + static inline ASDQuaternion FromRotationMatrix(const TMatrix3x3& m) + { + T xx = m(0, 0); + T yy = m(1, 1); + T zz = m(2, 2); + T tr = xx + yy + zz; + ASDQuaternion Q; + if ((tr > xx) && (tr > yy) && (tr > zz)) + { + T S = std::sqrt(tr + 1.0) * 2.0; + Q = ASDQuaternion( + 0.25 * S, + (m(2, 1) - m(1, 2)) / S, + (m(0, 2) - m(2, 0)) / S, + (m(1, 0) - m(0, 1)) / S + ); + } + else if ((xx > yy) && (xx > zz)) + { + T S = std::sqrt(1.0 + xx - yy - zz) * 2.0; + Q = ASDQuaternion( + (m(2, 1) - m(1, 2)) / S, + 0.25 * S, + (m(0, 1) + m(1, 0)) / S, + (m(0, 2) + m(2, 0)) / S + ); + } + else if (yy > zz) + { + T S = std::sqrt(1.0 + yy - xx - zz) * 2.0; + Q = ASDQuaternion( + (m(0, 2) - m(2, 0)) / S, + (m(0, 1) + m(1, 0)) / S, + 0.25 * S, + (m(1, 2) + m(2, 1)) / S + ); + } + else + { + T S = std::sqrt(1.0 + zz - xx - yy) * 2.0; + Q = ASDQuaternion( + (m(1, 0) - m(0, 1)) / S, + (m(0, 2) + m(2, 0)) / S, + (m(1, 2) + m(2, 1)) / S, + 0.25 * S + ); + } + + + Q.normalize(); + return Q; + } + +private: + T mX; + T mY; + T mZ; + T mW; + +}; + +/** +Performs a ASDQuaternion-ASDQuaternion product and returns the concatenation +of the two input quaternions (i.e. the compound rotation) +@param a the first quaternion +@param b the second quaternion +@return the compound quaternion +*/ +template +inline ASDQuaternion operator* (const ASDQuaternion& a, const ASDQuaternion& b) +{ + return ASDQuaternion( + a.w() * b.w() - a.x() * b.x() - a.y() * b.y() - a.z() * b.z(), + a.w() * b.x() + a.x() * b.w() + a.y() * b.z() - a.z() * b.y(), + a.w() * b.y() + a.y() * b.w() + a.z() * b.x() - a.x() * b.z(), + a.w() * b.z() + a.z() * b.w() + a.x() * b.y() - a.y() * b.x() + ); +} + +/** +Prints this quaternion to a input stream +@param s the output stream +@param q the quaternion +@return the stream +*/ +template +inline TStream& operator << (TStream& s, const ASDQuaternion& q) +{ + return (s << "[(" << q.x() << ", " << q.y() << ", " << q.z() << "), " << q.w() << "]"); +} + +#endif // !ASDMath_h + + diff --git a/SRC/element/shell/ASDShellQ4.cpp b/SRC/element/shell/ASDShellQ4.cpp new file mode 100644 index 0000000000..6609ea8835 --- /dev/null +++ b/SRC/element/shell/ASDShellQ4.cpp @@ -0,0 +1,1646 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.10 $ +// $Date: 2020/05/18 22:51:21 $ + +// Original implementation: Massimo Petracca (ASDEA) +// +// A 4-node general shell element based on the AGQ formulation +// for the in-plane behavior, +// and the MITC4 formulation for the out-of-plane behavior. +// +// It supports both linear and corotational kinematics. Warped geometries +// can be modelled since this element is not assumed flat. +// + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +void * +OPS_ASDShellQ4(void) +{ + static bool first_done = false; + if (!first_done) { + opserr << "Using ASDShellQ4 - Developed by: Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; + first_done = true; + } + + int numArgs = OPS_GetNumRemainingInputArgs(); + if (numArgs < 6) { + opserr << "Want: element ASDShellQ4 $tag $iNode $jNoe $kNode $lNode $secTag <-corotational>"; + return 0; + } + + int iData[6]; + int numData = 6; + if (OPS_GetInt(&numData, iData) != 0) { + opserr << "WARNING invalid integer tag: element ASDShellQ4 \n"; + return 0; + } + bool corotational = false; + + if (numArgs == 7) { + const char* type = OPS_GetString(); + if ((strcmp(type, "-corotational") == 0) || (strcmp(type, "-Corotational") == 0)) + corotational = true; + } + + SectionForceDeformation* section = OPS_getSectionForceDeformation(iData[5]); + + if (section == 0) { + opserr << "ERROR: element ASDShellQ4 " << iData[0] << "section " << iData[5] << " not found\n"; + return 0; + } + + return new ASDShellQ4(iData[0], iData[1], iData[2], iData[3], iData[4], section, corotational); +} + +// anonymous namespace for utilities +namespace +{ + // some typedefs + typedef ASDVector3 Vector3Type; + + // calculation options + constexpr int OPT_NONE = 0; + constexpr int OPT_UPDATE = (1 << 0); + constexpr int OPT_LHS = (1 << 1); + constexpr int OPT_RHS = (1 << 2); + constexpr int OPT_LHS_IS_INITIAL = (1 << 3); + + // gauss quadrature data + constexpr double GLOC = 0.577350269189626; + constexpr std::array XI = { -GLOC, GLOC, GLOC, -GLOC }; + constexpr std::array ETA = { -GLOC, -GLOC, GLOC, GLOC }; + constexpr std::array WTS = { 1.0, 1.0, 1.0, 1.0 }; + + // shape functions + inline void shapeFunctions(double xi, double eta, Vector& N) + { + N(0) = 0.25 * (1.0 - xi) * (1.0 - eta); + N(1) = 0.25 * (1.0 + xi) * (1.0 - eta); + N(2) = 0.25 * (1.0 + xi) * (1.0 + eta); + N(3) = 0.25 * (1.0 - xi) * (1.0 + eta); + } + + // shape function derivatives in iso-parametric space + inline void shapeFunctionsNaturalDerivatives(double xi, double eta, Matrix& dN) + { + dN(0, 0) = -(1.0 - eta) * 0.25; + dN(1, 0) = (1.0 - eta) * 0.25; + dN(2, 0) = (1.0 + eta) * 0.25; + dN(3, 0) = -(1.0 + eta) * 0.25; + + dN(0, 1) = -(1.0 - xi) * 0.25; + dN(1, 1) = -(1.0 + xi) * 0.25; + dN(2, 1) = (1.0 + xi) * 0.25; + dN(3, 1) = (1.0 - xi) * 0.25; + } + + /** \brief JacobianOperator + * + * This class is a utility to compute at a given integration point, + * the Jacobian, its inverse, its determinant + * and the derivatives of the shape functions in the local + * cartesian coordinate system. + */ + struct JacobianOperator + { + // Jacobian matrix + Matrix J = Matrix(2, 2); + // Jacobian inverse + Matrix invJ = Matrix(2, 2); + // Determinant of the Jacobian matrix + double detJ = 0.0; + + void calculate(const ASDShellQ4LocalCoordinateSystem& CS, const Matrix& dN) + { + // jacobian + J(0, 0) = dN(0, 0) * CS.X1() + dN(1, 0) * CS.X2() + dN(2, 0) * CS.X3() + dN(3, 0) * CS.X4(); + J(1, 0) = dN(0, 0) * CS.Y1() + dN(1, 0) * CS.Y2() + dN(2, 0) * CS.Y3() + dN(3, 0) * CS.Y4(); + J(0, 1) = dN(0, 1) * CS.X1() + dN(1, 1) * CS.X2() + dN(2, 1) * CS.X3() + dN(3, 1) * CS.X4(); + J(1, 1) = dN(0, 1) * CS.Y1() + dN(1, 1) * CS.Y2() + dN(2, 1) * CS.Y3() + dN(3, 1) * CS.Y4(); + + // determinant + detJ = J(0, 0) * J(1, 1) - J(1, 0) * J(0, 1); + double mult = 1.0 / detJ; + + // inv(jacobian) + invJ(0, 0) = J(1, 1) * mult; + invJ(1, 1) = J(0, 0) * mult; + invJ(0, 1) = -J(0, 1) * mult; + invJ(1, 0) = -J(1, 0) * mult; + } + + }; + + /** \brief MITC4Params + * + * This class performs some operations and stores some data to compute + * the transverse shear contribution of the stiffness matrix using the + * M.I.T.C. formulation. + * + */ + struct MITC4Params + { + double Ax = 0.0; + double Ay = 0.0; + double Bx = 0.0; + double By = 0.0; + double Cx = 0.0; + double Cy = 0.0; + Matrix transformation = Matrix(2, 2); + Matrix shearStrains = Matrix(4, 24); + + void compute(const ASDShellQ4LocalCoordinateSystem& LCS) + { + double x21 = LCS.X2() - LCS.X1(); + double y21 = LCS.Y2() - LCS.Y1(); + double x34 = LCS.X3() - LCS.X4(); + double y34 = LCS.Y3() - LCS.Y4(); + double x41 = LCS.X4() - LCS.X1(); + double y41 = LCS.Y4() - LCS.Y1(); + double x32 = LCS.X3() - LCS.X2(); + double y32 = LCS.Y3() - LCS.Y2(); + + Ax = -LCS.X1() + LCS.X2() + LCS.X3() - LCS.X4(); + Bx = LCS.X1() - LCS.X2() + LCS.X3() - LCS.X4(); + Cx = -LCS.X1() - LCS.X2() + LCS.X3() + LCS.X4(); + Ay = -LCS.Y1() + LCS.Y2() + LCS.Y3() - LCS.Y4(); + By = LCS.Y1() - LCS.Y2() + LCS.Y3() - LCS.Y4(); + Cy = -LCS.Y1() - LCS.Y2() + LCS.Y3() + LCS.Y4(); + + double Alpha = std::atan(Ay / Ax); + double Beta = 3.141592653589793 * 0.5 - std::atan(Cx / Cy); + + transformation(0, 0) = std::sin(Beta); + transformation(0, 1) = -std::sin(Alpha); + transformation(1, 0) = -std::cos(Beta); + transformation(1, 1) = std::cos(Alpha); + + shearStrains.Zero(); + + shearStrains(0, 2) = -0.5; + shearStrains(0, 3) = -y41 * 0.25; + shearStrains(0, 4) = x41 * 0.25; + + shearStrains(0, 20) = 0.5; + shearStrains(0, 21) = -y41 * 0.25; + shearStrains(0, 22) = x41 * 0.25; + + shearStrains(1, 2) = -0.5; + shearStrains(1, 3) = -y21 * 0.25; + shearStrains(1, 4) = x21 * 0.25; + + shearStrains(1, 8) = 0.5; + shearStrains(1, 9) = -y21 * 0.25; + shearStrains(1, 10) = x21 * 0.25; + + shearStrains(2, 8) = -0.5; + shearStrains(2, 9) = -y32 * 0.25; + shearStrains(2, 10) = x32 * 0.25; + + shearStrains(2, 14) = 0.5; + shearStrains(2, 15) = -y32 * 0.25; + shearStrains(2, 16) = x32 * 0.25; + + shearStrains(3, 14) = 0.5; + shearStrains(3, 15) = -y34 * 0.25; + shearStrains(3, 16) = x34 * 0.25; + + shearStrains(3, 20) = -0.5; + shearStrains(3, 21) = -y34 * 0.25; + shearStrains(3, 22) = x34 * 0.25; + } + + }; + + /** \brief AGQIParams + * + * This class performs some operations and stores some data to compute + * the AGQI enhancement of the membrane part + * + */ + struct AGQIParams + { + std::array X = { {0.0, 0.0, 0.0, 0.0} }; + std::array Y = { {0.0, 0.0, 0.0, 0.0} }; + std::array b = { {0.0, 0.0, 0.0, 0.0} }; + std::array c = { {0.0, 0.0, 0.0, 0.0} }; + double A1 = 0.0; + double A2 = 0.0; + double A3 = 0.0; + double A = 0.0; + std::array g = { {0.0, 0.0, 0.0, 0.0} }; + + void compute(const ASDShellQ4LocalCoordinateSystem& LCS) + { + // extract the x and y coordinates + // and compute bi = yj-yk, and ci = xk-xj + // Eq 3 + for (int i = 0; i < 4; i++) { + X[i] = LCS.X(i); + Y[i] = LCS.Y(i); + } + for (int i = 0; i < 4; i++) { + int j = i + 1; if (j > 3) j = 0; + int k = j + 1; if (k > 3) k = 0; + b[i] = Y[j] - Y[k]; + c[i] = X[k] - X[j]; + } + + // areas of sub-triangles + A1 = 0.5 * (X[1] * Y[3] + X[0] * Y[1] + X[3] * Y[0] - X[1] * Y[0] - X[3] * Y[1] - X[0] * Y[3]); + A2 = 0.5 * (X[1] * Y[2] + X[0] * Y[1] + X[2] * Y[0] - X[1] * Y[0] - X[2] * Y[1] - X[0] * Y[2]); + A3 = 0.5 * (X[2] * Y[3] + X[1] * Y[2] + X[3] * Y[1] - X[2] * Y[1] - X[3] * Y[2] - X[1] * Y[3]); + A = A1 + A3; + // characteristic parameters of a quadrilateral + // Eq 4 + g[0] = A1 / A; g[1] = A2 / A; g[2] = 1.0 - g[0]; g[3] = 1.0 - g[1]; + } + + }; + + /** \brief ASDShellQ4Globals + * + * This singleton class stores some data for the shell calculations that + * can be statically instanciated to avoid useless re-allocations + * + */ + class ASDShellQ4Globals + { + private: + ASDShellQ4Globals() = default; + + public: + + JacobianOperator jac; // Jacobian + MITC4Params mitc; // MITC4 parameters + AGQIParams agq; // GQ12 parameters + + Vector UG = Vector(24); // global displacements + Vector UL = Vector(24); // local displacements + + Matrix B = Matrix(8, 24); // strain-displacement matrix + Matrix B1 = Matrix(8, 24); // strain-displacement matrix with inverted bending terms + Matrix B1TD = Matrix(24, 8); // holds the B1^T*D terms + Vector Bd = Vector(24); // strain-displacement matrix for drilling + Vector Bd0 = Vector(24); // strain-displacement matrix for drilling (reduced integration) + Vector N = Vector(4); // shape functions + Matrix dN = Matrix(4, 2); // shape functions derivatives in isoparametric space + Matrix dNdX = Matrix(4, 2); // shape functions derivatives in cartesian space + Vector E = Vector(8); // strain vector + Vector S = Vector(8); // stress vector + Vector Elocal = Vector(8); // strain vector in local element coordinate system + Matrix Re = Matrix(8, 8); // rotation matrix for strains + Matrix Rs = Matrix(8, 8); // rotation matrix for stresses + Matrix RsT = Matrix(8, 8); // transpose of above + Matrix D = Matrix(8, 8); // section tangent + Matrix DRsT = Matrix(8, 8); // holds the product D * Rs^T + + Matrix BQ = Matrix(8, 4); // B matrix for internal DOFs + Matrix BQ_mean = Matrix(8, 4); // Average B matrix for internal DOFs + Matrix BQTD = Matrix(4, 8); // holds the BQ^T*D terms + Matrix DBQ = Matrix(8, 4); // holds the D*BQ^T terms + + Matrix LHS = Matrix(24, 24); // LHS matrix (tangent stiffness) + Matrix LHS_initial = Matrix(24, 24); // LHS matrix (initial stiffness) + Matrix LHS_mass = Matrix(24, 24); // LHS matrix (mass matrix) + Vector RHS = Vector(24); // RHS vector (residual vector) + Vector RHS_winertia = Vector(24); // RHS vector (residual vector with inertia terms) + + public: + static ASDShellQ4Globals& instance() { + static ASDShellQ4Globals _instance; + return _instance; + } + }; + + // computes only the drilling B matrix + void computeBdrilling( + const ASDShellQ4LocalCoordinateSystem& LCS, + double xi, double eta, + const JacobianOperator& Jac, + const AGQIParams& agq, + const Vector& N, + const Matrix& dN, + Vector& Bd + ) + { + // cartesian derivatives of standard shape function + auto& dNdX = ASDShellQ4Globals::instance().dNdX; + dNdX.addMatrixProduct(0.0, dN, Jac.invJ, 1.0); + + // initialize + Bd.Zero(); + + // AGQI proc *********************************************************************************************** + + // area coordinates of the gauss point (Eq 7) + std::array L; + L[0] = 0.25 * (1.0 - xi) * (agq.g[1] * (1.0 - eta) + agq.g[2] * (1.0 + eta)); + L[1] = 0.25 * (1.0 - eta) * (agq.g[3] * (1.0 - xi) + agq.g[2] * (1.0 + xi)); + L[2] = 0.25 * (1.0 + xi) * (agq.g[0] * (1.0 - eta) + agq.g[3] * (1.0 + eta)); + L[3] = 0.25 * (1.0 + eta) * (agq.g[0] * (1.0 - xi) + agq.g[1] * (1.0 + xi)); + + // computed modified shape function gradients for the strain matrix for external dofs + // using the area coordinate method as written in the reference paper of the AGQI element + static constexpr std::array NXI = { -1.0, 1.0, 1.0, -1.0 }; + static constexpr std::array NETA = { -1.0, -1.0, 1.0, 1.0 }; + for (int i = 0; i < 4; i++) + { + int j = i + 1; if (j > 3) j = 0; + int k = j + 1; if (k > 3) k = 0; + double SX = 0.0; + double SY = 0.0; + for (int ii = 0; ii < 4; ii++) + { + int jj = ii + 1; if (jj > 3) jj = 0; + int kk = jj + 1; if (kk > 3) kk = 0; + int mm = kk + 1; if (mm > 3) mm = 0; + SX = SX + agq.b[ii] * NXI[ii] * NETA[ii] * (3.0 * (L[jj] - L[mm]) + (agq.g[jj] - agq.g[kk])); + SY = SY + agq.c[ii] * NXI[ii] * NETA[ii] * (3.0 * (L[jj] - L[mm]) + (agq.g[jj] - agq.g[kk])); + } + dNdX(i, 0) = (agq.b[i] + agq.b[j]) / agq.A / 2.0 + + NXI[i] * NETA[i] * agq.g[k] * SX / 2.0 / agq.A / (1.0 + agq.g[0] * agq.g[2] + agq.g[1] * agq.g[3]); + dNdX(i, 1) = (agq.c[i] + agq.c[j]) / agq.A / 2.0 + + NXI[i] * NETA[i] * agq.g[k] * SY / 2.0 / agq.A / (1.0 + agq.g[0] * agq.g[2] + agq.g[1] * agq.g[3]); + } + + // We use the drilling penalty as defined by hughes and brezzi, + // where we link the independent rotation to the skew symmetric part of the in-plane displacement field. + + Bd(0) = -0.5 * dNdX(0, 1); + Bd(1) = 0.5 * dNdX(0, 0); + Bd(5) = -N(0); + + Bd(6) = -0.5 * dNdX(1, 1); + Bd(7) = 0.5 * dNdX(1, 0); + Bd(11) = -N(1); + + Bd(12) = -0.5 * dNdX(2, 1); + Bd(13) = 0.5 * dNdX(2, 0); + Bd(17) = -N(2); + + Bd(18) = -0.5 * dNdX(3, 1); + Bd(19) = 0.5 * dNdX(3, 0); + Bd(23) = -N(3); + } + + // computes the complete B matrix + void computeBMatrix( + const ASDShellQ4LocalCoordinateSystem& LCS, + double xi, double eta, + const JacobianOperator& Jac, + const AGQIParams& agq, + const MITC4Params& mitc, + const Vector& N, + const Matrix& dN, + const Matrix& BQ_mean, + Matrix& B, + Matrix& BQ, + Vector& Bd + ) + { + // cartesian derivatives of standard shape function + auto& dNdX = ASDShellQ4Globals::instance().dNdX; + dNdX.addMatrixProduct(0.0, dN, Jac.invJ, 1.0); + + // initialize + B.Zero(); + BQ.Zero(); + Bd.Zero(); + + // AGQI proc *********************************************************************************************** + + // area coordinates of the gauss point (Eq 7) + std::array L; + L[0] = 0.25 * (1.0 - xi) * (agq.g[1] * (1.0 - eta) + agq.g[2] * (1.0 + eta)); + L[1] = 0.25 * (1.0 - eta) * (agq.g[3] * (1.0 - xi) + agq.g[2] * (1.0 + xi)); + L[2] = 0.25 * (1.0 + xi) * (agq.g[0] * (1.0 - eta) + agq.g[3] * (1.0 + eta)); + L[3] = 0.25 * (1.0 + eta) * (agq.g[0] * (1.0 - xi) + agq.g[1] * (1.0 + xi)); + + // computed modified shape function gradients for the strain matrix for external dofs + // using the area coordinate method as written in the reference paper of the AGQI element + static constexpr std::array NXI = { -1.0, 1.0, 1.0, -1.0 }; + static constexpr std::array NETA = { -1.0, -1.0, 1.0, 1.0 }; + for (int i = 0; i < 4; i++) + { + int j = i + 1; if (j > 3) j = 0; + int k = j + 1; if (k > 3) k = 0; + double SX = 0.0; + double SY = 0.0; + for (int ii = 0; ii < 4; ii++) + { + int jj = ii + 1; if (jj > 3) jj = 0; + int kk = jj + 1; if (kk > 3) kk = 0; + int mm = kk + 1; if (mm > 3) mm = 0; + SX = SX + agq.b[ii] * NXI[ii] * NETA[ii] * (3.0 * (L[jj] - L[mm]) + (agq.g[jj] - agq.g[kk])); + SY = SY + agq.c[ii] * NXI[ii] * NETA[ii] * (3.0 * (L[jj] - L[mm]) + (agq.g[jj] - agq.g[kk])); + } + dNdX(i, 0) = (agq.b[i] + agq.b[j]) / agq.A / 2.0 + + NXI[i] * NETA[i] * agq.g[k] * SX / 2.0 / agq.A / (1.0 + agq.g[0] * agq.g[2] + agq.g[1] * agq.g[3]); + dNdX(i, 1) = (agq.c[i] + agq.c[j]) / agq.A / 2.0 + + NXI[i] * NETA[i] * agq.g[k] * SY / 2.0 / agq.A / (1.0 + agq.g[0] * agq.g[2] + agq.g[1] * agq.g[3]); + } + + // compute the BQ matrix for the internal DOFs + for (int i = 0; i < 2; i++) + { + unsigned int j = i + 1; if (j > 3) j = 0; + unsigned int k = j + 1; if (k > 3) k = 0; + double NQX = (agq.b[i] * L[k] + agq.b[k] * L[i]) / agq.A / 2.0; + double NQY = (agq.c[i] * L[k] + agq.c[k] * L[i]) / agq.A / 2.0; + unsigned int index1 = i * 2; + unsigned int index2 = index1 + 1; + BQ(0, index1) += NQX; + BQ(1, index2) += NQY; + BQ(2, index1) += NQY; + BQ(2, index2) += NQX; + } + BQ.addMatrix(1.0, BQ_mean, -1.0); + + // membrane ************************************************************************************************ + // this is the memebrane part of the compatible standard in-plane displacement field + + B(0, 0) = dNdX(0, 0); B(0, 6) = dNdX(1, 0); B(0, 12) = dNdX(2, 0); B(0, 18) = dNdX(3, 0); + B(1, 1) = dNdX(0, 1); B(1, 7) = dNdX(1, 1); B(1, 13) = dNdX(2, 1); B(1, 19) = dNdX(3, 1); + B(2, 0) = dNdX(0, 1); B(2, 6) = dNdX(1, 1); B(2, 12) = dNdX(2, 1); B(2, 18) = dNdX(3, 1); + B(2, 1) = dNdX(0, 0); B(2, 7) = dNdX(1, 0); B(2, 13) = dNdX(2, 0); B(2, 19) = dNdX(3, 0); + + // We use the drilling penalty as defined by hughes and brezzi, + // where we link the independent rotation to the skew symmetric part of the in-plane displacement field. + + Bd(0) = -0.5 * dNdX(0, 1); + Bd(1) = 0.5 * dNdX(0, 0); + Bd(5) = -N(0); + + Bd(6) = -0.5 * dNdX(1, 1); + Bd(7) = 0.5 * dNdX(1, 0); + Bd(11) = -N(1); + + Bd(12) = -0.5 * dNdX(2, 1); + Bd(13) = 0.5 * dNdX(2, 0); + Bd(17) = -N(2); + + Bd(18) = -0.5 * dNdX(3, 1); + Bd(19) = 0.5 * dNdX(3, 0); + Bd(23) = -N(3); + + // bending ************************************************************************************************* + + B(3, 4) = -dNdX(0, 0); B(3, 10) = -dNdX(1, 0); B(3, 16) = -dNdX(2, 0); B(3, 22) = -dNdX(3, 0); + B(4, 3) = dNdX(0, 1); B(4, 9) = dNdX(1, 1); B(4, 15) = dNdX(2, 1); B(4, 21) = dNdX(3, 1); + B(5, 3) = dNdX(0, 0); B(5, 9) = dNdX(1, 0); B(5, 15) = dNdX(2, 0); B(5, 21) = dNdX(3, 0); + B(5, 4) = -dNdX(0, 1); B(5, 10) = -dNdX(1, 1); B(5, 16) = -dNdX(2, 1); B(5, 22) = -dNdX(3, 1); + + // shear *************************************************************************************************** + + // MITC modified shape functions + static Matrix MITCShapeFunctions(2, 4); + MITCShapeFunctions.Zero(); + MITCShapeFunctions(1, 0) = 1.0 - xi; + MITCShapeFunctions(0, 1) = 1.0 - eta; + MITCShapeFunctions(1, 2) = 1.0 + xi; + MITCShapeFunctions(0, 3) = 1.0 + eta; + + // strain displacement matrix in natural coordinate system. + // interpolate the shear strains given in MITC4Params + // using the modified shape function + static Matrix BN(2, 24); + BN.addMatrixProduct(0.0, MITCShapeFunctions, mitc.shearStrains, 1.0); + + // modify the shear strain intensity in the tying points + // to match the values that would be obtained using standard + // interpolations + double Temp1, Temp2, Temp3; + Temp1 = mitc.Cx + xi * mitc.Bx; + Temp3 = mitc.Cy + xi * mitc.By; + Temp1 = Temp1 * Temp1 + Temp3 * Temp3; + Temp1 = std::sqrt(Temp1) / (8.0 * Jac.detJ); + Temp2 = mitc.Ax + eta * mitc.Bx; + Temp3 = mitc.Ay + eta * mitc.By; + Temp2 = Temp2 * Temp2 + Temp3 * Temp3; + Temp2 = std::sqrt(Temp2) / (8.0 * Jac.detJ); + for (int i = 0; i < 24; i++) { + BN(0, i) *= Temp1; + BN(1, i) *= Temp2; + } + + // transform the strain-displacement matrix from natural + // to local coordinate system taking into account the element distorsion + static Matrix TBN(2, 24); + TBN.addMatrixProduct(0.0, mitc.transformation, BN, 1.0); + for (int i = 0; i < 2; i++) + for (int j = 0; j < 24; j++) + B(i + 6, j) = TBN(i, j); + } + + // invert bending terms + void invertBBendingTerms( + const Matrix& B, + Matrix& B1) + { + // due to the convention in the shell sections, we need to change the sign of the bending terms + // for the B^T case. + B1.addMatrix(0.0, B, 1.0); + for (int i = 3; i < 6; i++) { + for (int j = 0; j < 4; j++) { + B1(i, j * 6 + 3) *= -1.0; + B1(i, j * 6 + 4) *= -1.0; + } + } + } + + // computes the transformation matrix for generalized strains + inline void getRotationMatrixForGeneralizedStrains(double radians, Matrix& T) + { + double c = std::cos(radians); + double s = std::sin(radians); + + T.Zero(); + + T(0, 0) = c * c; T(0, 1) = s * s; T(0, 2) = -s * c; + T(1, 0) = s * s; T(1, 1) = c * c; T(1, 2) = s * c; + T(2, 0) = 2.0 * s * c; T(2, 1) = -2.0 * s * c; T(2, 2) = c * c - s * s; + + T(3, 3) = c * c; T(3, 4) = s * s; T(3, 5) = -s * c; + T(4, 3) = s * s; T(4, 4) = c * c; T(4, 5) = s * c; + T(5, 3) = 2.0 * s * c; T(5, 4) = -2.0 * s * c; T(5, 5) = c * c - s * s; + + T(6, 6) = c; T(6, 7) = s; + T(7, 6) = -s; T(7, 7) = c; + } + + // computes the transformation matrix for generalized stresses + inline void getRotationMatrixForGeneralizedStresses(double radians, Matrix& T) + { + double c = std::cos(radians); + double s = std::sin(radians); + + T.Zero(); + + T(0, 0) = c * c; T(0, 1) = s * s; T(0, 2) = -2.0 * s * c; + T(1, 0) = s * s; T(1, 1) = c * c; T(1, 2) = 2.0 * s * c; + T(2, 0) = s * c; T(2, 1) = -s * c; T(2, 2) = c * c - s * s; + + T(3, 3) = c * c; T(3, 4) = s * s; T(3, 5) = -2.0 * s * c; + T(4, 3) = s * s; T(4, 4) = c * c; T(4, 5) = 2.0 * s * c; + T(5, 3) = s * c; T(5, 4) = -s * c; T(5, 5) = c * c - s * s; + + T(6, 6) = c; T(6, 7) = s; + T(7, 6) = -s; T(7, 7) = c; + } + +} + +ASDShellQ4::ASDShellQ4() + : Element(0, ELE_TAG_ASDShellQ4) + , m_transformation(new ASDShellQ4Transformation()) +{ +} + +ASDShellQ4::ASDShellQ4( + int tag, + int node1, + int node2, + int node3, + int node4, + SectionForceDeformation* section, + bool corotational) + : Element(tag, ELE_TAG_ASDShellQ4) + , m_transformation(corotational ? new ASDShellQ4CorotationalTransformation() : new ASDShellQ4Transformation()) +{ + // save node ids + m_node_ids(0) = node1; + m_node_ids(1) = node2; + m_node_ids(2) = node3; + m_node_ids(3) = node4; + + // copy sections + for (int i = 0; i < 4; i++) { + m_sections[i] = section->getCopy(); + if (m_sections[i] == 0) { + opserr << "ASDShellQ4::constructor - failed to get a material of type: ShellSection\n"; + exit(-1); + } + } +} + +ASDShellQ4::~ASDShellQ4( ) +{ + // clean up section + for (int i = 0; i < 4; i++) + delete m_sections[i]; + + // clean up coordinate transformation + if(m_transformation) + delete m_transformation; + + // clean up load vectors + if (m_load) + delete m_load; +} + +void ASDShellQ4::setDomain(Domain* theDomain) +{ + // set domain on transformation + m_transformation->setDomain(theDomain, m_node_ids); + + // compute drilling penalty parameter + m_drill_stiffness = 0.0; + for (int i = 0; i < 4; i++) + m_drill_stiffness += m_sections[i]->getInitialTangent()(2, 2); + m_drill_stiffness /= 4.0; + + // compute section orientation angle + ASDShellQ4LocalCoordinateSystem reference_cs = m_transformation->createReferenceCoordinateSystem(); + Vector3Type e1_local = reference_cs.Vx(); + Vector3Type P1(m_transformation->getNodes()[0]->getCrds()); + Vector3Type P2(m_transformation->getNodes()[1]->getCrds()); + Vector3Type P3(m_transformation->getNodes()[2]->getCrds()); + Vector3Type P4(m_transformation->getNodes()[3]->getCrds()); + Vector3Type e1 = (P2 + P3) / 2.0 - (P1 + P4) / 2.0; + e1.normalize(); + m_angle = std::acos(std::max(-1.0, std::min(1.0, e1.dot(e1_local)))); + if (m_angle != 0.0) { + // if they are not counter-clock-wise, let's change the sign of the angle + const Matrix& R = reference_cs.Orientation(); + if ((e1(0) * R(1, 0) + e1(1) * R(1, 1) + e1(2) * R(1, 2)) < 0.0) + m_angle = -m_angle; + } + + // AGQI internal DOFs + AGQIinitialize(); + + // call base class implementation + DomainComponent::setDomain(theDomain); +} + +void ASDShellQ4::Print(OPS_Stream& s, int flag) +{ + if (flag == -1) { + int eleTag = this->getTag(); + s << "EL_ASDShellQ4\t" << eleTag << "\t"; + s << eleTag << "\t" << 1; + s << "\t" << m_node_ids(0) << "\t" << m_node_ids(1); + s << "\t" << m_node_ids(2) << "\t" << m_node_ids(3) << "\t0.00"; + s << endln; + s << "PROP_3D\t" << eleTag << "\t"; + s << eleTag << "\t" << 1; + s << "\t" << -1 << "\tSHELL\t1.0\0.0"; + s << endln; + } + + if (flag < -1) { + int counter = (flag + 1) * -1; + int eleTag = this->getTag(); + int i, j; + for (i = 0; i < 4; i++) { + const Vector& stress = m_sections[i]->getStressResultant(); + s << "STRESS\t" << eleTag << "\t" << counter << "\t" << i << "\tTOP"; + for (j = 0; j < 6; j++) + s << "\t" << stress(j); + s << endln; + } + } + + if (flag == OPS_PRINT_CURRENTSTATE) { + s << endln; + s << "MITC4 Non-Locking Four Node Shell \n"; + s << "Element Number: " << this->getTag() << endln; + s << "Node 1 : " << m_node_ids(0) << endln; + s << "Node 2 : " << m_node_ids(1) << endln; + s << "Node 3 : " << m_node_ids(2) << endln; + s << "Node 4 : " << m_node_ids(3) << endln; + + s << "Material Information : \n "; + m_sections[0]->Print(s, flag); + + s << endln; + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << "\t\t\t{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"ASDShellQ4\", "; + s << "\"nodes\": [" << m_node_ids(0) << ", " << m_node_ids(1) << ", "; + s << m_node_ids(2) << ", " << m_node_ids(3) << "], "; + s << "\"section\": \"" << m_sections[0]->getTag() << "\"}"; + } +} + +int ASDShellQ4::getNumExternalNodes() const +{ + return 4; +} + +const ID& ASDShellQ4::getExternalNodes() +{ + return m_node_ids; +} + +Node** +ASDShellQ4::getNodePtrs(void) +{ + return m_transformation->getNodes().data(); +} + +int ASDShellQ4::getNumDOF() +{ + return 24; +} + +int ASDShellQ4::commitState() +{ + int success = 0; + + // transformation + m_transformation->commit(); + + // sections + for (int i = 0; i < 4; i++) + success += m_sections[i]->commitState(); + + // AGQI internal DOFs + m_U_converged = m_U; + m_Q_converged = m_Q; + + // done + return success; +} + +int ASDShellQ4::revertToLastCommit() +{ + int success = 0; + + // transformation + m_transformation->revertToLastCommit(); + + // sections + for (int i = 0; i < 4; i++) + success += m_sections[i]->revertToLastCommit(); + + // AGQI internal DOFs + m_U = m_U_converged; + m_Q = m_Q_converged; + + // done + return success; +} + +int ASDShellQ4::revertToStart() +{ + int success = 0; + + // transformation + m_transformation->revertToStart(); + + // sections + for (int i = 0; i < 4; i++) + success += m_sections[i]->revertToStart(); + + // AGQI internal DOFs + AGQIinitialize(); + + return success; +} + +int ASDShellQ4::update() +{ + // calculate + auto& LHS = ASDShellQ4Globals::instance().LHS; + auto& RHS = ASDShellQ4Globals::instance().RHS; + return calculateAll(LHS, RHS, (OPT_UPDATE)); +} + +const Matrix& ASDShellQ4::getTangentStiff() +{ + // calculate + auto& LHS = ASDShellQ4Globals::instance().LHS; + auto& RHS = ASDShellQ4Globals::instance().RHS; + calculateAll(LHS, RHS, (OPT_LHS)); + return LHS; +} + +const Matrix& ASDShellQ4::getInitialStiff() +{ + // calculate + auto& LHS = ASDShellQ4Globals::instance().LHS_initial; + auto& RHS = ASDShellQ4Globals::instance().RHS; + calculateAll(LHS, RHS, (OPT_LHS | OPT_LHS_IS_INITIAL)); + return LHS; +} + +const Matrix& ASDShellQ4::getMass() +{ + // Output matrix + auto& LHS = ASDShellQ4Globals::instance().LHS_mass; + LHS.Zero(); + + // Compute the reference coordinate system + ASDShellQ4LocalCoordinateSystem reference_cs = + m_transformation->createReferenceCoordinateSystem(); + + // Jacobian + auto& jac = ASDShellQ4Globals::instance().jac; + + // Some matrices + auto& dN = ASDShellQ4Globals::instance().dN; + auto& N = ASDShellQ4Globals::instance().N; + + // Gauss loop + for (int i = 0; i < 4; i++) + { + // Current integration point data + double xi = XI[i]; + double eta = ETA[i]; + double w = WTS[i]; + shapeFunctions(xi, eta, N); + shapeFunctionsNaturalDerivatives(xi, eta, dN); + jac.calculate(reference_cs, dN); + double dA = w * jac.detJ; + + // Section density (already integrated through the thickness) + double rho = m_sections[i]->getRho(); + + // Add current integration point contribution + for (int j = 0; j < 4; j++) + { + int index = j * 6; + + // Translational mass contribution + double Tmass = N(j) * rho * dA; + for (int q = 0; q < 3; q++) + LHS(index + q, index + q) += Tmass; + + // Rotational mass neglected for the moment ... + } + } + + // Done + return LHS; +} + +void ASDShellQ4::zeroLoad() +{ + if (m_load) + m_load->Zero(); +} + +int +ASDShellQ4::addLoad(ElementalLoad* theLoad, double loadFactor) +{ + opserr << "ASDShellQ4::addLoad - load type unknown for ele with tag: " << this->getTag() << endln; + return -1; +} + +int +ASDShellQ4::addInertiaLoadToUnbalance(const Vector& accel) +{ + // Allocate load vector if necessary + if (m_load == nullptr) + m_load = new Vector(24); + auto& F = *m_load; + + // Get mass matrix + const auto& M = getMass(); + + // Add -M*R*acc to unbalance, taking advantage of lumped mass matrix + for (int i = 0; i < 4; i++) + { + const auto& RV = m_transformation->getNodes()[i]->getRV(accel); + int index = i * 6; + for (int j = 0; j < 6; j++) + F(index + j) -= M(index + j, index + j) * RV(j); + } + + // Done + return 0; +} + +const Vector& ASDShellQ4::getResistingForce() +{ + // calculate + auto& LHS = ASDShellQ4Globals::instance().LHS; + auto& RHS = ASDShellQ4Globals::instance().RHS; + calculateAll(LHS, RHS, (OPT_RHS)); + return RHS; +} + +const Vector& ASDShellQ4::getResistingForceIncInertia() +{ + // calculate + auto& LHS = ASDShellQ4Globals::instance().LHS; + auto& RHS = ASDShellQ4Globals::instance().RHS_winertia; + calculateAll(LHS, RHS, (OPT_RHS)); + + // Add damping terms + if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + RHS.addVector(1.0, getRayleighDampingForces(), 1.0); + + // Compute mass + const auto& M = getMass(); + + // Add M*acc to unbalance, taking advantage of lumped mass matrix + for (int i = 0; i < 4; i++) + { + const auto& A = m_transformation->getNodes()[i]->getTrialAccel(); + int index = i * 6; + for (int j = 0; j < 6; j++) + RHS(index + j) += M(index + j, index + j) * A(j); + } + + // Done + return RHS; +} + +int ASDShellQ4::sendSelf(int commitTag, Channel& theChannel) +{ + int res = 0; + + // note: we don't check for dataTag == 0 for Element + // objects as that is taken care of in a commit by the Domain + // object - don't want to have to do the check if sending data + int dataTag = this->getDbTag(); + + // send the ids of sections + int matDbTag; + + // INT data + // 4 section class tags + + // 4 mat db tag + + // 1 tag + + // 4 node tags + + // 1 transformation type + static ID idData(14); + + for (int i = 0; i < 4; i++) { + idData(i) = m_sections[i]->getClassTag(); + matDbTag = m_sections[i]->getDbTag(); + // NOTE: we do have to ensure that the material has a database + // tag if we are sending to a database channel. + if (matDbTag == 0) { + matDbTag = theChannel.getDbTag(); + if (matDbTag != 0) + m_sections[i]->setDbTag(matDbTag); + } + idData(i + 4) = matDbTag; + } + + idData(8) = getTag(); + idData(9) = m_node_ids(0); + idData(10) = m_node_ids(1); + idData(11) = m_node_ids(2); + idData(12) = m_node_ids(3); + idData(13) = m_transformation->isLinear() ? 0 : 1; + + res += theChannel.sendID(dataTag, commitTag, idData); + if (res < 0) { + opserr << "WARNING ASDShellQ4::sendSelf() - " << this->getTag() << " failed to send ID\n"; + return res; + } + + // DOUBLE data + // 4 damping factors + + // 2 drill stiffness and section orientation angle + + // N transformation data + int NT = m_transformation->internalDataSize(); + Vector vectData(6 + NT); + + vectData(0) = alphaM; + vectData(1) = betaK; + vectData(2) = betaK0; + vectData(3) = betaKc; + vectData(4) = m_drill_stiffness; + vectData(5) = m_angle; + m_transformation->saveInternalData(vectData, 6); + + res += theChannel.sendVector(dataTag, commitTag, vectData); + if (res < 0) { + opserr << "WARNING ASDShellQ4::sendSelf() - " << this->getTag() << " failed to send Vector\n"; + return res; + } + + // send all sections + for (int i = 0; i < 4; i++) { + res += m_sections[i]->sendSelf(commitTag, theChannel); + if (res < 0) { + opserr << "WARNING ASDShellQ4::sendSelf() - " << this->getTag() << " failed to send its Material\n"; + return res; + } + } + + // done + return res; +} + +int ASDShellQ4::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) +{ + int res = 0; + + int dataTag = this->getDbTag(); + + // INT data + // 4 section class tags + + // 4 mat db tag + + // 1 tag + + // 4 node tags + + // 1 transformation type + static ID idData(14); + res += theChannel.recvID(dataTag, commitTag, idData); + if (res < 0) { + opserr << "WARNING ASDShellQ4::recvSelf() - " << this->getTag() << " failed to receive ID\n"; + return res; + } + + setTag(idData(8)); + m_node_ids(0) = idData(9); + m_node_ids(1) = idData(10); + m_node_ids(2) = idData(11); + m_node_ids(3) = idData(12); + + if (m_transformation) + delete m_transformation; + m_transformation = idData(13) == 0 ? new ASDShellQ4Transformation() : new ASDShellQ4CorotationalTransformation(); + + // DOUBLE data + // 4 damping factors + + // 2 drill stiffness and section orientation angle + + // N transformation data + int NT = m_transformation->internalDataSize(); + Vector vectData(6 + NT); + + res += theChannel.recvVector(dataTag, commitTag, vectData); + if (res < 0) { + opserr << "WARNING ASDShellQ4::sendSelf() - " << this->getTag() << " failed to receive Vector\n"; + return res; + } + + alphaM = vectData(0); + betaK = vectData(1); + betaK0 = vectData(2); + betaKc = vectData(3); + m_drill_stiffness = vectData(4); + m_angle = vectData(5); + m_transformation->restoreInternalData(vectData, 6); + + // all sections + for (int i = 0; i < 4; i++) { + int matClassTag = idData(i); + int matDbTag = idData(i + 4); + // Allocate new material with the sent class tag + if (m_sections[i]) + delete m_sections[i]; + m_sections[i] = theBroker.getNewSection(matClassTag); + if (m_sections[i] == 0) { + opserr << "ASDShellQ4::recvSelf() - Broker could not create NDMaterial of class type" << matClassTag << endln;; + return -1; + } + // Receive the material + m_sections[i]->setDbTag(matDbTag); + res += m_sections[i]->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "ASDShellQ4::recvSelf() - material " << i << "failed to recv itself\n"; + return res; + } + } + + // done + return res; +} + +Response* +ASDShellQ4::setResponse(const char **argv, int argc, OPS_Stream &output) +{ + Response* theResponse = 0; + + output.tag("ElementOutput"); + output.attr("eleType", "ASDShellQ4"); + output.attr("eleTag", this->getTag()); + int numNodes = this->getNumExternalNodes(); + const ID& nodes = this->getExternalNodes(); + static char nodeData[32]; + + for (int i = 0; i < numNodes; i++) { + sprintf(nodeData, "node%d", i + 1); + output.attr(nodeData, nodes(i)); + } + + if (strcmp(argv[0], "force") == 0 || strcmp(argv[0], "forces") == 0 || + strcmp(argv[0], "globalForce") == 0 || strcmp(argv[0], "globalForces") == 0) { + const Vector& force = this->getResistingForce(); + int size = force.Size(); + for (int i = 0; i < size; i++) { + sprintf(nodeData, "P%d", i + 1); + output.tag("ResponseType", nodeData); + } + theResponse = new ElementResponse(this, 1, this->getResistingForce()); + } + + else if (strcmp(argv[0], "material") == 0 || strcmp(argv[0], "Material") == 0) { + if (argc < 2) { + opserr << "ASDShellQ4::setResponse() - need to specify more data\n"; + return 0; + } + int pointNum = atoi(argv[1]); + if (pointNum > 0 && pointNum <= 4) { + + output.tag("GaussPoint"); + output.attr("number", pointNum); + output.attr("eta", XI[pointNum - 1]); + output.attr("neta", ETA[pointNum - 1]); + + theResponse = m_sections[pointNum - 1]->setResponse(&argv[2], argc - 2, output); + + output.endTag(); + } + + } + else if (strcmp(argv[0], "stresses") == 0) { + + for (int i = 0; i < 4; i++) { + output.tag("GaussPoint"); + output.attr("number", i + 1); + output.attr("eta", XI[i]); + output.attr("neta", ETA[i]); + + output.tag("SectionForceDeformation"); + output.attr("classType", m_sections[i]->getClassTag()); + output.attr("tag", m_sections[i]->getTag()); + + output.tag("ResponseType", "p11"); + output.tag("ResponseType", "p22"); + output.tag("ResponseType", "p1212"); + output.tag("ResponseType", "m11"); + output.tag("ResponseType", "m22"); + output.tag("ResponseType", "m12"); + output.tag("ResponseType", "q1"); + output.tag("ResponseType", "q2"); + + output.endTag(); // GaussPoint + output.endTag(); // NdMaterialOutput + } + + theResponse = new ElementResponse(this, 2, Vector(32)); + } + + else if (strcmp(argv[0], "strains") == 0) { + + for (int i = 0; i < 4; i++) { + output.tag("GaussPoint"); + output.attr("number", i + 1); + output.attr("eta", XI[i]); + output.attr("neta", ETA[i]); + + output.tag("SectionForceDeformation"); + output.attr("classType", m_sections[i]->getClassTag()); + output.attr("tag", m_sections[i]->getTag()); + + output.tag("ResponseType", "eps11"); + output.tag("ResponseType", "eps22"); + output.tag("ResponseType", "gamma12"); + output.tag("ResponseType", "theta11"); + output.tag("ResponseType", "theta22"); + output.tag("ResponseType", "theta33"); + output.tag("ResponseType", "gamma13"); + output.tag("ResponseType", "gamma23"); + + output.endTag(); // GaussPoint + output.endTag(); // NdMaterialOutput + } + + theResponse = new ElementResponse(this, 3, Vector(32)); + } + + output.endTag(); + return theResponse; +} + +int +ASDShellQ4::getResponse(int responseID, Information &eleInfo) +{ + static Vector stresses(32); + static Vector strains(32); + + switch (responseID) { + case 1: // global forces + return eleInfo.setVector(this->getResistingForce()); + break; + + case 2: // stresses + for (int i = 0; i < 4; i++) { + + // Get material stress response + const Vector& sigma = m_sections[i]->getStressResultant(); + stresses(0) = sigma(0); + stresses(1) = sigma(1); + stresses(2) = sigma(2); + stresses(3) = sigma(3); + stresses(4) = sigma(4); + stresses(5) = sigma(5); + stresses(6) = sigma(6); + stresses(7) = sigma(7); + } + return eleInfo.setVector(stresses); + break; + case 3: //strain + for (int i = 0; i < 4; i++) { + + // Get section deformation + const Vector& deformation = m_sections[i]->getSectionDeformation(); + strains(0) = deformation(0); + strains(1) = deformation(1); + strains(2) = deformation(2); + strains(3) = deformation(3); + strains(4) = deformation(4); + strains(5) = deformation(5); + strains(6) = deformation(6); + strains(7) = deformation(7); + } + return eleInfo.setVector(strains); + break; + default: + return -1; + } +} + +int ASDShellQ4::setParameter(const char** argv, int argc, Parameter& param) +{ + int res = -1; + int matRes = res; + for (int i = 0; i < 4; i++) + { + matRes = m_sections[i]->setParameter(argv, argc, param); + if (matRes != -1) + res = matRes; + } + return res; +} + +int ASDShellQ4::calculateAll(Matrix& LHS, Vector& RHS, int options) +{ + // Check options + if (!m_transformation->isLinear()) { + // corotational calculation of the tangent LHS requires the RHS! + if (options & OPT_LHS) + options |= OPT_RHS; + } + + // Zero output + int result = 0; + if(options & OPT_RHS) + RHS.Zero(); + if(options & OPT_LHS) + LHS.Zero(); + + // Global displacements + auto& UG = ASDShellQ4Globals::instance().UG; + m_transformation->computeGlobalDisplacements(UG); + + // update transformation + if(options & OPT_UPDATE) + m_transformation->update(UG); + + // Compute the reference coordinate system + ASDShellQ4LocalCoordinateSystem reference_cs = + m_transformation->createReferenceCoordinateSystem(); + + // Compute the local coordinate system. + ASDShellQ4LocalCoordinateSystem local_cs = + m_transformation->createLocalCoordinateSystem(UG); + + // Prepare all the parameters needed for the MITC4 + // and AGQI formulations. + // This is to be done here outside the Gauss Loop. + auto& mitc = ASDShellQ4Globals::instance().mitc; + auto& agq = ASDShellQ4Globals::instance().agq; + mitc.compute(reference_cs); + agq.compute(reference_cs); + + // Jacobian + auto& jac = ASDShellQ4Globals::instance().jac; + + // Some matrices/vectors + auto& B = ASDShellQ4Globals::instance().B; + auto& Bd = ASDShellQ4Globals::instance().Bd; + auto& Bd0 = ASDShellQ4Globals::instance().Bd0; + auto& BQ = ASDShellQ4Globals::instance().BQ; + auto& BQ_mean = ASDShellQ4Globals::instance().BQ_mean; + auto& BQTD = ASDShellQ4Globals::instance().BQTD; + auto& DBQ = ASDShellQ4Globals::instance().DBQ; + auto& B1 = ASDShellQ4Globals::instance().B1; + auto& B1TD = ASDShellQ4Globals::instance().B1TD; + auto& N = ASDShellQ4Globals::instance().N; + auto& dN = ASDShellQ4Globals::instance().dN; + auto& E = ASDShellQ4Globals::instance().E; + auto& S = ASDShellQ4Globals::instance().S; + auto& D = ASDShellQ4Globals::instance().D; + + // matrices for orienting strains in section coordinate system + auto& Re = ASDShellQ4Globals::instance().Re; + auto& Rs = ASDShellQ4Globals::instance().Rs; + if (m_angle != 0.0) { + if (options & OPT_UPDATE) + getRotationMatrixForGeneralizedStrains(-m_angle, Re); + if ((options & OPT_RHS) || (options & OPT_LHS)) + getRotationMatrixForGeneralizedStresses(m_angle, Rs); + } + + // Local displacements + auto& UL = ASDShellQ4Globals::instance().UL; + m_transformation->calculateLocalDisplacements(local_cs, UG, UL); + + // Update AGQI internal DOFs + if (options & OPT_UPDATE) + AGQIupdate(UL); + + // AGQI begin gauss loop (computes the BQ_mean correction matrix) + AGQIbeginGaussLoop(reference_cs); + + // Drilling strain-displacement matrix at center for reduced + // integration + shapeFunctions(0.0, 0.0, N); + shapeFunctionsNaturalDerivatives(0.0, 0.0, dN); + computeBdrilling(reference_cs, 0.0, 0.0, jac, agq, N, dN, Bd0); + + // Gauss loop + for (int igauss = 0; igauss < 4; igauss++) + { + // Current integration point data + double xi = XI[igauss]; + double eta = ETA[igauss]; + double w = WTS[igauss]; + shapeFunctions(xi, eta, N); + shapeFunctionsNaturalDerivatives(xi, eta, dN); + jac.calculate(reference_cs, dN); + double dA = w * jac.detJ; + + // Strain-displacement matrix + computeBMatrix(reference_cs, xi, eta, jac, agq, mitc, N, dN, BQ_mean, B, BQ, Bd); + + // The drilling according to Hughes-Brezzi plays and important role in warped shells and + // the stiffness should be equal to the initial (elastic) in-plane shear modulus. + // If fully integrated however, locks the membrane response. If under-integrated the element + // has spurious zero-energy modes. Thus here we use the compute the drilling B matrix + // as a weighted sum of the reduced integrated one (Bd0) and a scaled version of the fully + // integrated one, just to suppress spurious zero energy modes. + constexpr double sqrt_drill_scale = 1.0e-2; // drill_scale = 1.0e-4 + Bd.addVector(sqrt_drill_scale, Bd0, 1.0); + + // Update strain strain + if (options & OPT_UPDATE) + { + // Section deformation + if (m_angle != 0.0) { + auto& Elocal = ASDShellQ4Globals::instance().Elocal; + Elocal.addMatrixVector(0.0, B, UL, 1.0); + Elocal.addMatrixVector(1.0, BQ, m_Q, 1.0); + E.addMatrixVector(0.0, Re, Elocal, 1.0); + } + else { + E.addMatrixVector(0.0, B, UL, 1.0); + E.addMatrixVector(1.0, BQ, m_Q, 1.0); + } + + // Update section + result += m_sections[igauss]->setTrialSectionDeformation(E); + + // Drilling strain Ed = Bd*UL + double& Ed = m_drill_strain[igauss]; + Ed = 0.0; + for (int i = 0; i < 24; i++) + Ed += Bd(i) * UL(i); + } + + // Invert bending terms for correct statement of equilibrium + if((options & OPT_RHS) || (options & OPT_LHS)) + invertBBendingTerms(B, B1); + + // Integrate RHS + if (options & OPT_RHS) + { + // Section force + if (m_angle != 0.0) { + auto& Ssection = m_sections[igauss]->getStressResultant(); + S.addMatrixVector(0.0, Rs, Ssection, 1.0); + } + else { + S = m_sections[igauss]->getStressResultant(); + } + + // Add current integration point contribution (RHS) + RHS.addMatrixTransposeVector(1.0, B1, S, dA); + + // Add drilling stress = Bd'*Sd * dA (RHS) + double Sd = m_drill_stiffness * m_drill_strain[igauss]; + for (int i = 0; i < 24; i++) + RHS(i) += Bd(i) * Sd * dA; + + // AGQI: update residual for internal DOFs + m_Q_residual.addMatrixTransposeVector(1.0, BQ, S, -dA); + } + + // AGQI: due to the static condensation, the following items + // must be computed if we need either the RHS or the LHS, or both of them + if ((options & OPT_RHS) || (options & OPT_LHS)) + { + // Section tangent + if (m_angle != 0.0) { + const auto& Dsection = (options & OPT_LHS_IS_INITIAL) ? + m_sections[igauss]->getInitialTangent() : + m_sections[igauss]->getSectionTangent(); + auto& RsT = ASDShellQ4Globals::instance().RsT; + RsT.addMatrixTranspose(0.0, Rs, 1.0); + auto& DRsT = ASDShellQ4Globals::instance().DRsT; + DRsT.addMatrixProduct(0.0, Dsection, RsT, 1.0); + D.addMatrixProduct(0.0, Rs, DRsT, 1.0); + } + else { + D = (options & OPT_LHS_IS_INITIAL) ? + m_sections[igauss]->getInitialTangent() : + m_sections[igauss]->getSectionTangent(); + } + + // Matrices for AGQI static condensation of internal DOFs + BQTD.addMatrixTransposeProduct(0.0, BQ, D, dA); + DBQ.addMatrixProduct(0.0, D, BQ, dA); + m_KQQ_inv.addMatrixProduct(1.0, BQTD, BQ, 1.0); + m_KQU.addMatrixProduct(1.0, BQTD, B, 1.0); + m_KUQ.addMatrixTransposeProduct(1.0, B1, DBQ, 1.0); + } + + // Integrate LHS + if (options & OPT_LHS) + { + // Add current integration point contribution (LHS) + B1TD.addMatrixTransposeProduct(0.0, B1, D, dA); + LHS.addMatrixProduct(1.0, B1TD, B, 1.0); + + // Add drilling stiffness = Bd'*Kd*Bd * dA (LHS) + for (int i = 0; i < 24; i++) + for (int j = 0; j < 24; j++) + LHS(i, j) += Bd(i) * m_drill_stiffness * Bd(j) * dA; + } + + } // End of Gauss Loop + + // AGQI: static condensation + if ((options & OPT_RHS) || (options & OPT_LHS)) + { + static Matrix KQQ = Matrix(4, 4); + static Matrix KUQ_KQQ_inv = Matrix(24, 4); + KQQ = m_KQQ_inv; + int inv_res = KQQ.Invert(m_KQQ_inv); + KUQ_KQQ_inv.addMatrixProduct(0.0, m_KUQ, m_KQQ_inv, 1.0); + if (options & OPT_RHS) + RHS.addMatrixVector(1.0, KUQ_KQQ_inv, m_Q_residual, 1.0); + if (options & OPT_LHS) + LHS.addMatrixProduct(1.0, KUQ_KQQ_inv, m_KQU, -1.0); + } + + // Tranform LHS to global coordinate system + m_transformation->transformToGlobal(local_cs, UG, UL, LHS, RHS, (options & OPT_LHS)); + + // Subtract external loads if any + if ((options & OPT_RHS) && m_load) + RHS.addVector(1.0, *m_load, -1.0); + + // Done + return result; +} + +void ASDShellQ4::AGQIinitialize() +{ + // Global displacements + auto& UG = ASDShellQ4Globals::instance().UG; + m_transformation->computeGlobalDisplacements(UG); + + ASDShellQ4LocalCoordinateSystem local_cs = m_transformation->createLocalCoordinateSystem(UG); + + // Local displacements + auto& UL = ASDShellQ4Globals::instance().UL; + m_transformation->calculateLocalDisplacements(local_cs, UG, UL); + + // Initialize internal DOFs members + m_Q.Zero(); + m_Q_converged.Zero(); + m_U = UL; + m_U_converged = UL; +} + +void ASDShellQ4::AGQIupdate(const Vector& UL) +{ + // Compute incremental displacements + static Vector dUL(24); + dUL = UL; + dUL.addVector(1.0, m_U, -1.0); + + // Save current trial displacements + m_U = UL; + + // Update internal DOFs + static Vector temp(4); + temp.addMatrixVector(0.0, m_KQU, dUL, 1.0); + temp.addVector(1.0, m_Q_residual, -1.0); + m_Q.addMatrixVector(1.0, m_KQQ_inv, temp, -1.0); +} + +void ASDShellQ4::AGQIbeginGaussLoop(const ASDShellQ4LocalCoordinateSystem& reference_cs) +{ + // set to zero vectors and matrices for the static condensation + // of internal DOFs before proceding with gauss integration + m_KQU.Zero(); + m_KUQ.Zero(); + m_KQQ_inv.Zero(); + m_Q_residual.Zero(); + + // Some matrices/vectors + auto& N = ASDShellQ4Globals::instance().N; + auto& dN = ASDShellQ4Globals::instance().dN; + + // Jacobian + auto& jac = ASDShellQ4Globals::instance().jac; + + // this one is already computed in the caller method + auto& agq = ASDShellQ4Globals::instance().agq; + + // The AGQI uses incompatible modes and only the weak patch test is passed. + // Here we computed the mean Bq matrix for the enhanced strains. It will be subtracted + // from the gauss-wise Bq matrices to make this element pass the strict patch test: + // BQ = BQ - 1/A*int{BQ*dV} + auto& BQ_mean = ASDShellQ4Globals::instance().BQ_mean; + BQ_mean.Zero(); + double Atot = 0.0; + + // Gauss loop + std::array L; + for (int igauss = 0; igauss < 4; igauss++) + { + // Current integration point data + double xi = XI[igauss]; + double eta = ETA[igauss]; + double w = WTS[igauss]; + shapeFunctions(xi, eta, N); + shapeFunctionsNaturalDerivatives(xi, eta, dN); + jac.calculate(reference_cs, dN); + double dA = w * jac.detJ; + Atot += dA; + + // area coordinates of the gauss point (Eq 7) + L[0] = 0.25 * (1.0 - xi) * (agq.g[1] * (1.0 - eta) + agq.g[2] * (1.0 + eta)); + L[1] = 0.25 * (1.0 - eta) * (agq.g[3] * (1.0 - xi) + agq.g[2] * (1.0 + xi)); + L[2] = 0.25 * (1.0 + xi) * (agq.g[0] * (1.0 - eta) + agq.g[3] * (1.0 + eta)); + L[3] = 0.25 * (1.0 + eta) * (agq.g[0] * (1.0 - xi) + agq.g[1] * (1.0 + xi)); + + // strain matrix for internal dofs + for (int i = 0; i < 2; i++) + { + int j = i + 1; if (j > 3) j = 0; + int k = j + 1; if (k > 3) k = 0; + double NQX = (agq.b[i] * L[k] + agq.b[k] * L[i]) / agq.A / 2.0; + double NQY = (agq.c[i] * L[k] + agq.c[k] * L[i]) / agq.A / 2.0; + int index1 = i * 2; + int index2 = index1 + 1; + BQ_mean(0, index1) += NQX * dA; + BQ_mean(1, index2) += NQY * dA; + BQ_mean(2, index1) += NQY * dA; + BQ_mean(2, index2) += NQX * dA; + } + } + + // Average + BQ_mean /= Atot; +} + diff --git a/SRC/element/shell/ASDShellQ4.h b/SRC/element/shell/ASDShellQ4.h new file mode 100644 index 0000000000..27d7e80d0c --- /dev/null +++ b/SRC/element/shell/ASDShellQ4.h @@ -0,0 +1,192 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.10 $ +// $Date: 2020/05/18 22:51:21 $ + +// Original implementation: Massimo Petracca (ASDEA) +// +// A 4-node general shell element based on +// the AGQ6-I formulation for the membrane part, +// and the MITC4 formulation for the shear-deformable bending part. +// +// It supports both linear and corotational kinematics. Warped geometries +// can be modelled since this element is not assumed flat. +// +// References: +// +// 1 Chen, Xiao-Ming, et al. "Membrane elements insensitive to distortion +// using the quadrilateral area coordinate method." +// Computers & Structures 82.1 (2004): 35-54. +// http://www.paper.edu.cn/scholar/showpdf/MUT2ANwINTT0Ax5h +// +// 2 Dvorkin, Eduardo N., and Klaus-Jurgen Bathe. +// "A continuum mechanics based four-node shell element for +// general non-linear analysis." Engineering computations (1984). +// https://www.researchgate.net/profile/Eduardo_Dvorkin/publication/235313212_A_Continuum_mechanics_based_four-node_shell_element_for_general_nonlinear_analysis/links/00b7d52611d8813ffe000000.pdf +// +// 3 Bathe, Klaus-Jurgen, and Eduardo N. Dvorkin. +// "A four-node plate bending element based on Mindlin/Reissner plate theory +// and a mixed interpolation." +// International Journal for Numerical Methods in Engineering 21.2 (1985): 367-383. +// http://www.simytec.com/docs/Short_communicaion_%20four_node_plate.pdf +// +// 4 Hughes, Thomas JR, and F. Brezzi. +// "On drilling degrees of freedom." +// Computer methods in applied mechanics and engineering 72.1 (1989): 105-121. +// https://www.sciencedirect.com/science/article/pii/0045782589901242 +// +// Notes: +// +// - The AGQ6-I formulation greatly enhances the membrane behavior of the +// standard 4-node iso-parametric element. However it does not pass the constant-strain +// patch test as most of the enhanced elements based on incompatible-modes. +// In this implementation the enhancing BQ matrix is corrected to make the element +// pass the constant strain patch test. At each gauss point the BQ = BQ - 1/V*BQ_mean +// +// - The drilling DOF is treated using the Hughes-Brezzi formulation. The drilling +// stiffness is taken equal to the initial (elastic) in-plane section shear modulus. +// Taking the real shear modulus (and not a scaled version of it, as suggested in many +// articles) is mandatory to obtain a correct response for warped shells, i.e. when +// the drilling rotation affects the bending rotation. However using the full shear modulus +// deteriorates the element membrane behavior, making the element stiffer. For example, +// when using softening material models, this drilling stiffness makes the element lock +// failing in representing crack propagation correctly. +// Here we solved this problem using a reduced integration for the drilling part. However +// a pure reduced integration for the drilling DOFs, leads to 3 spurious zero-energy modes. +// Therefore we also include a fully integrated contribution of the drilling DOFs +// scaling the drilling stiffness by 1.0e-4, so just to suppress these spurious zero energy modes. +// + +#ifndef ASDShellQ4_h +#define ASDShellQ4_h + +#include +#include +#include +#include + +class SectionForceDeformation; +class ASDShellQ4Transformation; +class ASDShellQ4LocalCoordinateSystem; + +class ASDShellQ4 : public Element +{ + +public: + + // life cycle + ASDShellQ4(); + ASDShellQ4( + int tag, + int node1, + int node2, + int node3, + int node4, + SectionForceDeformation* section, + bool corotational = false); + virtual ~ASDShellQ4(); + + // domain + void setDomain(Domain* theDomain); + + // print + void Print(OPS_Stream& s, int flag); + + // methods dealing with nodes and number of external dof + int getNumExternalNodes() const; + const ID& getExternalNodes(); + Node** getNodePtrs(); + int getNumDOF(); + + // methods dealing with committed state and update + int commitState(); + int revertToLastCommit(); + int revertToStart(); + int update(); + + // methods to return the current linearized stiffness, + // damping and mass matrices + const Matrix& getTangentStiff(); + const Matrix& getInitialStiff(); + const Matrix& getMass(); + + // methods for applying loads + void zeroLoad(); + int addLoad(ElementalLoad* theLoad, double loadFactor); + int addInertiaLoadToUnbalance(const Vector& accel); + + // methods for obtaining resisting force (force includes elemental loads) + const Vector& getResistingForce(); + const Vector& getResistingForceIncInertia(); + + // public methods for element output + int sendSelf(int commitTag, Channel& theChannel); + int recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker); + + Response* setResponse(const char** argv, int argc, OPS_Stream& output); + int getResponse(int responseID, Information& eleInfo); + + int setParameter(const char** argv, int argc, Parameter& param); + +private: + + // internal method to compute everything using switches... + int calculateAll(Matrix& LHS, Vector& RHS, int options); + + void AGQIinitialize(); + void AGQIupdate(const Vector& UL); + void AGQIbeginGaussLoop(const ASDShellQ4LocalCoordinateSystem& reference_cs); + +private: + + // cross sections + SectionForceDeformation* m_sections[4] = { nullptr, nullptr, nullptr, nullptr }; + + // nodal ids + ID m_node_ids = ID(4); + + // coordinate transformation + ASDShellQ4Transformation* m_transformation = nullptr; + + // vectors for applying load (allocated only if necessary) + Vector* m_load = nullptr; + + // drilling strain for the indipendent rotation field (Hughes-Brezzi) + double m_drill_strain[4] = { 0.0, 0.0, 0.0, 0.0 }; + double m_drill_stiffness = 0.0; + + // section orientation with respect to the local coordinate system + double m_angle = 0.0; + + // members for non-linear treatement of AGQI internal DOFs: + // it has 24 displacement DOFs + // and 4 internal DOFs for membrane enhancement + Vector m_Q = Vector(4); + Vector m_Q_converged = Vector(4); + Vector m_U = Vector(24); + Vector m_U_converged = Vector(24); + Vector m_Q_residual = Vector(4); + Matrix m_KQQ_inv = Matrix(4, 4); + Matrix m_KQU = Matrix(4, 24); // L = G'*C*B + Matrix m_KUQ = Matrix(24, 4); // L^T = B'*C'*G +}; + +#endif // ASDShellQ4_h diff --git a/SRC/element/shell/ASDShellQ4CorotationalTransformation.h b/SRC/element/shell/ASDShellQ4CorotationalTransformation.h new file mode 100644 index 0000000000..c2990bd89d --- /dev/null +++ b/SRC/element/shell/ASDShellQ4CorotationalTransformation.h @@ -0,0 +1,598 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.10 $ +// $Date: 2020/05/18 22:51:21 $ + +// Original implementation: Massimo Petracca (ASDEA) +// +// Implementation of a corotational coordinate transformation 4-node shells +// + +#ifndef ASDShellQ4CorotationalTransformation_h +#define ASDShellQ4CorotationalTransformation_h + +#include +#include + +// this is experimental: it fits the corotational frame following the polar +// decomposition rather than the 1-2 side allignement as per Felippa's work +#define USE_POLAR_DECOMP_ALLIGN + +/** \brief ASDShellQ4CorotationalTransformation +* +* This class represents a corotational (nonlinear) coordinate transformation +* that can be used by any element whose geometry is a QUAD 4 in 3D space, +* with 6 D.O.F.s per node. +* Its main aim is to: +* 1) Create the local coordinate system +* 2) Transform the incoming global displacements in local coordinate system +* removing rigid body displacements and rotations. +* 3) Transform the outgoing matrices and vectors in global coordinate system +* with rigid body displacements and rotations. +* +* - Makes use of Quaternions (Euler Parameters) to parametrize finite rotations +* in an efficient and robust way. +* +* References: +* +* - C.A.Felippa,B.Haugen, "Unified formulation of small-strain corotational +* finite elements: I. Theory", +* CU-CAS-05-02, January 2005 +* - C.A.Felippa, AFEM.Ch.38, "Quadrilateral Shell Elements", +* Chapter 5 of B.Haugen's Thesis. +* link: http://www.colorado.edu/engineering/CAS/courses.d/AFEM.d/ +*/ +class ASDShellQ4CorotationalTransformation : public ASDShellQ4Transformation +{ + +public: + + typedef ASDVector3 Vector3Type; + + typedef ASDQuaternion QuaternionType; + + typedef Vector VectorType; + + typedef Matrix MatrixType; + + typedef std::array NodeContainerType; + +public: + + ASDShellQ4CorotationalTransformation() + : ASDShellQ4Transformation() + { + } + + virtual ~ASDShellQ4CorotationalTransformation() + { + } + +public: + + virtual ASDShellQ4Transformation* create()const + { + return new ASDShellQ4CorotationalTransformation(); + } + + virtual bool isLinear() const + { + return false; + } + + virtual void revertToStart() + { + // create the reference (undeformed configuration) coordinate system + ASDShellQ4LocalCoordinateSystem LCS = createReferenceCoordinateSystem(); + + // save reference orientation and center + m_Q0 = QuaternionType::FromRotationMatrix(LCS.Orientation()); + m_C0 = LCS.Center(); + + // save initial rotations, no need to take current rotation + // since we will remove the initial ones (themselves)... + for (int i = 0; i < 4; i++) + { + m_RV[i] = Vector3Type(0.0, 0.0, 0.0); + m_QN[i] = QuaternionType::FromRotationVector(m_RV[i]); + + m_RV_converged[i] = m_RV[i]; + m_QN_converged[i] = m_QN[i]; + } + } + + virtual void setDomain(Domain* domain, const ID& node_ids) + { + // call base class setDomain to + // get nodes and save initial displacements and rotations + ASDShellQ4Transformation::setDomain(domain, node_ids); + + // init state variables + revertToStart(); + } + + virtual void revertToLastCommit() + { + for (int i = 0; i < 4; i++) + { + m_RV[i] = m_RV_converged[i]; + m_QN[i] = m_QN_converged[i]; + } + } + + virtual void commit() + { + for (int i = 0; i < 4; i++) + { + m_RV_converged[i] = m_RV[i]; + m_QN_converged[i] = m_QN[i]; + } + } + + virtual void update(const VectorType& globalDisplacements) + { + for (int i = 0; i < 4; i++) + { + // compute current rotation vector removing initial rotations if any + Vector3Type currentRotVec; + int index = i * 6; + currentRotVec(0) = globalDisplacements(index + 3) - m_U0(index + 3); + currentRotVec(1) = globalDisplacements(index + 4) - m_U0(index + 4); + currentRotVec(2) = globalDisplacements(index + 5) - m_U0(index + 5); + + // compute incremental rotation vector + Vector3Type incrementalRotation = currentRotVec - m_RV[i]; + + // save current rotation vector + m_RV[i] = currentRotVec; + + // compute incremental quaternion from incremental rotation vector + QuaternionType incrementalQuaternion = QuaternionType::FromRotationVector(incrementalRotation); + + // update nodal quaternion + m_QN[i] = incrementalQuaternion * m_QN[i]; + } + } + + virtual ASDShellQ4LocalCoordinateSystem createLocalCoordinateSystem(const VectorType& globalDisplacements)const + { + // reference coordinate system + ASDShellQ4LocalCoordinateSystem a = createReferenceCoordinateSystem(); + + // compute nodal positions at current configuration removing intial displacements if any + std::array def = { + Vector3Type(m_nodes[0]->getCrds()), + Vector3Type(m_nodes[1]->getCrds()), + Vector3Type(m_nodes[2]->getCrds()), + Vector3Type(m_nodes[3]->getCrds()) + }; + for (int i = 0; i < 4; i++) { + int index = i * 6; + Vector3Type& iP = def[i]; + iP(0) += globalDisplacements(index) - m_U0(index); + iP(1) += globalDisplacements(index + 1) - m_U0(index + 1); + iP(2) += globalDisplacements(index + 2) - m_U0(index + 2); + } + + // current coordinate system + ASDShellQ4LocalCoordinateSystem b(def[0], def[1], def[2], def[3]); + +#ifndef USE_POLAR_DECOMP_ALLIGN + return b; +#endif // !USE_POLAR_DECOMP_ALLIGN + + double aX1 = a.X1(); double aY1 = a.Y1(); + double bX1 = b.X1(); double bY1 = b.Y1(); + double aX2 = a.X2(); double aY2 = a.Y2(); + double bX2 = b.X2(); double bY2 = b.Y2(); + double aX3 = a.X3(); double aY3 = a.Y3(); + double bX3 = b.X3(); double bY3 = b.Y3(); + double aX4 = a.X4(); double aY4 = a.Y4(); + double bX4 = b.X4(); double bY4 = b.Y4(); + + // now we are in the local coordinate systems (reference and current), i.e. we are looking in the local Z direction + // which is the same for both coordinate systems. + // now we can compute the 2D deformation gradient between the 2 configurations, at the element center. + + double C1 = 1.0 / (aX1 * aY2 - aX2 * aY1 - aX1 * aY4 + aX2 * aY3 - aX3 * aY2 + aX4 * aY1 + aX3 * aY4 - aX4 * aY3); + double C2 = bY1 / 4.0 + bY2 / 4.0 - bY3 / 4.0 - bY4 / 4.0; + double C3 = bY1 / 4.0 - bY2 / 4.0 - bY3 / 4.0 + bY4 / 4.0; + double C4 = bX1 / 4.0 + bX2 / 4.0 - bX3 / 4.0 - bX4 / 4.0; + double C5 = bX1 / 4.0 - bX2 / 4.0 - bX3 / 4.0 + bX4 / 4.0; + double C6 = aX1 + aX2 - aX3 - aX4; + double C7 = aX1 - aX2 - aX3 + aX4; + double C8 = aY1 + aY2 - aY3 - aY4; + double C9 = aY1 - aY2 - aY3 + aY4; + double f11 = 2.0 * C1 * C5 * C8 - 2.0 * C1 * C4 * C9; + double f12 = 2.0 * C1 * C4 * C7 - 2.0 * C1 * C5 * C6; + double f21 = 2.0 * C1 * C3 * C8 - 2.0 * C1 * C2 * C9; + double f22 = 2.0 * C1 * C2 * C7 - 2.0 * C1 * C3 * C6; + + // now we can extrapolate the rotation angle that makes this deformation gradient symmetric. + // F = R*U -> find R such that R'*F = U + double alpha = std::atan2(f21 - f12, f11 + f22); + + // this final coordinate system is the one in which + // the deformation gradient is equal to the stretch tensor + return ASDShellQ4LocalCoordinateSystem(def[0], def[1], def[2], def[3], alpha); + } + + virtual void calculateLocalDisplacements( + const ASDShellQ4LocalCoordinateSystem& LCS, + const VectorType& globalDisplacements, + VectorType& localDisplacements) + { + // orientation and center of current local coordinate system + QuaternionType Q = QuaternionType::FromRotationMatrix(LCS.Orientation()); + const Vector3Type& C = LCS.Center(); + + for (int i = 0; i < 4; i++) + { + int index = i * 6; + + // centered undeformed position + Vector3Type X0 = Vector3Type(m_nodes[i]->getCrds()); + X0 -= m_C0; + + // centered deformed position + Vector3Type X = X0 + Vector3Type(globalDisplacements, index); + X -= C; + + // get deformational displacements + Q.rotateVector(X); + m_Q0.rotateVector(X0); + Vector3Type deformationalDisplacements = X - X0; + + localDisplacements[index] = deformationalDisplacements[0]; + localDisplacements[index + 1] = deformationalDisplacements[1]; + localDisplacements[index + 2] = deformationalDisplacements[2]; + + // get deformational rotations + QuaternionType Qd = Q * m_QN[i] * m_Q0.conjugate(); + Qd.toRotationVector( + localDisplacements[index + 3], + localDisplacements[index + 4], + localDisplacements[index + 5]); + } + } + + virtual void transformToGlobal( + const ASDShellQ4LocalCoordinateSystem& LCS, + const VectorType& globalDisplacements, + const VectorType& localDisplacements, + MatrixType& LHS, + VectorType& RHS, + bool LHSrequired) + { + // Get the total rotation matrix (local - to - global) + // Note: do NOT include the warpage correction matrix! + // Explanation: + // The Warpage correction matrix computed by the LocalCoordinateSystem is a Linear Projector. + // It should be used in a LinearCoordinateTransformation. + // Here instead we already calculate a nonlinear Projector (P = Pu - S * G)! + + static MatrixType T(24, 24); + LCS.ComputeTotalRotationMatrix(T); + + // Form all matrices: + // S: Spin-Fitter matrix + // G: Spin-Lever matrix + // P: Projector (Translational & Rotational) + static MatrixType P(24, 24); + static MatrixType S(24, 3); + static MatrixType G(3, 24); + EICR::Compute_Pt(4, P); + EICR::Compute_S(LCS.Nodes(), S); + RotationGradient(LCS, globalDisplacements, G); + P.addMatrixProduct(1.0, S, G, -1.0); // P -= S*G + + // Compute the projected local forces ( pe = P' * RHS ). + // Note: here the RHS is already given as a residual vector -> - internalForces -> (pe = - Ke * U) + // so projectedLocalForces = - P' * Ke * U + + static VectorType projectedLocalForces(24); + projectedLocalForces.addMatrixTransposeVector(0.0, P, RHS, 1.0); + + // Compute the Right-Hand-Side vector in global coordinate system (- T' * P' * Km * U). + // At this point the computation of the Right-Hand-Side is complete. + + RHS.addMatrixTransposeVector(0.0, T, projectedLocalForces, 1.0); + + // Begin the computation of the Left-Hand-Side Matrix : + + if (!LHSrequired) + return; // avoid useless calculations! + + // H: Axial Vector Jacobian + static MatrixType H(24, 24); + EICR::Compute_H(localDisplacements, H); + + // Step 1: ( K.M : Material Stiffness Matrix ) + // Apply the projector to the Material Stiffness Matrix (Ke = P' * Km * H * P) + // At this point 'LHS' contains the 'projected' Material Stiffness matrix + // in local corotational coordinate system + + static MatrixType temp(24, 24); + temp.addMatrixProduct(0.0, LHS, H, 1.0); + LHS.addMatrixProduct(0.0, temp, P, 1.0); + temp.addMatrixTransposeProduct(0.0, P, LHS, 1.0); + LHS = temp; + + // Step 2: ( K.GP: Equilibrium Projection Geometric Stiffness Matrix ) + // First assemble the 'Fnm' matrix with the Spins of the nodal forces. + // Actually at this point the 'Fnm' Matrix is the 'Fn' Matrix, + // because it only contains the spins of the 'translational' forces. + // At this point 'LHS' contains also this term of the Geometric stiffness + // (Ke = (P' * Km * H * P) - (G' * Fn' * P)) + + static MatrixType Fnm(24, 3); + Fnm.Zero(); + EICR::Spin_AtRow(projectedLocalForces, Fnm, 0); + EICR::Spin_AtRow(projectedLocalForces, Fnm, 6); + EICR::Spin_AtRow(projectedLocalForces, Fnm, 12); + EICR::Spin_AtRow(projectedLocalForces, Fnm, 18); + + static MatrixType FnmT(3, 24); + FnmT.addMatrixTranspose(0.0, Fnm, 1.0); + + temp.addMatrixTransposeProduct(0.0, G, FnmT, 1.0); + LHS.addMatrixProduct(1.0, temp, P, 1.0); // note: '+' not '-' because the RHS already has the negative sign + + // Step 3: ( K.GR: Rotational Geometric Stiffness Matrix ) + // Add the Spins of the nodal moments to 'Fnm'. + // At this point 'LHS' contains also this term of the Geometric stiffness + // (Ke = (P' * Km * H * P) - (G' * Fn' * P) - (Fnm * G)) + + EICR::Spin_AtRow(projectedLocalForces, Fnm, 3); + EICR::Spin_AtRow(projectedLocalForces, Fnm, 9); + EICR::Spin_AtRow(projectedLocalForces, Fnm, 15); + EICR::Spin_AtRow(projectedLocalForces, Fnm, 21); + + LHS.addMatrixProduct(1.0, Fnm, G, 1.0); // note: '+' not '-' because the RHS already has the negative sign + + // Step 4: (Global Stiffness Matrix) + // Transform the LHS to the Global coordinate system. + // T' * [(P' * Km * H * P) - (G' * Fn' * P) - (Fnm * G)] * T + temp.addMatrixProduct(0.0, LHS, T, 1.0); + LHS.addMatrixTransposeProduct(0.0, T, temp, 1.0); + } + + virtual void transformToGlobal( + const ASDShellQ4LocalCoordinateSystem& LCS, + MatrixType& LHS, + VectorType& RHS, + bool LHSrequired) + { + static VectorType globalDisplacements(24); + static VectorType localDisplacements(24); + computeGlobalDisplacements(globalDisplacements); + calculateLocalDisplacements(LCS, globalDisplacements, localDisplacements); + transformToGlobal(LCS, globalDisplacements, localDisplacements, LHS, RHS, LHSrequired); + } + + virtual int internalDataSize() const + { + // 24 -> initial displacement + + // 9*4 -> 9 quaternions + + // 9*3 -> 9 3d vectors + return 87; + } + + virtual void saveInternalData(VectorType& v, int pos) const + { + if ((v.Size() - pos) < internalDataSize()) { + opserr << "ASDShellQ4CorotationalTransformation - failed to save internal data: vector too small\n"; + exit(-1); + } + + // 24 -> initial displacement + + for (int i = 0; i < 24; i++) + v(pos++) = m_U0(i); + + // 9*4 -> 9 quaternions + + auto lamq = [&v, &pos](const QuaternionType& x) { + v(pos++) = x.w(); + v(pos++) = x.x(); + v(pos++) = x.y(); + v(pos++) = x.z(); + }; + lamq(m_Q0); + for (int i = 0; i < 4; i++) + lamq(m_QN[i]); + for (int i = 0; i < 4; i++) + lamq(m_QN_converged[i]); + + // 9*3 -> 9 3d vectors + + auto lamv = [&v, &pos](const Vector3Type& x) { + v(pos++) = x.x(); + v(pos++) = x.y(); + v(pos++) = x.z(); + }; + lamv(m_C0); + for (int i = 0; i < 4; i++) + lamv(m_RV[i]); + for (int i = 0; i < 4; i++) + lamv(m_RV_converged[i]); + } + + virtual void restoreInternalData(const VectorType& v, int pos) + { + if ((v.Size() - pos) < internalDataSize()) { + opserr << "ASDShellQ4CorotationalTransformation - failed to restore internal data: vector too small\n"; + exit(-1); + } + + // 24 -> initial displacement + + for (int i = 0; i < 24; i++) + m_U0(i) = v(pos++); + + // 9*4 -> 9 quaternions + + auto lamq = [&v, &pos](QuaternionType& x) { + x = QuaternionType(v(pos++), v(pos++), v(pos++), v(pos++)); + }; + lamq(m_Q0); + for (int i = 0; i < 4; i++) + lamq(m_QN[i]); + for (int i = 0; i < 4; i++) + lamq(m_QN_converged[i]); + + // 9*3 -> 9 3d vectors + + auto lamv = [&v, &pos](Vector3Type& x) { + x = Vector3Type(v(pos++), v(pos++), v(pos++)); + }; + lamv(m_C0); + for (int i = 0; i < 4; i++) + lamv(m_RV[i]); + for (int i = 0; i < 4; i++) + lamv(m_RV_converged[i]); + } + +private: + + /** + * Computes the Spin Fitter Matrix. + * This is the only matrix not included in the EICR, because it depends on how + * the corotational frame follows the element. + * This implementation works for the fitting based on polar decomposition. + * For the moment the gradient is calculated numerically (perturbation). + * TODO: Find a closed form of the derivative. + * @return the Spin Fitter Matrix + */ + inline void RotationGradient( + const ASDShellQ4LocalCoordinateSystem& LCS, + const VectorType& globalDisplacements, + MatrixType& G) + { + G.Zero(); + +#ifdef USE_POLAR_DECOMP_ALLIGN + + /** + Note: when attaching the local system using the polar decomposition, it turns out + that the G matrix should be exactly 0! + */ + + //// perturbation relative to initial area + //double pert = std::sqrt(createReferenceCoordinateSystem().Area()) * 1.0e-8; + + //// un-perturbed coordinate system + //auto CS0 = createLocalCoordinateSystem(globalDisplacements); + //Vector3Type e30 = CS0.Vz(); + //Vector3Type e10 = CS0.Vx(); + //QuaternionType Q0 = QuaternionType::FromRotationMatrix(CS0.Orientation()); + + //// perturbed displacement vector + //static Vector UGP(24); + //UGP = globalDisplacements; + + //// for each node... + //for (int i = 0; i < 4; i++) + //{ + // int index = i * 6; + + // // for each component in [x, y, z] ... + // for (int j = 0; j < 3; j++) + // { + // // apply perturbation + // UGP(index + j) += pert; + + // // current coordinate system (perturbed at node i component j) + // auto CSi = createLocalCoordinateSystem(UGP); + + // // save the (numerical) rotation gradient + + // Vector3Type e3 = CSi.Vz();// - e30; + // Vector3Type e1 = CSi.Vx();// - e10; + // Q0.rotateVector(e3); + // Q0.rotateVector(e1); + + // G(0, index + j) = e3(1) / pert; // - d(e3.y)/dxj , where xj is x,y,z for j=0,1,2 + // G(1, index + j) = -e3(0) / pert; // + d(e3.x)/dxj , where xj is x,y,z for j=0,1,2 + // G(2, index + j) = -e1(1) / pert; // + d(e1.y)/dxj , where xj is x,y,z for j=0,1,2 + + // UGP(index + j) = globalDisplacements(index + j); // restore the current coordinate + // } + //} + +#else // !USE_POLAR_DECOMP_ALLIGN + + const auto& P1 = LCS.P1(); + const auto& P2 = LCS.P2(); + const auto& P3 = LCS.P3(); + const auto& P4 = LCS.P4(); + + double Ap = 2.0 * LCS.Area(); + double m = 1.0 / Ap; + + Vector3Type D12(P2 - P1); + Vector3Type D24(P4 - P2); + Vector3Type D13(P3 - P1); + + double x42 = D24(0); + double x24 = -x42; + double y42 = D24(1); + double y24 = -y42; + double x31 = D13(0); + double x13 = -x31; + double y31 = D13(1); + double y13 = -y31; + + // Note, assuming the input vectors are in local CR, + // l12 is the length of the side 1-2 projected onto the xy plane. + double l12 = std::sqrt(D12(0) * D12(0) + D12(1) * D12(1)); + + // G1 + + G(0, 2) = x42 * m; + G(1, 2) = y42 * m; + G(2, 1) = -1.0 / l12; + + // G2 + + G(0, 8) = x13 * m; + G(1, 8) = y13 * m; + G(2, 7) = 1.0 / l12; + + // G3 + + G(0, 14) = x24 * m; + G(1, 14) = y24 * m; + + // G4 + + G(0, 20) = x31 * m; + G(1, 20) = y31 * m; + +#endif // USE_POLAR_DECOMP_ALLIGN + + } + +private: + + QuaternionType m_Q0; + Vector3Type m_C0; + std::array m_QN; + std::array m_RV; + std::array m_QN_converged; + std::array m_RV_converged; +}; + +#endif // !ASDShellQ4CorotationalTransformation_h diff --git a/SRC/element/shell/ASDShellQ4LocalCoordinateSystem.h b/SRC/element/shell/ASDShellQ4LocalCoordinateSystem.h new file mode 100644 index 0000000000..8b204403d2 --- /dev/null +++ b/SRC/element/shell/ASDShellQ4LocalCoordinateSystem.h @@ -0,0 +1,226 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.10 $ +// $Date: 2020/05/18 22:51:21 $ + +// Original implementation: Massimo Petracca (ASDEA) +// +// Implementation of a local coordinate system for 4-node shells +// + +#ifndef ASDShellQ4LocalCoordinateSystem_h +#define ASDShellQ4LocalCoordinateSystem_h + +#include +#include +#include + +/** \brief ASDShellQ4LocalCoordinateSystem +* +* This class represent the local coordinate system of any element whose geometry +* is a 4-node Quadrilateral in 3D space +*/ +class ASDShellQ4LocalCoordinateSystem +{ + +public: + + typedef ASDVector3 Vector3Type; + + typedef ASDQuaternion QuaternionType; + + typedef std::vector Vector3ContainerType; + + typedef Matrix MatrixType; + +public: + + ASDShellQ4LocalCoordinateSystem( + const Vector3Type& P1global, + const Vector3Type& P2global, + const Vector3Type& P3global, + const Vector3Type& P4global, + double alpha = 0.0) + : m_P(4) + , m_orientation(3, 3) + { + // compute the central point + m_center = P1global; + m_center += P2global; + m_center += P3global; + m_center += P4global; + m_center *= 0.25; + + // compute the diagonal vectors + Vector3Type d13 = P3global - P1global; + Vector3Type d24 = P4global - P2global; + + // compute the Normal vector at the element center + // as the cross product of the 2 diagonals. + // While normalizing the normal vector save its norm to compute the area. + // Note: the norm should be divided by 2 because it's computed from the + // cross product of the diagonals, which gives twice the area! + Vector3Type e3 = d13.cross(d24); + m_area = e3.normalize(); + m_area /= 2.0; + + // compute the local X direction parallel to the projection of the side 1-2 onto + // the local xy plane. + Vector3Type e1 = P2global - P1global; + double e1_dot_e3 = e1.dot(e3); + e1 -= e1_dot_e3 * e3; + + // if user defined local rotation is included... + if (std::abs(alpha) > 0.0) + QuaternionType::FromAxisAngle(e3(0), e3(1), e3(2), alpha).rotateVector(e1); + + e1.normalize(); + + // finally compute the local Y direction to be orthogonal to both X and Z local directions + Vector3Type e2 = e3.cross(e1); + e2.normalize(); + + // form the 3x3 transformation matrix (the transposed actually...) + for (int i = 0; i < 3; i++) + { + m_orientation(0, i) = e1(i); + m_orientation(1, i) = e2(i); + m_orientation(2, i) = e3(i); + } + + // transform global coordinates to the local coordinate system + for (int i = 0; i < 3; i++) + { + m_P[0](i) = m_orientation(i, 0) * (P1global(0) - m_center(0)) + m_orientation(i, 1) * (P1global(1) - m_center(1)) + m_orientation(i, 2) * (P1global(2) - m_center(2)); + m_P[1](i) = m_orientation(i, 0) * (P2global(0) - m_center(0)) + m_orientation(i, 1) * (P2global(1) - m_center(1)) + m_orientation(i, 2) * (P2global(2) - m_center(2)); + m_P[2](i) = m_orientation(i, 0) * (P3global(0) - m_center(0)) + m_orientation(i, 1) * (P3global(1) - m_center(1)) + m_orientation(i, 2) * (P3global(2) - m_center(2)); + m_P[3](i) = m_orientation(i, 0) * (P4global(0) - m_center(0)) + m_orientation(i, 1) * (P4global(1) - m_center(1)) + m_orientation(i, 2) * (P4global(2) - m_center(2)); + } + } + +public: + + inline const Vector3ContainerType& Nodes()const { return m_P; } + + inline const Vector3Type& P1()const { return m_P[0]; } + inline const Vector3Type& P2()const { return m_P[1]; } + inline const Vector3Type& P3()const { return m_P[2]; } + inline const Vector3Type& P4()const { return m_P[3]; } + inline const Vector3Type& Center()const { return m_center; } + + inline double X1()const { return m_P[0][0]; } + inline double X2()const { return m_P[1][0]; } + inline double X3()const { return m_P[2][0]; } + inline double X4()const { return m_P[3][0]; } + + inline double Y1()const { return m_P[0][1]; } + inline double Y2()const { return m_P[1][1]; } + inline double Y3()const { return m_P[2][1]; } + inline double Y4()const { return m_P[3][1]; } + + inline double Z1()const { return m_P[0][2]; } + inline double Z2()const { return m_P[1][2]; } + inline double Z3()const { return m_P[2][2]; } + inline double Z4()const { return m_P[3][2]; } + + inline double X(size_t i)const { return m_P[i][0]; } + inline double Y(size_t i)const { return m_P[i][1]; } + inline double Z(size_t i)const { return m_P[i][2]; } + + inline double Area()const { return m_area; } + + inline const MatrixType& Orientation()const { return m_orientation; } + + inline Vector3Type Vx()const { return Vector3Type(m_orientation(0, 0), m_orientation(0, 1), m_orientation(0, 2)); } + inline Vector3Type Vy()const { return Vector3Type(m_orientation(1, 0), m_orientation(1, 1), m_orientation(1, 2)); } + inline Vector3Type Vz()const { return Vector3Type(m_orientation(2, 0), m_orientation(2, 1), m_orientation(2, 2)); } + + inline double WarpageFactor()const { return Z1(); } + inline bool IsWarped()const { return std::abs(WarpageFactor()) > 0.0; } + + inline void ComputeTotalRotationMatrix(MatrixType& R)const + { + constexpr size_t mat_size = 24; + if (R.noRows() != mat_size || R.noCols() != mat_size) + R.resize(mat_size, mat_size); + + R.Zero(); + + for (size_t k = 0; k < 8; k++) + { + size_t i = k * 3; + R(i, i) = m_orientation(0, 0); R(i, i + 1) = m_orientation(0, 1); R(i, i + 2) = m_orientation(0, 2); + R(i + 1, i) = m_orientation(1, 0); R(i + 1, i + 1) = m_orientation(1, 1); R(i + 1, i + 2) = m_orientation(1, 2); + R(i + 2, i) = m_orientation(2, 0); R(i + 2, i + 1) = m_orientation(2, 1); R(i + 2, i + 2) = m_orientation(2, 2); + } + } + + inline void ComputeTotalWarpageMatrix(MatrixType& W, double wf)const + { + constexpr size_t mat_size = 24; + if (W.noRows() != mat_size || W.noCols() != mat_size) + W.resize(mat_size, mat_size); + + W.Zero(); + for (size_t i = 0; i < mat_size; i++) + W(i, i) = 1.0; + + W(0, 4) = -wf; + W(1, 3) = wf; + + W(6, 10) = wf; + W(7, 9) = -wf; + + W(12, 16) = -wf; + W(13, 15) = wf; + + W(18, 22) = wf; + W(19, 21) = -wf; + } + + inline void ComputeTotalWarpageMatrix(MatrixType& W)const + { + ComputeTotalWarpageMatrix(W, WarpageFactor()); + } + +private: + + Vector3ContainerType m_P; + Vector3Type m_center; + MatrixType m_orientation; + double m_area; + +}; + +template +inline static TStream& operator << (TStream& s, const ASDShellQ4LocalCoordinateSystem& lc) +{ + s << "Points:\n"; + s << "["; + for (size_t i = 0; i < 4; i++) { + s << " (" << lc.X(i) << ", " << lc.Y(i) << ") "; + } + s << "]"; + s << "Normal: " << lc.Vz() << "\n"; + return s; +} + +#endif // !ASDShellQ4LocalCoordinateSystem_h diff --git a/SRC/element/shell/ASDShellQ4Transformation.h b/SRC/element/shell/ASDShellQ4Transformation.h new file mode 100644 index 0000000000..c47d507c06 --- /dev/null +++ b/SRC/element/shell/ASDShellQ4Transformation.h @@ -0,0 +1,247 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.10 $ +// $Date: 2020/05/18 22:51:21 $ + +// Original implementation: Massimo Petracca (ASDEA) +// +// Implementation of a linear coordinate transformation 4-node shells +// + +#ifndef ASDShellQ4Transformation_h +#define ASDShellQ4Transformation_h + +#include +#include +#include + +/** \brief ASDShellQ4Transformation +* +* This class represents a basic (linear) coordinate transformation that can be used +* by any element whose geometry is a QUAD 4 in 3D space, with 6 D.O.F.s per node. +* Its main aim is to: +* 1) Create the local coordinate system +* 2) Transform the incoming global displacements in local coordinate system +* 3) Transform the outgoing matrices and vectors in global coordinate system +*/ +class ASDShellQ4Transformation +{ + +public: + + typedef ASDVector3 Vector3Type; + + typedef ASDQuaternion QuaternionType; + + typedef Vector VectorType; + + typedef Matrix MatrixType; + + typedef std::array NodeContainerType; + +public: + + ASDShellQ4Transformation() + { + } + + virtual ~ASDShellQ4Transformation() + { + } + +private: + + ASDShellQ4Transformation(const ASDShellQ4Transformation& other) = delete; + + ASDShellQ4Transformation& operator = (const ASDShellQ4Transformation& other) = delete; + +public: + + virtual ASDShellQ4Transformation* create()const + { + return new ASDShellQ4Transformation(); + } + + virtual bool isLinear() const + { + return true; + } + + virtual void revertToStart() + { + } + + virtual void setDomain(Domain* domain, const ID& node_ids) + { + // get nodes and save initial displacements and rotations + for (size_t i = 0; i < 4; i++) { + m_nodes[i] = domain->getNode(node_ids(i)); + if (m_nodes[i] == nullptr) { + opserr << "ASDShellQ4Transformation::setDomain - no node " << node_ids(i) + << " exists in the model\n"; + exit(-1); + } + const Vector& iU = m_nodes[i]->getTrialDisp(); + if (iU.Size() != 6) { + opserr << "ASDShellQ4Transformation::setDomain - node " << node_ids(i) + << " has " << iU.Size() << " DOFs, while 6 are expected\n"; + exit(-1); + } + size_t index = i * 6; + for (size_t j = 0; j < 6; j++) + m_U0(index + j) = iU(j); + } + } + + virtual void revertToLastCommit() + { + } + + virtual void commit() + { + } + + virtual void update(const VectorType& globalDisplacements) + { + } + + virtual ASDShellQ4LocalCoordinateSystem createReferenceCoordinateSystem()const + { + // the reference coordinate system in the underformed configuration + // using the default alignment to the first column of the jacobian at center + return ASDShellQ4LocalCoordinateSystem( + Vector3Type(m_nodes[0]->getCrds()), + Vector3Type(m_nodes[1]->getCrds()), + Vector3Type(m_nodes[2]->getCrds()), + Vector3Type(m_nodes[3]->getCrds()) + ); + } + + virtual ASDShellQ4LocalCoordinateSystem createLocalCoordinateSystem(const VectorType& globalDisplacements)const + { + // same as reference + return createReferenceCoordinateSystem(); + } + + virtual void computeGlobalDisplacements(VectorType& globalDisplacements) const + { + for (int i = 0; i < 4; i++) { + int index = i * 6; + const VectorType& iU = m_nodes[i]->getTrialDisp(); + for (int j = 0; j < 6; j++) { + globalDisplacements(index + j) = iU(j) - m_U0(index + j); + } + } + } + + virtual const MatrixType& computeTransformationMatrix(const ASDShellQ4LocalCoordinateSystem& LCS) const + { + static MatrixType R(24, 24); + static MatrixType T(24, 24); + static MatrixType W(24, 24); + if (LCS.IsWarped()) { + LCS.ComputeTotalRotationMatrix(R); + LCS.ComputeTotalWarpageMatrix(W); + T.addMatrixProduct(0.0, W, R, 1.0); + } + else { + LCS.ComputeTotalRotationMatrix(T); + } + return T; + } + + virtual void calculateLocalDisplacements( + const ASDShellQ4LocalCoordinateSystem& LCS, + const VectorType& globalDisplacements, + VectorType& localDisplacements) + { + const MatrixType& R = computeTransformationMatrix(LCS); + localDisplacements.addMatrixVector(0.0, R, globalDisplacements, 1.0); + } + + virtual void transformToGlobal( + const ASDShellQ4LocalCoordinateSystem& LCS, + const VectorType& globalDisplacements, + const VectorType& localDisplacements, + MatrixType& LHS, + VectorType& RHS, + bool LHSrequired) + { + static MatrixType RT_LHS(24, 24); + static VectorType RHScopy(24); + const MatrixType& R = computeTransformationMatrix(LCS); + RHScopy = RHS; + RHS.addMatrixTransposeVector(0.0, R, RHScopy, 1.0); + if (LHSrequired) { + RT_LHS.addMatrixTransposeProduct(0.0, R, LHS, 1.0); + LHS.addMatrixProduct(0.0, RT_LHS, R, 1.0); + } + } + + virtual void transformToGlobal( + const ASDShellQ4LocalCoordinateSystem& LCS, + MatrixType& LHS, + VectorType& RHS, + bool LHSrequired) + { + static VectorType dummy; + transformToGlobal(LCS, dummy, dummy, LHS, RHS, LHSrequired); + } + + virtual int internalDataSize() const + { + // just the size of the initial displacements + return 24; + } + + virtual void saveInternalData(VectorType& v, int pos) const + { + if ((v.Size() - pos) < internalDataSize()) { + opserr << "ASDShellQ4Transformation - failed to save internal data: vector too small\n"; + exit(-1); + } + for (int i = 0; i < 24; i++) + v(pos++) = m_U0(i); + } + + virtual void restoreInternalData(const VectorType& v, int pos) + { + if ((v.Size() - pos) < internalDataSize()) { + opserr << "ASDShellQ4Transformation - failed to restore internal data: vector too small\n"; + exit(-1); + } + for (int i = 0; i < 24; i++) + m_U0(i) = v(pos++); + } + +public: + + inline const NodeContainerType& getNodes()const { return m_nodes; } + inline NodeContainerType& getNodes() { return m_nodes; } + +protected: + + NodeContainerType m_nodes = { {nullptr, nullptr, nullptr, nullptr} }; + Vector m_U0 = Vector(24); +}; + +#endif // !ASDShellQ4Transformation_h + diff --git a/SRC/element/shell/Makefile b/SRC/element/shell/Makefile index cd9f1e2942..25ae629957 100644 --- a/SRC/element/shell/Makefile +++ b/SRC/element/shell/Makefile @@ -8,6 +8,7 @@ OBJS = ShellMITC4.o \ ShellNLDKGT.o \ ShellMITC4Thermal.o \ ShellNLDKGQThermal.o \ + ASDShellQ4.o \ R3vectors.o \ ShellANDeS.o diff --git a/SRC/element/shell/ShellDKGQ.h b/SRC/element/shell/ShellDKGQ.h index af1486d33e..3341864558 100755 --- a/SRC/element/shell/ShellDKGQ.h +++ b/SRC/element/shell/ShellDKGQ.h @@ -38,7 +38,6 @@ #include #include #include -#include class ShellDKGQ : public Element { diff --git a/SRC/element/shell/ShellDKGT.h b/SRC/element/shell/ShellDKGT.h index 389030dae5..ef7dae7d3b 100644 --- a/SRC/element/shell/ShellDKGT.h +++ b/SRC/element/shell/ShellDKGT.h @@ -38,7 +38,6 @@ #include #include #include -#include class ShellDKGT : public Element { diff --git a/SRC/element/shell/ShellMITC4.h b/SRC/element/shell/ShellMITC4.h index e8b307c15c..4e40973711 100644 --- a/SRC/element/shell/ShellMITC4.h +++ b/SRC/element/shell/ShellMITC4.h @@ -43,7 +43,6 @@ #include #include #include -#include class ShellMITC4 : public Element { diff --git a/SRC/element/shell/ShellMITC9.h b/SRC/element/shell/ShellMITC9.h index 651b98fda1..ee138e8a86 100644 --- a/SRC/element/shell/ShellMITC9.h +++ b/SRC/element/shell/ShellMITC9.h @@ -32,7 +32,6 @@ #include #include #include -#include class ShellMITC9 : public Element { diff --git a/SRC/element/shell/ShellNLDKGQ.h b/SRC/element/shell/ShellNLDKGQ.h index 9afc4e0f10..fee866da02 100755 --- a/SRC/element/shell/ShellNLDKGQ.h +++ b/SRC/element/shell/ShellNLDKGQ.h @@ -41,7 +41,6 @@ #include #include #include -#include class ShellNLDKGQ : public Element { diff --git a/SRC/element/surfaceLoad/SurfaceLoad.cpp b/SRC/element/surfaceLoad/SurfaceLoad.cpp index 060dc5451f..ee792d4059 100644 --- a/SRC/element/surfaceLoad/SurfaceLoad.cpp +++ b/SRC/element/surfaceLoad/SurfaceLoad.cpp @@ -245,7 +245,7 @@ SurfaceLoad::UpdateBase(double Xi, double Eta) myNI(2) = 0.25 * onePlusXi * onePlusEta; myNI(3) = 0.25 * oneMinusXi * onePlusEta; - // normal vector to master surface as cross product of g1 and g2 + // normal vector to primary surface as cross product of g1 and g2 myNhat(0) = g1(1)*g2(2) - g1(2)*g2(1); myNhat(1) = g1(2)*g2(0) - g1(0)*g2(2); myNhat(2) = g1(0)*g2(1) - g1(1)*g2(0); diff --git a/SRC/element/surfaceLoad/TriSurfaceLoad.cpp b/SRC/element/surfaceLoad/TriSurfaceLoad.cpp index 241a4de847..59e4cb7f2a 100644 --- a/SRC/element/surfaceLoad/TriSurfaceLoad.cpp +++ b/SRC/element/surfaceLoad/TriSurfaceLoad.cpp @@ -240,7 +240,7 @@ TriSurfaceLoad::UpdateBase(double Xi, double Eta) myNI(1) = 0.5; myNI(2) = 0.5; - // normal vector to master surface as cross product of g1 and g2 + // normal vector to primary surface as cross product of g1 and g2 myNhat(0) = g1(1)*g2(2) - g1(2)*g2(1); myNhat(1) = g1(2)*g2(0) - g1(0)*g2(2); myNhat(2) = g1(0)*g2(1) - g1(1)*g2(0); diff --git a/SRC/element/tetrahedron/FourNodeTetrahedron.cpp b/SRC/element/tetrahedron/FourNodeTetrahedron.cpp index 7b5b56c5f6..0e6768de91 100644 --- a/SRC/element/tetrahedron/FourNodeTetrahedron.cpp +++ b/SRC/element/tetrahedron/FourNodeTetrahedron.cpp @@ -1726,7 +1726,7 @@ FourNodeTetrahedron::setResponse(const char **argv, int argc, OPS_Stream &output int FourNodeTetrahedron::getResponse(int responseID, Information &eleInfo) { - static Vector stresses(48); + static Vector stresses(6); if (responseID == 1) return eleInfo.setVector(this->getResistingForce()); @@ -2012,3 +2012,19 @@ FourNodeTetrahedron::shp3d( const double ss[4], double &xsj, double shp[4][4], c // Return[{Nfx,Nfy,Nfz,Jdet}]]; return ; } + + +void +FourNodeTetrahedron::onActivate() +{ + + Domain* theDomain = this->getDomain(); + this->setDomain(theDomain); + this->update(); +} + +void +FourNodeTetrahedron::onDeactivate() +{ + +} diff --git a/SRC/element/tetrahedron/FourNodeTetrahedron.h b/SRC/element/tetrahedron/FourNodeTetrahedron.h index 004b3f3524..7c2007409f 100644 --- a/SRC/element/tetrahedron/FourNodeTetrahedron.h +++ b/SRC/element/tetrahedron/FourNodeTetrahedron.h @@ -128,6 +128,8 @@ class FourNodeTetrahedron : public Element { //plotting int displaySelf(Renderer &, int mode, float fact, const char **displayModes=0, int numModes=0); + void onActivate(); + void onDeactivate(); private : diff --git a/SRC/element/triangle/Tri31.cpp b/SRC/element/triangle/Tri31.cpp index 3c4cd2239e..25c3950c31 100644 --- a/SRC/element/triangle/Tri31.cpp +++ b/SRC/element/triangle/Tri31.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -376,9 +377,6 @@ Tri31::Tri31(int tag, int nd1, int nd2, int nd3, b[0] = b1; b[1] = b2; - numgp = 1; - numnodes = 3; - // Allocate arrays of pointers to NDMaterials theMaterial = new NDMaterial *[numgp]; @@ -748,6 +746,10 @@ Tri31::getMass() void Tri31::zeroLoad(void) { + applyLoad = 0; + appliedB[0] = 0.0; + appliedB[1] = 0.0; + Q.Zero(); return; } @@ -755,7 +757,20 @@ Tri31::zeroLoad(void) int Tri31::addLoad(ElementalLoad *theLoad, double loadFactor) { - opserr << "Tri31::addLoad - load type unknown for ele with tag: " << this->getTag() << endln; + // body forces can be applied in a load pattern + int type; + const Vector &data = theLoad->getData(type, loadFactor); + + if (type == LOAD_TAG_SelfWeight) { + applyLoad = 1; + appliedB[0] += loadFactor*data(0)*b[0]; + appliedB[1] += loadFactor*data(1)*b[1]; + return 0; + } else { + opserr << "Tri31::addLoad - load type unknown for ele with tag: " << this->getTag() << endln; + return -1; + } + return -1; } @@ -835,8 +850,13 @@ Tri31::getResistingForce() // Subtract equiv. body forces from the nodes //P = P - (N^ b) * intWt(i)*intWt(j) * detJ; //P.addMatrixTransposeVector(1.0, N, b, -intWt(i)*intWt(j)*detJ); - P(ia) -= dvol*(shp[2][alpha]*b[0]); - P(ia+1) -= dvol*(shp[2][alpha]*b[1]); + if (applyLoad == 0) { + P(ia) -= dvol*(shp[2][alpha]*b[0]); + P(ia+1) -= dvol*(shp[2][alpha]*b[1]); + } else { + P(ia) -= dvol*(shp[2][alpha]*appliedB[0]); + P(ia+1) -= dvol*(shp[2][alpha]*appliedB[1]); + } } } @@ -1098,7 +1118,7 @@ Tri31::Print(OPS_Stream &s, int flag) for (i = 0; i < numNodes; i++) { const Vector &nodeCrd = theNodes[i]->getCrds(); - const Vector &nodeDisp = theNodes[i]->getDisp(); + // const Vector &nodeDisp = theNodes[i]->getDisp(); s << "#NODE " << nodeCrd(0) << " " << nodeCrd(1) << " " << endln; } @@ -1260,9 +1280,31 @@ Tri31::setResponse(const char **argv, int argc, OPS_Stream &output) output.endTag(); // GaussPoint output.endTag(); // NdMaterialOutput } - theResponse = new ElementResponse(this, 3, Vector(12)); + theResponse = new ElementResponse(this, 3, Vector(3*numgp)); } + else if ((strcmp(argv[0],"stressesAtNodes") ==0) || (strcmp(argv[0],"stressAtNodes") ==0)) { + for (int i=0; igetClassTag()); + // output.attr("tag", theMaterial[i]->getTag()); + + output.tag("ResponseType","sigma11"); + output.tag("ResponseType","sigma22"); + output.tag("ResponseType","sigma12"); + + output.endTag(); // GaussPoint + // output.endTag(); // NdMaterialOutput + } + theResponse = new ElementResponse(this, 11, Vector(3*numnodes)); + } + + output.endTag(); // ElementOutput return theResponse; @@ -1287,6 +1329,42 @@ Tri31::getResponse(int responseID, Information &eleInfo) cnt += 3; } return eleInfo.setVector(stresses); + + } else if (responseID == 11) { + + // extrapolate stress from Gauss points to element nodes + static Vector stressGP(3*numgp); + static Vector stressAtNodes(3*numnodes); // 3*nnodes + stressAtNodes.Zero(); + int cnt = 0; + // first get stress components (xx, yy, xy) at Gauss points + for (int i = 0; i < numgp; i++) { + // Get material stress response + const Vector &sigma = theMaterial[i]->getStress(); + stressGP(cnt) = sigma(0); + stressGP(cnt+1) = sigma(1); + stressGP(cnt+2) = sigma(2); + cnt += 3; + } + + double We[numnodes][numgp] = {{1.0}, + {1.0}, + {1.0}}; + + int p, l; + for (int i = 0; i < numnodes; i++) { + for (int k = 0; k < 3; k++) { // number of stress components + p = 3*i + k; + for (int j = 0; j < numgp; j++) { + l = 3*j + k; + stressAtNodes(p) += We[i][j] * stressGP(l); + // opserr << "stressAtNodes(" << p << ") = We[" << i << "][" << j << "] * stressGP(" << l << ") = " << We[i][j] << " * " << stressGP(l) << " = " << stressAtNodes(p) << "\n"; + } + } + } + + return eleInfo.setVector(stressAtNodes); + } else return -1; diff --git a/SRC/element/triangle/Tri31.h b/SRC/element/triangle/Tri31.h index f2cafc6035..3c1e3d1753 100644 --- a/SRC/element/triangle/Tri31.h +++ b/SRC/element/triangle/Tri31.h @@ -115,6 +115,10 @@ class Tri31 : public Element static Vector P; // Element resisting force vector Vector Q; // Applied nodal loads double b[2]; // Body forces + + double appliedB[2]; // Body forces applied with load pattern + int applyLoad; // flag for body force in load + Vector pressureLoad; // Pressure load at nodes double thickness; // Element thickness @@ -131,8 +135,8 @@ class Tri31 : public Element Matrix *Ki; - int numgp; // number of guess points - int numnodes; // number of nodes + static constexpr int numgp = 1; // number of gauss points + static constexpr int numnodes = 3; // number of nodes }; #endif diff --git a/SRC/element/truss/CorotTruss.cpp b/SRC/element/truss/CorotTruss.cpp index ef5507e63e..ee64433e91 100644 --- a/SRC/element/truss/CorotTruss.cpp +++ b/SRC/element/truss/CorotTruss.cpp @@ -1107,10 +1107,41 @@ CorotTruss::setResponse(const char **argv, int argc, OPS_Stream &output) output.tag("ResponseType", "U"); theResponse = new ElementResponse(this, 3, 0.0); - // a material quantity - } else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"-material") == 0) { - - theResponse = theMaterial->setResponse(&argv[1], argc-1, output); + // a material quantity + } + else if (strcmp(argv[0], "material") == 0 || strcmp(argv[0], "-material") == 0) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + + if (argc > 1) { + // we need at least one more argument otherwise + // there is no need to forward this call to the material + if (argc > 2) { + // if we have 2 or more extra arguments, the first one + // could be an integer. In this case we check to see if it is the section id + // (only 1 in this case) + int sectionNum = atoi(argv[1]); + if (sectionNum == 0) { + // if it is not a number we forward the call to the section as usual + theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + } + else { + // it is a number. Now we have to make sure it is within the allowed range + // for this element (in this case it can only be 1) + // If it is > 1, then we MUST return NULL, because the MPCO recorder iteratively + // uses this call to understand how many fibers we have in a section + if (sectionNum == 1) { + theResponse = theMaterial->setResponse(&argv[2], argc - 2, output); + } + } + } + else { + // otherwise forward it as usual + theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + } + } + output.endTag(); } output.endTag(); diff --git a/SRC/element/truss/CorotTruss2.cpp b/SRC/element/truss/CorotTruss2.cpp index 95a5e14446..9d73ad606c 100644 --- a/SRC/element/truss/CorotTruss2.cpp +++ b/SRC/element/truss/CorotTruss2.cpp @@ -942,10 +942,41 @@ CorotTruss2::setResponse(const char **argv, int argc, OPS_Stream &output) output.tag("ResponseType", "U"); theResponse = new ElementResponse(this, 3, 0.0); - // a material quantity - } else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"-material") == 0) { - - theResponse = theMaterial->setResponse(&argv[1], argc-1, output); + // a material quantity + } + else if (strcmp(argv[0], "material") == 0 || strcmp(argv[0], "-material") == 0) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + + if (argc > 1) { + // we need at least one more argument otherwise + // there is no need to forward this call to the material + if (argc > 2) { + // if we have 2 or more extra arguments, the first one + // could be an integer. In this case we check to see if it is the section id + // (only 1 in this case) + int sectionNum = atoi(argv[1]); + if (sectionNum == 0) { + // if it is not a number we forward the call to the section as usual + theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + } + else { + // it is a number. Now we have to make sure it is within the allowed range + // for this element (in this case it can only be 1) + // If it is > 1, then we MUST return NULL, because the MPCO recorder iteratively + // uses this call to understand how many fibers we have in a section + if (sectionNum == 1) { + theResponse = theMaterial->setResponse(&argv[2], argc - 2, output); + } + } + } + else { + // otherwise forward it as usual + theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + } + } + output.endTag(); } output.endTag(); diff --git a/SRC/element/truss/CorotTrussSection.cpp b/SRC/element/truss/CorotTrussSection.cpp index a4c4ec0905..0d2e76dee2 100644 --- a/SRC/element/truss/CorotTrussSection.cpp +++ b/SRC/element/truss/CorotTrussSection.cpp @@ -971,10 +971,41 @@ CorotTrussSection::setResponse(const char **argv, int argc, OPS_Stream &output) theResponse = new ElementResponse(this, 3, 0.0); // a section quantity - } else if (strcmp(argv[0],"section") ==0) { - theResponse = theSection->setResponse(&argv[1], argc-1, output); - - } + } + else if (strcmp(argv[0], "section") == 0) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + + if (argc > 1) { + // we need at least one more argument otherwise + // there is no need to forward this call to the section + if (argc > 2) { + // if we have 2 or more extra arguments, the first one + // could be an integer. In this case we check to see if it is the section id + // (only 1 in this case) + int sectionNum = atoi(argv[1]); + if (sectionNum == 0) { + // if it is not a number we forward the call to the section as usual + theResponse = theSection->setResponse(&argv[1], argc - 1, output); + } + else { + // it is a number. Now we have to make sure it is within the allowed range + // for this element (in this case it can only be 1) + // If it is > 1, then we MUST return NULL, because the MPCO recorder iteratively + // uses this call to understand how many fibers we have in a section + if (sectionNum == 1) { + theResponse = theSection->setResponse(&argv[2], argc - 2, output); + } + } + } + else { + // otherwise forward it as usual + theResponse = theSection->setResponse(&argv[1], argc - 1, output); + } + } + output.endTag(); + } output.endTag(); return theResponse; diff --git a/SRC/element/truss/N4BiaxialTruss.cpp b/SRC/element/truss/N4BiaxialTruss.cpp index 54ef73a2d7..a507b69ccf 100644 --- a/SRC/element/truss/N4BiaxialTruss.cpp +++ b/SRC/element/truss/N4BiaxialTruss.cpp @@ -1311,14 +1311,59 @@ N4BiaxialTruss::setResponse(const char **argv, int argc, OPS_Stream &output) // a material quantity } else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"-material") == 0) { - CompositeResponse *theCResponse = new CompositeResponse(); - Response *theResponse1 = theMaterial_1->setResponse(&argv[1], argc-1, output); - Response *theResponse2 = theMaterial_2->setResponse(&argv[1], argc-1, output); - - theCResponse->addResponse(theResponse1); - theCResponse->addResponse(theResponse2); - - theResponse = theCResponse; + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + + if (argc > 1) { + // we need at least one more argument otherwise + // there is no need to forward this call to the material + if (argc > 2) { + // if we have 2 or more extra arguments, the first one + // could be an integer. In this case we check to see if it is the section id + // (only 1 in this case) + int sectionNum = atoi(argv[1]); + if (sectionNum == 0) { + // if it is not a number we forward the call to the section as usual + CompositeResponse* theCResponse = new CompositeResponse(); + Response* theResponse1 = theMaterial_1->setResponse(&argv[1], argc - 1, output); + Response* theResponse2 = theMaterial_2->setResponse(&argv[1], argc - 1, output); + + theCResponse->addResponse(theResponse1); + theCResponse->addResponse(theResponse2); + + theResponse = theCResponse; + } + else { + // it is a number. Now we have to make sure it is within the allowed range + // for this element (in this case it can only be 1) + // If it is > 1, then we MUST return NULL, because the MPCO recorder iteratively + // uses this call to understand how many fibers we have in a section + if (sectionNum == 1) { + CompositeResponse* theCResponse = new CompositeResponse(); + Response* theResponse1 = theMaterial_1->setResponse(&argv[2], argc - 2, output); + Response* theResponse2 = theMaterial_2->setResponse(&argv[2], argc - 2, output); + + theCResponse->addResponse(theResponse1); + theCResponse->addResponse(theResponse2); + + theResponse = theCResponse; + } + } + } + else { + // otherwise forward it as usual + CompositeResponse* theCResponse = new CompositeResponse(); + Response* theResponse1 = theMaterial_1->setResponse(&argv[1], argc - 1, output); + Response* theResponse2 = theMaterial_2->setResponse(&argv[1], argc - 1, output); + + theCResponse->addResponse(theResponse1); + theCResponse->addResponse(theResponse2); + + theResponse = theCResponse; + } + } + output.endTag(); } output.endTag(); diff --git a/SRC/element/truss/Truss.cpp b/SRC/element/truss/Truss.cpp index ae9ceaa818..fff236b018 100644 --- a/SRC/element/truss/Truss.cpp +++ b/SRC/element/truss/Truss.cpp @@ -1176,9 +1176,11 @@ Truss::setResponse(const char **argv, int argc, OPS_Stream &output) } theResponse = new ElementResponse(this, 1, Vector(numDOF)); + } else if ((strcmp(argv[0],"localForce") == 0) || (strcmp(argv[0],"localForces") == 0) ) { + theResponse = new ElementResponse(this, 11, Vector(numDOF)); + } else if ((strcmp(argv[0],"axialForce") == 0) || (strcmp(argv[0],"basicForce") == 0) || - (strcmp(argv[0],"localForce") == 0) || (strcmp(argv[0],"basicForces") == 0)) { output.tag("ResponseType", "N"); theResponse = new ElementResponse(this, 2, Vector(1)); @@ -1197,8 +1199,38 @@ Truss::setResponse(const char **argv, int argc, OPS_Stream &output) // a material quantity } else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"-material") == 0) { - - theResponse = theMaterial->setResponse(&argv[1], argc-1, output); + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + + if (argc > 1) { + // we need at least one more argument otherwise + // there is no need to forward this call to the material + if (argc > 2) { + // if we have 2 or more extra arguments, the first one + // could be an integer. In this case we check to see if it is the section id + // (only 1 in this case) + int sectionNum = atoi(argv[1]); + if (sectionNum == 0) { + // if it is not a number we forward the call to the section as usual + theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + } + else { + // it is a number. Now we have to make sure it is within the allowed range + // for this element (in this case it can only be 1) + // If it is > 1, then we MUST return NULL, because the MPCO recorder iteratively + // uses this call to understand how many fibers we have in a section + if (sectionNum == 1) { + theResponse = theMaterial->setResponse(&argv[2], argc - 2, output); + } + } + } + else { + // otherwise forward it as usual + theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + } + } + output.endTag(); } output.endTag(); @@ -1216,6 +1248,13 @@ Truss::getResponse(int responseID, Information &eleInfo) case 1: return eleInfo.setVector(this->getResistingForce()); + case 11: { + Vector P(numDOF); + P(numDOF/2) = A*theMaterial->getStress(); + P(0) = -P(numDOF/2); + return eleInfo.setVector(P); + } + case 2: fVec(0) = A*theMaterial->getStress(); return eleInfo.setVector(fVec); diff --git a/SRC/element/truss/Truss2.cpp b/SRC/element/truss/Truss2.cpp index 4d6bb0cf60..b06a6264c9 100644 --- a/SRC/element/truss/Truss2.cpp +++ b/SRC/element/truss/Truss2.cpp @@ -1216,11 +1216,41 @@ Response* output.tag("ResponseType", "U"); theResponse = new ElementResponse(this, 3, 0.0); - // a material quantity - } else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"-material") == 0) { - - theResponse = theMaterial->setResponse(&argv[1], argc-1, output); + } + else if (strcmp(argv[0], "material") == 0 || strcmp(argv[0], "-material") == 0) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + + if (argc > 1) { + // we need at least one more argument otherwise + // there is no need to forward this call to the material + if (argc > 2) { + // if we have 2 or more extra arguments, the first one + // could be an integer. In this case we check to see if it is the section id + // (only 1 in this case) + int sectionNum = atoi(argv[1]); + if (sectionNum == 0) { + // if it is not a number we forward the call to the section as usual + theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + } + else { + // it is a number. Now we have to make sure it is within the allowed range + // for this element (in this case it can only be 1) + // If it is > 1, then we MUST return NULL, because the MPCO recorder iteratively + // uses this call to understand how many fibers we have in a section + if (sectionNum == 1) { + theResponse = theMaterial->setResponse(&argv[2], argc - 2, output); + } + } + } + else { + // otherwise forward it as usual + theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + } + } + output.endTag(); } output.endTag(); diff --git a/SRC/element/truss/TrussSection.cpp b/SRC/element/truss/TrussSection.cpp index 65ae904295..4dff6f5933 100644 --- a/SRC/element/truss/TrussSection.cpp +++ b/SRC/element/truss/TrussSection.cpp @@ -1120,9 +1120,11 @@ TrussSection::setResponse(const char **argv, int argc, OPS_Stream &output) } theResponse = new ElementResponse(this, 1, Vector(numDOF)); + } else if ((strcmp(argv[0],"localForce") == 0) || (strcmp(argv[0],"localForces") == 0) ) { + theResponse = new ElementResponse(this, 11, Vector(numDOF)); + } else if ((strcmp(argv[0],"axialForce") == 0) || (strcmp(argv[0],"basicForce") == 0) || - (strcmp(argv[0],"localForce") == 0) || (strcmp(argv[0],"basicForces") == 0)) { output.tag("ResponseType", "N"); theResponse = new ElementResponse(this, 2, Vector(1)); @@ -1140,12 +1142,39 @@ TrussSection::setResponse(const char **argv, int argc, OPS_Stream &output) theResponse = new ElementResponse(this, 4, Matrix(1,1)); // a section quantity - } else if (strcmp(argv[0],"section") ==0) { - int secNum = atoi(argv[1]); - if (secNum == 0) - theResponse = theSection->setResponse(&argv[1], argc-1, output); - else - theResponse = theSection->setResponse(&argv[2], argc-2, output); + } else if (strcmp(argv[0], "section") == 0) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + + if (argc > 1) { + // we need at least one more argument otherwise + // there is no need to forward this call to the section + if (argc > 2) { + // if we have 2 or more extra arguments, the first one + // could be an integer. In this case we check to see if it is the section id + // (only 1 in this case) + int sectionNum = atoi(argv[1]); + if (sectionNum == 0) { + // if it is not a number we forward the call to the section as usual + theResponse = theSection->setResponse(&argv[1], argc - 1, output); + } + else { + // it is a number. Now we have to make sure it is within the allowed range + // for this element (in this case it can only be 1) + // If it is > 1, then we MUST return NULL, because the MPCO recorder iteratively + // uses this call to understand how many fibers we have in a section + if (sectionNum == 1) { + theResponse = theSection->setResponse(&argv[2], argc - 2, output); + } + } + } + else { + // otherwise forward it as usual + theResponse = theSection->setResponse(&argv[1], argc - 1, output); + } + } + output.endTag(); } output.endTag(); @@ -1165,6 +1194,23 @@ TrussSection::getResponse(int responseID, Information &eleInfo) case 1: return eleInfo.setVector(this->getResistingForce()); + case 11: { + Vector P(numDOF); + int order = theSection->getOrder(); + const ID &code = theSection->getType(); + + const Vector &s = theSection->getStressResultant(); + force = 0.0; + int i; + for (i = 0; i < order; i++) { + if (code(i) == SECTION_RESPONSE_P) + force += s(i); + } + + P(numDOF/2) = force; + P(0) = -P(numDOF/2); + return eleInfo.setVector(P); + } case 2: if (L == 0.0) { strain = 0.0; diff --git a/SRC/element/zeroLength/TclZeroLength.cpp b/SRC/element/zeroLength/TclZeroLength.cpp index 22587c0d70..6e044cd663 100644 --- a/SRC/element/zeroLength/TclZeroLength.cpp +++ b/SRC/element/zeroLength/TclZeroLength.cpp @@ -496,7 +496,7 @@ TclModelBuilder_addZeroLengthSection(ClientData clientData, Tcl_Interp *interp, // Command: // -// element zeroLengthContact2D $tag $slaveNd $masterNd $Kn $Kt $fs $ContactDirction +// element zeroLengthContact2D $tag $secondaryNd $primaryNd $Kn $Kt $fs $ContactDirction // // @@ -512,7 +512,7 @@ TclModelBuilder_addZeroLengthContact2D(ClientData clientData, Tcl_Interp *interp int ndm = theBuilder->getNDM(); // the spatial dimension of the problem // - // first scan the command line to obtain eleID, SlaveNode, MasterNode, + // first scan the command line to obtain eleID, SecondaryNode, PrimaryNode, int eleTag, iNode, jNode; @@ -618,7 +618,7 @@ TclModelBuilder_addZeroLengthContact2D(ClientData clientData, Tcl_Interp *interp // Command: // -// element zeroLengthContact3D $tag $slaveNd $masterNd $Kn $Kt $fs $c $ContactDir +// element zeroLengthContact3D $tag $secondaryNd $primaryNd $Kn $Kt $fs $c $ContactDir // // @@ -632,7 +632,7 @@ TclModelBuilder_addZeroLengthContact3D(ClientData clientData, Tcl_Interp *interp int ndm = theBuilder->getNDM(); // the spatial dimension of the problem // - // first scan the command line to obtain eleID, SlaveNode, MasterNode, + // first scan the command line to obtain eleID, SecondaryNode, PrimaryNode, int eleTag, iNode, jNode; diff --git a/SRC/element/zeroLength/ZeroLength.cpp b/SRC/element/zeroLength/ZeroLength.cpp index 4957a2b767..e576863735 100644 --- a/SRC/element/zeroLength/ZeroLength.cpp +++ b/SRC/element/zeroLength/ZeroLength.cpp @@ -1682,3 +1682,20 @@ ZeroLength::updateDir(const Vector& x, const Vector& y) this->setUp(connectedExternalNodes(0), connectedExternalNodes(1), x, y); this->setTran1d(elemType, numMaterials1d); } + + +void +ZeroLength::onActivate() +{ + + Domain* theDomain = this->getDomain(); + this->setDomain(theDomain); + this->update(); +} + + +void +ZeroLength::onDeactivate() +{ + +} diff --git a/SRC/element/zeroLength/ZeroLength.h b/SRC/element/zeroLength/ZeroLength.h index 4d50f6e132..43931911df 100644 --- a/SRC/element/zeroLength/ZeroLength.h +++ b/SRC/element/zeroLength/ZeroLength.h @@ -153,6 +153,10 @@ class ZeroLength : public Element void updateDir (const Vector& x, const Vector& y); + void onActivate(); + void onDeactivate(); + + protected: private: diff --git a/SRC/element/zeroLength/ZeroLengthContact2D.cpp b/SRC/element/zeroLength/ZeroLengthContact2D.cpp index 1809f2aeda..38c9dc70ca 100644 --- a/SRC/element/zeroLength/ZeroLengthContact2D.cpp +++ b/SRC/element/zeroLength/ZeroLengthContact2D.cpp @@ -122,7 +122,7 @@ ZeroLengthContact2D::ZeroLengthContact2D(int tag, Kt = Ktangent; fs = frictionRatio; - // assign outward contact normal of master block + // assign outward contact normal of primary block ContactNormal(0) = normal(0)/normal.Norm(); ContactNormal(1) = normal(1)/normal.Norm(); @@ -668,7 +668,7 @@ ZeroLengthContact2D::getResponse(int responseID, Information &eleInfo) // Private methods -// determine the slave/master pair in contact, and setup Vectors (N,T1,T2) +// determine the secondary/primary pair in contact, and setup Vectors (N,T1,T2) int ZeroLengthContact2D::contactDetect(void) { //opserr<< this->getTag()<< " ZeroLengthContact2D::contactDetect" <getCrds() + nodePointers[0]->getTrialDisp(); + &U_secondary = nodePointers[0]->getCrds() + nodePointers[0]->getTrialDisp(); const Vector - &U_master= nodePointers[1]->getCrds() + nodePointers[1]->getTrialDisp(); + &U_primary= nodePointers[1]->getCrds() + nodePointers[1]->getTrialDisp(); gap=0; int i; for (i=0; i<2; i++){ - gap += (U_master(i)-U_slave(i))* ContactNormal(i); + gap += (U_primary(i)-U_secondary(i))* ContactNormal(i); } //*////////////////////////////// for transient gap /////////////////////////////// // we have another way to define the gap, can replace previous code block if want /*/////////////// for dynamic gap ////////////////////// const Vector // get current trial incremental position - &U_slave = nodePointers[0]->getCrds() + nodePointers[0]->getIncrDisp(); + &U_secondary = nodePointers[0]->getCrds() + nodePointers[0]->getIncrDisp(); const Vector - &U_master= nodePointers[1]->getCrds() + nodePointers[1]->getIncrDisp(); + &U_primary= nodePointers[1]->getCrds() + nodePointers[1]->getIncrDisp(); gap=0; int i; for (i=0; i<2; i++){ - gap += (U_master(i)-U_slave(i))* ContactNormal(i); + gap += (U_primary(i)-U_secondary(i))* ContactNormal(i); } gap+=gap_n; @@ -745,8 +745,8 @@ void ZeroLengthContact2D::formResidAndTangent( int tang_flag ) // trial displacement vectors - Vector DispTrialS(2); // trial disp for slave node - Vector DispTrialM(2); // trial disp for master node + Vector DispTrialS(2); // trial disp for secondary node + Vector DispTrialP(2); // trial disp for primary node // trial frictional force vectors (in local coordinate) double t_trial; double TtrNorm; @@ -778,18 +778,18 @@ void ZeroLengthContact2D::formResidAndTangent( int tang_flag ) // pressure = Kn*gap + lambda; // changed for augmented lagrange DispTrialS=nodePointers[0]->getTrialDisp(); - DispTrialM=nodePointers[1]->getTrialDisp(); + DispTrialP=nodePointers[1]->getTrialDisp(); //opserr<<"DispTrialS " << DispTrialS; - //opserr<<"DispTrialM " << DispTrialM; + //opserr<<"DispTrialP " << DispTrialP; //nodal displacements double ul[4]; ul[0]=DispTrialS(0); ul[1]=DispTrialS(1); - ul[2]=DispTrialM(0); - ul[3]=DispTrialM(1); + ul[2]=DispTrialP(0); + ul[3]=DispTrialP(1); t_trial = 0; xi=0; @@ -899,12 +899,12 @@ void ZeroLengthContact2D::formResidAndTangent( int tang_flag ) ___\/____ / \ /\ Rx(1) ---\ / (1) \ /||\n Note: (t,n) follows RightHand rule - =shear*t ---/ \ slave / || + =shear*t ---/ \ secondary / || \_________/ ||_____\t -----------------------*------/ | | | | - | (2) Master |/---- Rx(2) = shear*(-t) + | (2) Primary |/---- Rx(2) = shear*(-t) | |\---- ------------------------ /\ diff --git a/SRC/element/zeroLength/ZeroLengthContact2D.h b/SRC/element/zeroLength/ZeroLengthContact2D.h index 7763d3f94c..cbc5cbd5cd 100644 --- a/SRC/element/zeroLength/ZeroLengthContact2D.h +++ b/SRC/element/zeroLength/ZeroLengthContact2D.h @@ -179,7 +179,7 @@ class ZeroLengthContact2D: public Element // Normal and Tangental Vectors for Elemental Nodes, (4*1) Vector N; Vector T; - Vector ContactNormal; // out normal of master element + Vector ContactNormal; // out normal of primary element int ContactFlag; // 0: not contact; 1: stick; 2: slide int numDOF; // number of dof for ZeroLength diff --git a/SRC/element/zeroLength/ZeroLengthContact3D.cpp b/SRC/element/zeroLength/ZeroLengthContact3D.cpp index fc4dea4ff7..b544fff889 100644 --- a/SRC/element/zeroLength/ZeroLengthContact3D.cpp +++ b/SRC/element/zeroLength/ZeroLengthContact3D.cpp @@ -549,7 +549,7 @@ ZeroLengthContact3D::getResponse(int responseID, Information &eleInfo) // Private methods -// determine the slave/master pair in contact, and setup Vectors (N,T1,T2) +// determine the secondary/primary pair in contact, and setup Vectors (N,T1,T2) int ZeroLengthContact3D::contactDetect(void) { @@ -558,8 +558,8 @@ ZeroLengthContact3D::getResponse(int responseID, Information &eleInfo) int transientgap; transientgap = 1; // 1: transient gap; 0: dynamic gap - Vector slaveNd; - Vector masterNd; + Vector secondaryNd; + Vector primaryNd; //+--------------+-----------------+----------------+----------------+---------------+ // NOTES: some methods to get displacements from nodes @@ -573,22 +573,22 @@ ZeroLengthContact3D::getResponse(int responseID, Information &eleInfo) if (transientgap) { ///////////// for transient gap ////////////////////////// - slaveNd = nodePointers[0]->getCrds() + nodePointers[0]->getTrialDisp(); - masterNd= nodePointers[1]->getCrds() + nodePointers[1]->getTrialDisp(); + secondaryNd = nodePointers[0]->getCrds() + nodePointers[0]->getTrialDisp(); + primaryNd= nodePointers[1]->getCrds() + nodePointers[1]->getTrialDisp(); } else { ///////////// for dynamic gap //////////////////////////// - slaveNd = nodePointers[0]->getCrds() + nodePointers[0]->getIncrDisp(); - masterNd= nodePointers[1]->getCrds() + nodePointers[1]->getIncrDisp(); + secondaryNd = nodePointers[0]->getCrds() + nodePointers[0]->getIncrDisp(); + primaryNd= nodePointers[1]->getCrds() + nodePointers[1]->getIncrDisp(); } - double Xs=slaveNd(0) - origin(0); - double Ys=slaveNd(1) - origin(1); - double Zs=slaveNd(2); + double Xs=secondaryNd(0) - origin(0); + double Ys=secondaryNd(1) - origin(1); + double Zs=secondaryNd(2); double Rs=sqrt(Xs*Xs +Ys*Ys); - double Xm=masterNd(0) - origin(0); - double Ym=masterNd(1) - origin(1); - double Zm=masterNd(2); + double Xm=primaryNd(0) - origin(0); + double Ym=primaryNd(1) - origin(1); + double Zm=primaryNd(2); double Rm=sqrt(Xm*Xm +Ym*Ym); @@ -674,7 +674,7 @@ ZeroLengthContact3D::getResponse(int responseID, Information &eleInfo) - case 1: // normal of master plane pointing to +X direction + case 1: // normal of primary plane pointing to +X direction if (transientgap) { @@ -750,7 +750,7 @@ ZeroLengthContact3D::getResponse(int responseID, Information &eleInfo) - case 2: // normal of master plane pointing to +Y direction + case 2: // normal of primary plane pointing to +Y direction if (transientgap) { @@ -820,19 +820,19 @@ ZeroLengthContact3D::getResponse(int responseID, Information &eleInfo) - case 3: // normal of master plane pointing to +Z direction + case 3: // normal of primary plane pointing to +Z direction // ___________ // | | - // | slave | + // | secondary | // |___________| // | | - // | Master | + // | primary | // | | @@ -930,9 +930,9 @@ void ZeroLengthContact3D::formResidAndTangent( int tang_flag ) // trial displacement vectors - Vector DispTrialS(3); // trial disp for slave node + Vector DispTrialS(3); // trial disp for secondary node - Vector DispTrialM(3); // trial disp for master node + Vector DispTrialP(3); // trial disp for primary node // trial frictional force vectors (in local coordinate) @@ -984,7 +984,7 @@ void ZeroLengthContact3D::formResidAndTangent( int tang_flag ) DispTrialS=nodePointers[0]->getTrialDisp(); - DispTrialM=nodePointers[1]->getTrialDisp(); + DispTrialP=nodePointers[1]->getTrialDisp(); @@ -1000,11 +1000,11 @@ void ZeroLengthContact3D::formResidAndTangent( int tang_flag ) ul[2]=DispTrialS(2); - ul[3]=DispTrialM(0); + ul[3]=DispTrialP(0); - ul[4]=DispTrialM(1); + ul[4]=DispTrialP(1); - ul[5]=DispTrialM(2); + ul[5]=DispTrialP(2); diff --git a/SRC/element/zeroLength/ZeroLengthContact3D.h b/SRC/element/zeroLength/ZeroLengthContact3D.h index fd238ffc86..4e4783dd0f 100644 --- a/SRC/element/zeroLength/ZeroLengthContact3D.h +++ b/SRC/element/zeroLength/ZeroLengthContact3D.h @@ -64,16 +64,16 @@ where: $eleID: element ID of this contact element - $sNdID: slave node ID - $mNdID: master node ID + $sNdID: secondary node ID + $pNdID: primary node ID $Kn : penalty in normal directions $Kt: : penalty in tangential directions $c : cohesion $dir : direction of the contact (0,1,2,3) - 0: circular contact (slave node is inside) - 1: out normal of master plane pointing to +X direction - 2: out normal of master plane pointing to +Y direction - 3: out normal of master plane pointing to +Z direction + 0: circular contact (secondary node is inside) + 1: out normal of primary plane pointing to +X direction + 2: out normal of primary plane pointing to +Y direction + 3: out normal of primary plane pointing to +Z direction Description: This file contains the class definition for ZeroLengthContact3D. (1) A ZeroLengthContact3D element is defined by two nodes with the same coordinate diff --git a/SRC/element/zeroLength/ZeroLengthContactNTS2D.cpp b/SRC/element/zeroLength/ZeroLengthContactNTS2D.cpp index 4fddd89d37..f97d478b56 100644 --- a/SRC/element/zeroLength/ZeroLengthContactNTS2D.cpp +++ b/SRC/element/zeroLength/ZeroLengthContactNTS2D.cpp @@ -27,7 +27,7 @@ // Created: 12/28/2009 /* - element ZeroLengthContactNTS2D eleTag? -sNdNum sNode? -mNdNum mNode? -Nodes Nodes? Kn? Kt? phi? + element ZeroLengthContactNTS2D eleTag? -sNdNum sNode? -pNdNum pNode? -Nodes Nodes? Kn? Kt? phi? Description: This file contains the implementation for the ZeroLengthContactNTS2D class. */ @@ -62,7 +62,7 @@ OPS_ZeroLengthContactNTS2D(void) { int numData = 0; // get the ele tag - int eleTag, sNdNum, mNdNum; + int eleTag, sNdNum, pNdNum; numData = 1; if (OPS_GetInt(&numData, &eleTag) != 0) { @@ -73,11 +73,11 @@ OPS_ZeroLengthContactNTS2D(void) { const char *nextString = OPS_GetString(); if (strcmp(nextString,"-sNdNum") != 0) { opserr << "ZeroLengthContactNTS2D:: expecting "<< - "- element ZeroLengthContactNTS2D eleTag? -sNdNum sNode? -mNdNum mNode? -Nodes Nodes? Kn? Kt? phi? \n" ; + "- element ZeroLengthContactNTS2D eleTag? -sNdNum sNode? -pNdNum pNode? -Nodes Nodes? Kn? Kt? phi? \n" ; return 0; } - // get the number of slave nodes + // get the number of secondary nodes numData = 1; if (OPS_GetInt(&numData, &sNdNum) != 0) { opserr << "ZeroLengthContactNTS2D::WARNING invalied sNdNum \n"; @@ -87,23 +87,23 @@ OPS_ZeroLengthContactNTS2D(void) { numData = 10; nextString = OPS_GetString(); - if (strcmp(nextString,"-mNdNum") != 0) { + if (strcmp(nextString,"-mNdNum") != 0 && strcmp(nextString,"-pNdNum") != 0) { opserr << "ZeroLengthContactNTS2D:: expecting "<< - "- element ZeroLengthContactNTS2D eleTag? -sNdNum sNode? -mNdNum mNode? -Nodes Nodes? Kn? Kt? phi? \n" ; + "- element ZeroLengthContactNTS2D eleTag? -sNdNum sNode? -pNdNum pNode? -Nodes Nodes? Kn? Kt? phi? \n" ; return 0; } numData = 1; - if (OPS_GetInt(&numData, &mNdNum) != 0) { + if (OPS_GetInt(&numData, &pNdNum) != 0) { opserr << "ZeroLengthContactNTS2D::WARNING invalied sNdNum \n"; return 0; } // a quick check on number of args int argc = OPS_GetNumRemainingInputArgs(); - if (argc < 3 + sNdNum + mNdNum) { + if (argc < 3 + sNdNum + pNdNum) { opserr << "ZeroLengthContactNTS2D::WARNING too few arguments " << - "want - element zeroLengthContactNTS2D $tag -sNdNum $sNdNum -mNdNum $mNdNum -Nodes $Nodes $Kn $Kt $phi" ; + "want - element zeroLengthContactNTS2D $tag -sNdNum $sNdNum -pNdNum $pNdNum -Nodes $Nodes $Kn $Kt $phi" ; return 0; } @@ -112,19 +112,19 @@ OPS_ZeroLengthContactNTS2D(void) { if (strcmp(nextString,"-Nodes") != 0) { opserr << "ZeroLengthContactNTS2D:: expecting "<< - "- element ZeroLengthContactNTS2D eleTag? -sNdNum sNode? -mNdNum mNode? -Nodes Nodes? Kn? Kt? phi? \n" ; + "- element ZeroLengthContactNTS2D eleTag? -sNdNum sNode? -pNdNum pNode? -Nodes Nodes? Kn? Kt? phi? \n" ; return 0; } // read the Nodes values - numData = sNdNum+mNdNum; + numData = sNdNum+pNdNum; int *theNodeData = new int[numData]; ID Nodes(theNodeData, numData); if (OPS_GetInt(&numData, theNodeData) != 0) { opserr << "ZeroLengthContactNTS2D:: invalid Nodes number value for -Nodes "; - opserr << eleTag << "- element ZeroLengthContactNTS2D eleTag? -sNdNum sNode? -mNdNum mNode? -Nodes Nodes? Kn? Kt? phi? \n" ; + opserr << eleTag << "- element ZeroLengthContactNTS2D eleTag? -sNdNum sNode? -pNdNum pNode? -Nodes Nodes? Kn? Kt? phi? \n" ; return 0; } @@ -140,7 +140,7 @@ OPS_ZeroLengthContactNTS2D(void) { // now we create the element and add it to the domain // - theEle = new ZeroLengthContactNTS2D(eleTag, sNdNum, mNdNum, Nodes, dData[0], dData[1], dData[2]); + theEle = new ZeroLengthContactNTS2D(eleTag, sNdNum, pNdNum, Nodes, dData[0], dData[1], dData[2]); return theEle; } @@ -156,16 +156,16 @@ OPS_ZeroLengthContactNTS2D(void) { -ZeroLengthContactNTS2D::ZeroLengthContactNTS2D(int tag, int sNdNum, int mNdNum, const ID& Nodes, +ZeroLengthContactNTS2D::ZeroLengthContactNTS2D(int tag, int sNdNum, int pNdNum, const ID& Nodes, double Knormal, double Ktangent, double frictionAngle) :Element(tag,ELE_TAG_ZeroLengthContactNTS2D), - connectedExternalNodes(sNdNum + mNdNum), + connectedExternalNodes(sNdNum + pNdNum), N(6), T(6), ContactNormal(2), Ki(0), load(0) { //static data - numberNodes = sNdNum + mNdNum; - SlaveNodeNum = sNdNum; - MasterNodeNum = mNdNum; + numberNodes = sNdNum + pNdNum; + SecondaryNodeNum = sNdNum; + PrimaryNodeNum = pNdNum; // static data for 2D stiff.resize(2*numberNodes,2*numberNodes); @@ -510,7 +510,7 @@ ZeroLengthContactNTS2D::getResponse(int responseID, Information &eleInfo) } // Private methods -// determine the slave/master pair in contact, and setup Vectors (N,T) +// determine the secondar/primary pair in contact, and setup Vectors (N,T) int ZeroLengthContactNTS2D::contactDetect(int s, int m1, int m2, int stage) { //+--------------+-----------------+----------------+----------------+---------------+ @@ -523,10 +523,10 @@ int ZeroLengthContactNTS2D::contactDetect(int s, int m1, int m2, int stage) //+--------------+-----------------+----------------+----------------+-------------- ////////////////////////////// for transient gap /////////////////////////////////// // DEFINE: - // gap = (U_master-U_slave) / dot(ContactNormal), + // gap = (U_primary-U_secondary) / dot(ContactNormal), // defines overlapped normal distance, always keep positive (+) when contacted ///* - // get current position and after trial displacement (slave, master1, master2) + // get current position and after trial displacement (secondary, primary1, primary2) const Vector &xs = nodePointers[s]->getCrds(); const Vector &uxs = nodePointers[s]->getTrialDisp(); @@ -534,27 +534,27 @@ int ZeroLengthContactNTS2D::contactDetect(int s, int m1, int m2, int stage) const Vector &ux1= nodePointers[m1]->getTrialDisp(); const Vector &x2 = nodePointers[m2]->getCrds(); const Vector &ux2= nodePointers[m2]->getTrialDisp(); - Vector trial_slave = xs + uxs; - Vector trial_master1 = x1 + ux1; - Vector trial_master2 = x2 + ux2; + Vector trial_secondary = xs + uxs; + Vector trial_primary1 = x1 + ux1; + Vector trial_primary2 = x2 + ux2; - Vector diff = trial_master2 - trial_master1; + Vector diff = trial_primary2 - trial_primary1; // Length of segment double L = diff.Norm(); // tangent vector Vector ContactTangent(2); - ContactTangent = (1/L) * (trial_master2 - trial_master1); + ContactTangent = (1/L) * (trial_primary2 - trial_primary1); // normal vector ContactNormal(0) = -ContactTangent(1); ContactNormal(1) = ContactTangent(0); // local coordination alpha = 0 for starting node and alpha = 1 for end node double alpha = 0; for (int i = 0; i < 2; i++) - alpha += (1/L) * (trial_slave(i) - trial_master1(i)) * ContactTangent(i); + alpha += (1/L) * (trial_secondary(i) - trial_primary1(i)) * ContactTangent(i); // normal gap normal_gap(s) = 0; for (int i = 0; i < 2; i++) - normal_gap(s) += (trial_slave(i) - trial_master1(i)) * ContactNormal(i); + normal_gap(s) += (trial_secondary(i) - trial_primary1(i)) * ContactNormal(i); // Length of segment before deformation diff = x2 - x1; double L_bar = diff.Norm(); @@ -570,19 +570,19 @@ int ZeroLengthContactNTS2D::contactDetect(int s, int m1, int m2, int stage) // we have another way to define the gap, can replace previous code block if want ////////////////////////////// for dynamic gap ////////////////////////////////// const Vector // get current trial incremental position - &U_slave = nodePointers[0]->getCrds() + nodePointers[0]->getIncrDisp(); + &U_secondary = nodePointers[0]->getCrds() + nodePointers[0]->getIncrDisp(); const Vector - &U_master= nodePointers[1]->getCrds() + nodePointers[1]->getIncrDisp(); + &U_primary= nodePointers[1]->getCrds() + nodePointers[1]->getIncrDisp(); gap=0; int i; for (i=0; i<2; i++){ - gap += (U_master(i)-U_slave(i))* ContactNormal(i); + gap += (U_primary(i)-U_secondary(i))* ContactNormal(i); } gap+=gap_n; ///////////////// for dynamic gap ////////////////////// */ - // stage = 0 means searching slave nodes against master segments - // stage = 1 means searching master nodes against slave segments + // stage = 0 means searching secondary nodes against primary segments + // stage = 1 means searching primary nodes against secondary segments if ((stage == 0 && normal_gap(s) >= 0 && alpha > 0 && alpha < 1) || (stage == 1 && normal_gap(s) >= 0 && alpha >= 0 && alpha <= 1)) { // in contact N(0) = ContactNormal(0); @@ -604,7 +604,7 @@ int ZeroLengthContactNTS2D::contactDetect(int s, int m1, int m2, int stage) } } -void ZeroLengthContactNTS2D::formLocalResidAndTangent( int tang_flag , int slave, int master1, int master2, int stage) +void ZeroLengthContactNTS2D::formLocalResidAndTangent( int tang_flag , int secondary, int primary1, int primary2, int stage) { // trial frictional force vectors (in local coordinate) double t_trial; @@ -620,26 +620,26 @@ void ZeroLengthContactNTS2D::formLocalResidAndTangent( int tang_flag , int slav //int IsContact; // detect contact and set flag - ContactFlag = contactDetect(slave,master1,master2, stage); + ContactFlag = contactDetect(secondary,primary1,primary2, stage); if (ContactFlag == 1) // contacted { // create a vector for converting local matrix to global int loctoglob[6]; - loctoglob[0] = (2 * slave); loctoglob[1] = (2 * slave) + 1; - loctoglob[2] = (2 * master1); loctoglob[3] = (2 * master1) + 1; - loctoglob[4] = (2 * master2); loctoglob[5] = (2 * master2) + 1; + loctoglob[0] = (2 * secondary); loctoglob[1] = (2 * secondary) + 1; + loctoglob[2] = (2 * primary1); loctoglob[3] = (2 * primary1) + 1; + loctoglob[4] = (2 * primary2); loctoglob[5] = (2 * primary2) + 1; // contact presure; - pressure(slave) = Kn * normal_gap(slave); // pressure is positive if in contact + pressure(secondary) = Kn * normal_gap(secondary); // pressure is positive if in contact - double ng = normal_gap(slave); + double ng = normal_gap(secondary); - t_trial = Kt * (shear_gap(slave) - stored_shear_gap(slave)); // trial shear force + t_trial = Kt * (shear_gap(secondary) - stored_shear_gap(secondary)); // trial shear force // Coulomb friction law, trial state TtrNorm = sqrt(t_trial * t_trial); - Phi = TtrNorm - fc * pressure(slave); + Phi = TtrNorm - fc * pressure(secondary); if (Phi <= 0 ) { // stick case if ( tang_flag == 1 ) { @@ -652,7 +652,7 @@ void ZeroLengthContactNTS2D::formLocalResidAndTangent( int tang_flag , int slav } //endif tang_flag // force - for (i = 0; i < 6; i++) resid(loctoglob[i]) += pressure(slave) * N(i) + t_trial * T(i); //2D + for (i = 0; i < 6; i++) resid(loctoglob[i]) += pressure(secondary) * N(i) + t_trial * T(i); //2D } // end if stick else { // slide case, non-symmetric stiff ContactFlag=2; // set the contactFlag for sliding @@ -665,8 +665,8 @@ void ZeroLengthContactNTS2D::formLocalResidAndTangent( int tang_flag , int slav } //endfor j // force } // endif tang_flag - double shear = fc * pressure(slave) * (t_trial/TtrNorm); - for (i = 0; i < 6; i++) resid(loctoglob[i]) += (pressure(slave) * N(i)) + (shear * T(i)) ; //2D + double shear = fc * pressure(secondary) * (t_trial/TtrNorm); + for (i = 0; i < 6; i++) resid(loctoglob[i]) += (pressure(secondary) * N(i)) + (shear * T(i)) ; //2D } //endif slide } // endif ContactFlag==1 } @@ -678,18 +678,18 @@ void ZeroLengthContactNTS2D::formGlobalResidAndTangent( int tang_flag ) // but on contrary in the second loop the node to node contact // will be considered and this can be controlled by "stage = 0 or 1" - // loop over slave nodes and find the nodes - // which are in contact with master's segments - for (int i = 0 ; i < SlaveNodeNum; i++) { - for (int j = SlaveNodeNum ; j < SlaveNodeNum + MasterNodeNum - 1; j++) { + // loop over sedondary nodes and find the nodes + // which are in contact with primary's segments + for (int i = 0 ; i < SecondaryNodeNum; i++) { + for (int j = SecondaryNodeNum ; j < SecondaryNodeNum + PrimaryNodeNum - 1; j++) { formLocalResidAndTangent( tang_flag, i, j, j+1 , 0); // stage = 0 // } // endfor j } // endfor i - // loop over master nodes and find the nodes - // which are in contact with slave's segments - for (int i = SlaveNodeNum ; i < SlaveNodeNum + MasterNodeNum; i++) { - for (int j = 0 ; j < SlaveNodeNum - 1; j++) { + // loop over primary nodes and find the nodes + // which are in contact with secondary's segments + for (int i = SecondaryNodeNum ; i < SecondaryNodeNum + PrimaryNodeNum; i++) { + for (int j = 0 ; j < SecondaryNodeNum - 1; j++) { formLocalResidAndTangent( tang_flag, i, j, j+1 , 1); // stage = 1 // } // endfor j } // endfor i diff --git a/SRC/element/zeroLength/ZeroLengthContactNTS2D.h b/SRC/element/zeroLength/ZeroLengthContactNTS2D.h index 8d4d88933e..8a4c0dddb7 100644 --- a/SRC/element/zeroLength/ZeroLengthContactNTS2D.h +++ b/SRC/element/zeroLength/ZeroLengthContactNTS2D.h @@ -61,8 +61,8 @@ [3] Penalty (Kn,Kt) is used to enforce the constraints, i.e. No (in fact, very small) penetration in the normal direction, and Coulomb frictional law in the tangential direction. - [4] For 2D contact, slave nodes and master nodes must be 2 DOF and notice that the slave and - master nodes must be entered in counterclockwise order. + [4] For 2D contact, secondary nodes and primary nodes must be 2 DOF and notice that the secondary and + primary nodes must be entered in counterclockwise order. [5] The resulting tangent from the contact element is non-symmetric. Switch to the non-symmetric matrix solver if convergence problem is experienced. [6] As opposed to node-to-node contact, predefined normal vector for node-to-segment (NTS) element is not required @@ -154,13 +154,13 @@ class ZeroLengthContactNTS2D: public Element // Normal and Tangental Vectors for Elemental Nodes, (4*1) Vector N; Vector T; - Vector ContactNormal; // out normal of master element + Vector ContactNormal; // out normal of primary element int ContactFlag; // 0: not contact; 1: stick; 2: slide int numDOF; // number of dof for ZeroLength // detect the contact and set flag int contactDetect(int s, int m1, int m2, int stage); //form residual and tangent - void formLocalResidAndTangent( int tang_flag , int slave, int master1, int master2, int stage); + void formLocalResidAndTangent( int tang_flag , int secondary, int primary1, int primary2, int stage); void formGlobalResidAndTangent(int tang_flag ); Matrix *Ki; // pointer to objects matrix (a class Matrix) Vector *load; // pointer to objects vector (a class Vector) @@ -168,8 +168,8 @@ class ZeroLengthContactNTS2D: public Element Matrix stiff; // for stiff matrix Vector resid; // for force residual vector Matrix zeroMatrix; - int SlaveNodeNum; - int MasterNodeNum; + int SecondaryNodeNum; + int PrimaryNodeNum; double *restore_shear_gap; }; diff --git a/SRC/element/zeroLength/ZeroLengthImpact3D.cpp b/SRC/element/zeroLength/ZeroLengthImpact3D.cpp index 327ea38cc0..c5022199ee 100755 --- a/SRC/element/zeroLength/ZeroLengthImpact3D.cpp +++ b/SRC/element/zeroLength/ZeroLengthImpact3D.cpp @@ -539,7 +539,7 @@ ZeroLengthImpact3D::getResponse(int responseID, Information &eleInfo) } // Private methods -// determine the slave/master pair in contact, and setup Vectors (N,T1,T2) +// determine the secondary/primary pair in contact, and setup Vectors (N,T1,T2) int ZeroLengthImpact3D::contactDetect(void) { @@ -549,8 +549,8 @@ ZeroLengthImpact3D::contactDetect(void) int transientgap; transientgap = 1; // 1: transient gap; 0: dynamic gap - Vector slaveNd; - Vector masterNd; + Vector secondaryNd; + Vector primaryNd; //+--------------+-----------------+----------------+----------------+---------------+ // NOTES: some methods to get displacements from nodes @@ -564,24 +564,24 @@ ZeroLengthImpact3D::contactDetect(void) if (transientgap) { ///////////// for transient gap ////////////////////////// - slaveNd = nodePointers[0]->getCrds() + nodePointers[0]->getTrialDisp(); - masterNd= nodePointers[1]->getCrds() + nodePointers[1]->getTrialDisp(); + secondaryNd = nodePointers[0]->getCrds() + nodePointers[0]->getTrialDisp(); + primaryNd= nodePointers[1]->getCrds() + nodePointers[1]->getTrialDisp(); } else { ///////////// for dynamic gap //////////////////////////// - slaveNd = nodePointers[0]->getCrds() + nodePointers[0]->getIncrDisp(); - masterNd= nodePointers[1]->getCrds() + nodePointers[1]->getIncrDisp(); + secondaryNd = nodePointers[0]->getCrds() + nodePointers[0]->getIncrDisp(); + primaryNd= nodePointers[1]->getCrds() + nodePointers[1]->getIncrDisp(); } - double Xs=slaveNd(0) - origin(0); - double Ys=slaveNd(1) - origin(1); - double Zs=slaveNd(2); + double Xs=secondaryNd(0) - origin(0); + double Ys=secondaryNd(1) - origin(1); + double Zs=secondaryNd(2); double Rs=sqrt(Xs*Xs +Ys*Ys); - double Xm=masterNd(0) - origin(0); - double Ym=masterNd(1) - origin(1); - double Zm=masterNd(2); + double Xp=primaryNd(0) - origin(0); + double Yp=primaryNd(1) - origin(1); + double Zp=primaryNd(2); - double Rm=sqrt(Xm*Xm +Ym*Ym); + double Rp=sqrt(Xp*Xp +Yp*Yp); @@ -595,11 +595,11 @@ ZeroLengthImpact3D::contactDetect(void) if (transientgap) { - gap = Rs-Rm - initGap; + gap = Rs-Rp - initGap; } else { - gap= gap_n + Rs - Rm - initGap; // dynamic gap + gap= gap_n + Rs - Rp - initGap; // dynamic gap } @@ -615,15 +615,15 @@ ZeroLengthImpact3D::contactDetect(void) - N(0) = -Xm/Rm ; + N(0) = -Xp/Rp ; - N(1) = -Ym/Rm ; + N(1) = -Yp/Rp ; N(2) = 0 ; - N(3) = Xm/Rm ; + N(3) = Xp/Rp ; - N(4) = Ym/Rm ; + N(4) = Yp/Rp ; N(5) = 0 ; @@ -643,15 +643,15 @@ ZeroLengthImpact3D::contactDetect(void) - T2(0) = -Ym/Rm ; + T2(0) = -Yp/Rp ; - T2(1) = Xm/Rm ; + T2(1) = Xp/Rp ; T2(2) = 0 ; - T2(3) = Ym/Rm ; + T2(3) = Yp/Rp ; - T2(4) = -Xm/Rm ; + T2(4) = -Xp/Rp ; T2(5) = 0 ; @@ -665,15 +665,15 @@ ZeroLengthImpact3D::contactDetect(void) - case 1: // normal of master plane pointing to +X direction + case 1: // normal of primary plane pointing to +X direction if (transientgap) { - gap= Xm -Xs - initGap; // transient gap + gap= Xp -Xs - initGap; // transient gap } else { - gap= gap_n + Xm - Xs - initGap; // dynamic gap + gap= gap_n + Xp - Xs - initGap; // dynamic gap } @@ -741,15 +741,15 @@ ZeroLengthImpact3D::contactDetect(void) - case 2: // normal of master plane pointing to +Y direction + case 2: // normal of primary plane pointing to +Y direction if (transientgap) { - gap= Ym - Ys - initGap; // transient gap + gap= Yp - Ys - initGap; // transient gap } else { - gap= gap_n + Ym - Ys - initGap; // dynamic gap + gap= gap_n + Yp - Ys - initGap; // dynamic gap } @@ -811,19 +811,19 @@ ZeroLengthImpact3D::contactDetect(void) - case 3: // normal of master plane pointing to +Z direction + case 3: // normal of primary plane pointing to +Z direction // ___________ // | | - // | slave | + // | secondary | // |___________| // | | - // | Master | + // | primary | // | | @@ -833,11 +833,11 @@ ZeroLengthImpact3D::contactDetect(void) if (transientgap) { - gap= Zm - Zs - initGap; // transient gap + gap= Zp - Zs - initGap; // transient gap } else { - gap= gap_n + Zm - Zs - initGap; // dynamic gap + gap= gap_n + Zp - Zs - initGap; // dynamic gap } @@ -917,9 +917,9 @@ ZeroLengthImpact3D::formResidAndTangent( int tang_flag ) // trial displacement vectors - Vector DispTrialS(3); // trial disp for slave node + Vector DispTrialS(3); // trial disp for secondary node - Vector DispTrialM(3); // trial disp for master node + Vector DispTrialP(3); // trial disp for primary node // trial frictional force vectors (in local coordinate) @@ -973,7 +973,7 @@ ZeroLengthImpact3D::formResidAndTangent( int tang_flag ) DispTrialS=nodePointers[0]->getTrialDisp(); - DispTrialM=nodePointers[1]->getTrialDisp(); + DispTrialP=nodePointers[1]->getTrialDisp(); @@ -989,11 +989,11 @@ ZeroLengthImpact3D::formResidAndTangent( int tang_flag ) ul[2]=DispTrialS(2); - ul[3]=DispTrialM(0); + ul[3]=DispTrialP(0); - ul[4]=DispTrialM(1); + ul[4]=DispTrialP(1); - ul[5]=DispTrialM(2); + ul[5]=DispTrialP(2); diff --git a/SRC/element/zeroLength/ZeroLengthInterface2D.cpp b/SRC/element/zeroLength/ZeroLengthInterface2D.cpp index 5dbe6dfcf2..bd40f75975 100644 --- a/SRC/element/zeroLength/ZeroLengthInterface2D.cpp +++ b/SRC/element/zeroLength/ZeroLengthInterface2D.cpp @@ -27,7 +27,7 @@ // Date: July 02 2010 /* - - element zeroLengthInterface2D eleTag? -sNdNum sNdNum? -mNdNum mNdNum? –dof sdof? mdof? -Nodes Nodes? Kn? Kt? phi? + - element zeroLengthInterface2D eleTag? -sNdNum sNdNum? -pNdNum pNdNum? –dof sdof? mdof? -Nodes Nodes? Kn? Kt? phi? Description: This file contains the implementation for the ZeroLengthInterface2D class. */ @@ -50,18 +50,18 @@ //********************************************************************* // Full Constructor: -ZeroLengthInterface2D::ZeroLengthInterface2D(int tag, int sNdNum, int mNdNum, int sDof, int mDof, const ID& Nodes, +ZeroLengthInterface2D::ZeroLengthInterface2D(int tag, int sNdNum, int pNdNum, int sDof, int pDof, const ID& Nodes, double Knormal, double Ktangent, double frictionAngle) :Element(tag,ELE_TAG_ZeroLengthInterface2D), - connectedExternalNodes(sNdNum + mNdNum), + connectedExternalNodes(sNdNum + pNdNum), N(6), T(6), ContactNormal(2), Ki(0), load(0) { //static data - SlaveNodeNum = sNdNum; - MasterNodeNum = mNdNum; - numberNodes = SlaveNodeNum + MasterNodeNum; - SlaveDof = sDof; - MasterDof = mDof; + SecondaryNodeNum = sNdNum; + PrimaryNodeNum = pNdNum; + numberNodes = SecondaryNodeNum + PrimaryNodeNum; + SecondaryDof = sDof; + PrimaryDof = pDof; // allocate contact force vector pressure.resize(numberNodes); @@ -80,7 +80,7 @@ ZeroLengthInterface2D::ZeroLengthInterface2D(int tag, int sNdNum, int mNdNum, in normal_gap(i) = 0; } - int alloc = SlaveDof * SlaveNodeNum + MasterDof * MasterNodeNum; + int alloc = SecondaryDof * SecondaryNodeNum + PrimaryDof * PrimaryNodeNum; // static data for 2D stiff.resize(alloc, alloc); @@ -408,8 +408,8 @@ ZeroLengthInterface2D::getResponse(int responseID, Information &eleInfo) } // Private methods -// determine the slave/master pair in contact, and setup Vectors (N,T1,T2) -int ZeroLengthInterface2D::contactDetect(int s, int m1, int m2, int stage) +// determine the secondary/primary pair in contact, and setup Vectors (N,T1,T2) +int ZeroLengthInterface2D::contactDetect(int s, int p1, int p2, int stage) { //+--------------+-----------------+----------------+----------------+---------------+ // NOTES: some methods to get displacements from nodes @@ -421,38 +421,38 @@ int ZeroLengthInterface2D::contactDetect(int s, int m1, int m2, int stage) //+--------------+-----------------+----------------+----------------+-------------- ////////////////////////////// for transient gap /////////////////////////////////// // DEFINE: - // gap = (U_master-U_slave) / dot(ContactNormal), + // gap = (U_primary-U_secondary) / dot(ContactNormal), // defines overlapped normal distance, always keep positive (+) when contacted ///* - // get current position and after trial displacement for (slave, master1, master2) nodes + // get current position and after trial displacement for (secondary, primary1, primary2) nodes int i; const Vector &xs = nodePointers[s]->getCrds(); const Vector &uxs = nodePointers[s]->getTrialDisp(); - const Vector &x1 = nodePointers[m1]->getCrds(); - const Vector &ux1= nodePointers[m1]->getTrialDisp(); - const Vector &x2 = nodePointers[m2]->getCrds(); - const Vector &ux2= nodePointers[m2]->getTrialDisp(); + const Vector &x1 = nodePointers[p1]->getCrds(); + const Vector &ux1= nodePointers[p1]->getTrialDisp(); + const Vector &x2 = nodePointers[p2]->getCrds(); + const Vector &ux2= nodePointers[p2]->getTrialDisp(); - Vector trial_slave(2), trial_master1(2), trial_master2(2); + Vector trial_secondary(2), trial_primary1(2), trial_primary2(2); for (i = 0; i < 2; i++) { - trial_slave(i) = xs(i) + uxs(i); - trial_master1(i) = x1(i) + ux1(i); - trial_master2(i) = x2(i) + ux2(i); - //opserr << "trial_slave: " << trial_slave(i) << "\n"; - //opserr << "trial_master1: " << trial_master1(i) << "\n"; - //opserr << "trial_master2: " << trial_master2(i) << "\n"; + trial_secondary(i) = xs(i) + uxs(i); + trial_primary1(i) = x1(i) + ux1(i); + trial_primary2(i) = x2(i) + ux2(i); + //opserr << "trial_secondary: " << trial_secondary(i) << "\n"; + //opserr << "trial_primary1: " << trial_primary1(i) << "\n"; + //opserr << "trial_primary2: " << trial_primary2(i) << "\n"; } // calculate normal gap for contact Vector diff(2); Vector ContactTangent(2); for (i = 0; i < 2; i++) { - diff(i) = trial_master2(i) - trial_master1(i); + diff(i) = trial_primary2(i) - trial_primary1(i); //opserr << "diff: " << diff(i) << "\n"; } double L = diff.Norm(); // tangent vector - for (i = 0; i < 2; i++) ContactTangent(i) = (1/L) * (trial_master2(i) - trial_master1(i)); + for (i = 0; i < 2; i++) ContactTangent(i) = (1/L) * (trial_primary2(i) - trial_primary1(i)); // normal vector ContactNormal(0) = - ContactTangent(1); ContactNormal(1) = ContactTangent(0); @@ -461,8 +461,8 @@ int ZeroLengthInterface2D::contactDetect(int s, int m1, int m2, int stage) double alpha = 0; double alpha_bar = 0; for (i = 0; i < 2; i++) { - alpha += (1/L) * (trial_slave(i) - trial_master1(i)) * ContactTangent(i); - normal_gap(s) += (trial_slave(i) - trial_master1(i)) * ContactNormal(i); + alpha += (1/L) * (trial_secondary(i) - trial_primary1(i)) * ContactTangent(i); + normal_gap(s) += (trial_secondary(i) - trial_primary1(i)) * ContactNormal(i); diff(i) = x2(i) - x1(i); } @@ -476,19 +476,19 @@ int ZeroLengthInterface2D::contactDetect(int s, int m1, int m2, int stage) // we have another way to define the gap, can replace previous code block if want ////////////////////////////// for dynamic gap ////////////////////////////////// const Vector // get current trial incremental position - &U_slave = nodePointers[0]->getCrds() + nodePointers[0]->getIncrDisp(); + &U_secondary = nodePointers[0]->getCrds() + nodePointers[0]->getIncrDisp(); const Vector - &U_master= nodePointers[1]->getCrds() + nodePointers[1]->getIncrDisp(); + &U_primary= nodePointers[1]->getCrds() + nodePointers[1]->getIncrDisp(); gap=0; int i; for (i=0; i<2; i++){ - gap += (U_master(i)-U_slave(i))* ContactNormal(i); + gap += (U_primary(i)-U_secondary(i))* ContactNormal(i); } gap+=gap_n; ///////////////// for dynamic gap ////////////////////// */ - // stage = 0 means searching slave nodes against master segments - // stage = 1 means searching master nodes against slave segments + // stage = 0 means searching secondary nodes against primary segments + // stage = 1 means searching primary nodes against secondary segments if ((stage == 0 && normal_gap(s) >= 0 && alpha > 0 && alpha < 1) || (stage == 1 && normal_gap(s) >= 0 && alpha >= 0 && alpha <= 1)) { // in contact N(0) = ContactNormal(0); @@ -512,74 +512,74 @@ int ZeroLengthInterface2D::contactDetect(int s, int m1, int m2, int stage) } /* -void ZeroLengthInterface2D::GlobalResidAndTangentOrder2(int slave, int master1, int master2) +void ZeroLengthInterface2D::GlobalResidAndTangentOrder2(int secondary, int primary1, int primary2) { // create a vector for converting local matrix to global - int sdofNd = nodePointers[slave]->getNumberDOF(); - int m1dofNd = nodePointers[master1]->getNumberDOF(); - int m2dofNd = nodePointers[master2]->getNumberDOF(); - - if (sdofNd == 2 && m1dofNd == 3 && m2dofNd == 3) { - loctoglob[0] = (2 * slave); - loctoglob[1] = (2 * slave) + 1; - loctoglob[2] = (2 * SlaveNodeNum) + (3 * (master1 - SlaveNodeNum)); - loctoglob[3] = (2 * SlaveNodeNum) + (3 * (master1 - SlaveNodeNum)) + 1; - loctoglob[4] = (2 * SlaveNodeNum) + (3 * (master2 - SlaveNodeNum)); - loctoglob[5] = (2 * SlaveNodeNum) + (3 * (master2 - SlaveNodeNum)) + 1; - } else if (sdofNd == 3 && m1dofNd == 2 && m2dofNd == 2) { - loctoglob[0] = (2 * SlaveNodeNum) + (3 * (slave - SlaveNodeNum)); - loctoglob[1] = (2 * SlaveNodeNum) + (3 * (slave - SlaveNodeNum)) + 1; - loctoglob[2] = (2 * master1); - loctoglob[3] = (2 * master1) + 1; - loctoglob[4] = (2 * master2); - loctoglob[5] = (2 * master2) + 1; - } else if (sdofNd == 2 && m1dofNd == 2 && m2dofNd == 2) { - loctoglob[0] = (2 * slave); - loctoglob[1] = (2 * slave) + 1; - loctoglob[2] = (2 * master1); - loctoglob[3] = (2 * master1) + 1; - loctoglob[4] = (2 * master2); - loctoglob[5] = (2 * master2) + 1; - } else if (sdofNd == 3 && m1dofNd == 3 && m2dofNd == 3) { - loctoglob[0] = (3 * slave); - loctoglob[1] = (3 * slave) + 1; - loctoglob[2] = (3 * master1); - loctoglob[3] = (3 * master1) + 1; - loctoglob[4] = (3 * master2); - loctoglob[5] = (3 * master2) + 1; + int sdofNd = nodePointers[secondary]->getNumberDOF(); + int p1dofNd = nodePointers[primary1]->getNumberDOF(); + int p2dofNd = nodePointers[primary2]->getNumberDOF(); + + if (sdofNd == 2 && p1dofNd == 3 && p2dofNd == 3) { + loctoglob[0] = (2 * secondary); + loctoglob[1] = (2 * secondary) + 1; + loctoglob[2] = (2 * SecondaryNodeNum) + (3 * (primary1 - SecondaryNodeNum)); + loctoglob[3] = (2 * SecondaryNodeNum) + (3 * (primary1 - SecondaryNodeNum)) + 1; + loctoglob[4] = (2 * SecondaryNodeNum) + (3 * (primary2 - SecondaryNodeNum)); + loctoglob[5] = (2 * SecondaryNodeNum) + (3 * (primary2 - SecondaryNodeNum)) + 1; + } else if (sdofNd == 3 && p1dofNd == 2 && p2dofNd == 2) { + loctoglob[0] = (2 * SecondaryNodeNum) + (3 * (secondary - SecondaryNodeNum)); + loctoglob[1] = (2 * SecondaryNodeNum) + (3 * (secondary - SecondaryNodeNum)) + 1; + loctoglob[2] = (2 * primary1); + loctoglob[3] = (2 * primary1) + 1; + loctoglob[4] = (2 * primary2); + loctoglob[5] = (2 * primary2) + 1; + } else if (sdofNd == 2 && p1dofNd == 2 && p2dofNd == 2) { + loctoglob[0] = (2 * secondary); + loctoglob[1] = (2 * secondary) + 1; + loctoglob[2] = (2 * primary1); + loctoglob[3] = (2 * primary1) + 1; + loctoglob[4] = (2 * primary2); + loctoglob[5] = (2 * primary2) + 1; + } else if (sdofNd == 3 && p1dofNd == 3 && p2dofNd == 3) { + loctoglob[0] = (3 * secondary); + loctoglob[1] = (3 * secondary) + 1; + loctoglob[2] = (3 * primary1); + loctoglob[3] = (3 * primary1) + 1; + loctoglob[4] = (3 * primary2); + loctoglob[5] = (3 * primary2) + 1; } } */ -void ZeroLengthInterface2D::GlobalResidAndTangentOrder(int slave, int master1, int master2) +void ZeroLengthInterface2D::GlobalResidAndTangentOrder(int secondary, int primary1, int primary2) { // create a vector for converting local matrix to global - int sdofNd = nodePointers[slave]->getNumberDOF(); - int m1dofNd = nodePointers[master1]->getNumberDOF(); - int m2dofNd = nodePointers[master2]->getNumberDOF(); - int nd[3] = { slave, master1, master2 }; - int dof[3] = { sdofNd, m1dofNd, m2dofNd }; + int sdofNd = nodePointers[secondary]->getNumberDOF(); + int p1dofNd = nodePointers[primary1]->getNumberDOF(); + int p2dofNd = nodePointers[primary2]->getNumberDOF(); + int nd[3] = { secondary, primary1, primary2 }; + int dof[3] = { sdofNd, p1dofNd, p2dofNd }; for (int i = 0 ; i < 3 ; i++) { - if (dof[i] == SlaveDof) + if (dof[i] == SecondaryDof) { loctoglob[2 * i] = (dof[i] * nd[i]); loctoglob[2 * i + 1] = (dof[i] * nd[i] + 1); - } else if (dof[i] == MasterDof) + } else if (dof[i] == PrimaryDof) { - int add = SlaveDof * SlaveNodeNum; - int pos = nd[i] - SlaveNodeNum; + int add = SecondaryDof * SecondaryNodeNum; + int pos = nd[i] - SecondaryNodeNum; loctoglob[2 * i] = (dof[i] * pos) + add; loctoglob[2 * i + 1] = (dof[i] * pos + 1) + add; } else { - // error message dof is no equal with either of slave and master dofs + // error message dof is no equal with either of secondary and primary dofs } } } -void ZeroLengthInterface2D::formLocalResidAndTangent( int tang_flag , int slave, int master1, int master2, int stage) +void ZeroLengthInterface2D::formLocalResidAndTangent( int tang_flag , int secondary, int primary1, int primary2, int stage) { // trial frictional force vectors (in local coordinate) double t_trial; @@ -589,29 +589,29 @@ void ZeroLengthInterface2D::formLocalResidAndTangent( int tang_flag , int slave int i, j; // set the first value to zero - pressure(slave) = 0; + pressure(secondary) = 0; t_trial=0; // int IsContact; // detect contact and set flag - ContactFlag = contactDetect(slave,master1,master2, stage); + ContactFlag = contactDetect(secondary,primary1,primary2, stage); if (ContactFlag == 1) // contacted { // create a vector for converting local matrix to global - GlobalResidAndTangentOrder(slave, master1, master2); + GlobalResidAndTangentOrder(secondary, primary1, primary2); // contact presure; - pressure(slave) = Kn * normal_gap(slave); // pressure is positive if in contact + pressure(secondary) = Kn * normal_gap(secondary); // pressure is positive if in contact - double ng = normal_gap(slave); + double ng = normal_gap(secondary); - t_trial = Kt * (shear_gap(slave) - stored_shear_gap(slave)); // trial shear force + t_trial = Kt * (shear_gap(secondary) - stored_shear_gap(secondary)); // trial shear force // Coulomb friction law, trial state //TtrNorm=t_trial.Norm(); TtrNorm = sqrt(t_trial * t_trial); - Phi = TtrNorm - fc * pressure(slave); + Phi = TtrNorm - fc * pressure(secondary); if (Phi <= 0 ) { // stick case if ( tang_flag == 1 ) { @@ -623,7 +623,7 @@ void ZeroLengthInterface2D::formLocalResidAndTangent( int tang_flag , int slave } } //endif tang_flag // force - for (i = 0; i < 6; i++) resid(loctoglob[i]) += pressure(slave) * N(i) + t_trial * T(i); //2D + for (i = 0; i < 6; i++) resid(loctoglob[i]) += pressure(secondary) * N(i) + t_trial * T(i); //2D } // end if stick else { // slide case, non-symmetric stiff ContactFlag=2; // set the contactFlag for sliding @@ -636,8 +636,8 @@ void ZeroLengthInterface2D::formLocalResidAndTangent( int tang_flag , int slave } //endfor j // force } // endif tang_flag - double shear = fc * pressure(slave) * (t_trial/TtrNorm); - for (i = 0; i < 6; i++) resid(loctoglob[i]) += (pressure(slave) * N(i)) + (shear * T(i)) ; //2D + double shear = fc * pressure(secondary) * (t_trial/TtrNorm); + for (i = 0; i < 6; i++) resid(loctoglob[i]) += (pressure(secondary) * N(i)) + (shear * T(i)) ; //2D } //endif slide } // endif ContactFlag==1 } @@ -649,25 +649,25 @@ void ZeroLengthInterface2D::formGlobalResidAndTangent( int tang_flag ) // but on contrary in the second loop the node to node contact // will be considered and this can be controlled by "stage = 0 or 1" - // loop over slave nodes and find the nodes - // which are in contact with master's segments - for (int i = 0 ; i < SlaveNodeNum; i++) { - for (int j = SlaveNodeNum ; j < SlaveNodeNum + MasterNodeNum - 1; j++) { + // loop over secondary nodes and find the nodes + // which are in contact with primary's segments + for (int i = 0 ; i < SecondaryNodeNum; i++) { + for (int j = SecondaryNodeNum ; j < SecondaryNodeNum + PrimaryNodeNum - 1; j++) { formLocalResidAndTangent( tang_flag, i, j, j+1 , 0); // stage = 0 // } } - // loop over master nodes and find the nodes - // which are in contact with slave's segments - for (int i = SlaveNodeNum ; i < SlaveNodeNum + MasterNodeNum; i++) { - for (int j = 0 ; j < SlaveNodeNum - 1; j++) { + // loop over primary nodes and find the nodes + // which are in contact with secondary's segments + for (int i = SecondaryNodeNum ; i < SecondaryNodeNum + PrimaryNodeNum; i++) { + for (int j = 0 ; j < SecondaryNodeNum - 1; j++) { formLocalResidAndTangent( tang_flag, i, j, j+1 , 1); // stage = 1 // } } } -// element zeroLengthInterface2D $eleTag -sNdNum $sNdNum -mNdNum $mNdNum -dof $sdof $mdof -Nodes $Nodes $Kn $Kt $phi +// element zeroLengthInterface2D $eleTag -sNdNum $sNdNum -pNdNum $pNdNum -dof $sdof $mdof -Nodes $Nodes $Kn $Kt $phi // static int numZeroLengthInterface2D = 0; @@ -685,7 +685,7 @@ OPS_ZeroLengthInterface2D(void) { int numData = 0; // get the ele tag - int eleTag, sNdNum, mNdNum, sDOF, mDOF; + int eleTag, sNdNum, pNdNum, sDOF, mDOF; numData = 1; if (OPS_GetInt(&numData, &eleTag) != 0) { @@ -700,7 +700,7 @@ OPS_ZeroLengthInterface2D(void) { return 0; } - // get the number of slave nodes + // get the number of secondary nodes numData = 1; if (OPS_GetInt(&numData, &sNdNum) != 0) { opserr << "ZeroLengthInterface2D::WARNING invalied sNdNum \n"; @@ -710,14 +710,14 @@ OPS_ZeroLengthInterface2D(void) { numData = 10; nextString = OPS_GetString(); - if (strcmp(nextString,"-mNdNum") != 0) { - opserr << "ZeroLengthInterface2D:: expecting -mNdNum\n"; + if (strcmp(nextString,"-mNdNum") != 0 && strcmp(nextString,"-pNdNum") != 0) { + opserr << "ZeroLengthInterface2D:: expecting -pNdNum\n"; return 0; } numData = 1; - if (OPS_GetInt(&numData, &mNdNum) != 0) { - opserr << "ZeroLengthInterface2D::WARNING invalied sNdNum \n"; + if (OPS_GetInt(&numData, &pNdNum) != 0) { + opserr << "ZeroLengthInterface2D::WARNING invalied pNdNum \n"; return 0; } @@ -726,7 +726,7 @@ OPS_ZeroLengthInterface2D(void) { if (strcmp(nextString,"-dof") != 0) { opserr << "ZeroLengthInterface2D:: expecting -sdof in "<< - "element zeroLengthInterface2D eleTag? -sNdNum sNdNum? -mNdNum mNdNum? -dof sdof? mdof? -Nodes Nodes? Kn? Kt? phi? \n" ; + "element zeroLengthInterface2D eleTag? -sNdNum sNdNum? -pNdNum pNdNum? -dof sdof? mdof? -Nodes Nodes? Kn? Kt? phi? \n" ; return 0; } @@ -744,9 +744,9 @@ OPS_ZeroLengthInterface2D(void) { // a quick check on number of args int argc = OPS_GetNumRemainingInputArgs(); - if (argc < 3 + sNdNum + mNdNum) { + if (argc < 3 + sNdNum + pNdNum) { opserr << "ZeroLengthInterface2D::WARNING too few arguments " << - "element zeroLengthInterface2D eleTag? -sNdNum sNdNum? -mNdNum mNdNum? -dof sdof? mdof? -Nodes Nodes? Kn? Kt? phi? \n" ; + "element zeroLengthInterface2D eleTag? -sNdNum sNdNum? -pNdNum pNdNum? -dof sdof? mdof? -Nodes Nodes? Kn? Kt? phi? \n" ; return 0; } @@ -759,7 +759,7 @@ OPS_ZeroLengthInterface2D(void) { } // read the Nodes values - numData = sNdNum+mNdNum; + numData = sNdNum+pNdNum; int *theNodeData = new int[numData]; ID Nodes(theNodeData, numData); @@ -781,7 +781,7 @@ OPS_ZeroLengthInterface2D(void) { // now we create the element and add it to the domain // - theEle = new ZeroLengthInterface2D(eleTag, sNdNum, mNdNum, sDOF, mDOF, Nodes, dData[0], dData[1], dData[2]); + theEle = new ZeroLengthInterface2D(eleTag, sNdNum, pNdNum, sDOF, mDOF, Nodes, dData[0], dData[1], dData[2]); return theEle; } diff --git a/SRC/element/zeroLength/ZeroLengthInterface2D.h b/SRC/element/zeroLength/ZeroLengthInterface2D.h index e6d0323c6b..7c6c5e66f0 100644 --- a/SRC/element/zeroLength/ZeroLengthInterface2D.h +++ b/SRC/element/zeroLength/ZeroLengthInterface2D.h @@ -52,15 +52,15 @@ +----+----+----+----+----+----+----+----+----+----+----+----+----+----+------*/ /* - element zeroLengthInterface2D eleTag? -sNdNum sNdNum? -mNdNum mNdNum? �dof sdof? mdof? -Nodes Nodes? Kn? Kt? phi? + element zeroLengthInterface2D eleTag? -sNdNum sNdNum? -pNdNum pNdNum? �dof sdof? mdof? -Nodes Nodes? Kn? Kt? phi? Description: This file contains the class definition for ZeroLengthContact2D. [1] The contact element is node-to-segment (NTS) contact. The relation follows Mohr-coulomb frictional law: T = N * tan($phi), where T is tangential force and N is normal force across the interface. $phi is friction angle. -[2] For 2D contact, slave nodes and master nodes must be 2 DOF and notice note - that the slave and master nodes must be entered in counterclockwise order. +[2] For 2D contact, secondary nodes and primary nodes must be 2 DOF and notice note + that the secondary and primary nodes must be entered in counterclockwise order. [3] The resulting tangent from the contact element is non-symmetric. Switch to the non-symmetric matrix solver if convergence problem is experienced. [4] As opposed to node-to-node contact, predefined normal vector for node-to-segment (NTS) @@ -94,7 +94,7 @@ class ZeroLengthInterface2D: public Element { public: // Constructor - ZeroLengthInterface2D(int tag, int sNdNum, int mNdNum, int sDof, int mDof, const ID& Nodes, + ZeroLengthInterface2D(int tag, int sNdNum, int pNdNum, int sDof, int mDof, const ID& Nodes, double Kn, double Kt, double fRatio); // Null constructor ZeroLengthInterface2D(); @@ -156,26 +156,26 @@ class ZeroLengthInterface2D: public Element // Normal and Tangental Vectors for Elemental Nodes, (4*1) Vector N; Vector T; - Vector ContactNormal; // out normal of master element + Vector ContactNormal; // out normal of primary element int ContactFlag; // 0: not contact; 1: stick; 2: slide int numDOF; // number of dof for ZeroLength // detect the contact and set flag int contactDetect(int s, int m1, int m2, int stage); //form residual and tangent - void formLocalResidAndTangent( int tang_flag , int slave, int master1, int master2, int stage); + void formLocalResidAndTangent( int tang_flag , int secondary, int primary1, int primary2, int stage); void formGlobalResidAndTangent(int tang_flag ); - void GlobalResidAndTangentOrder(int slave, int master1, int master2); - void GlobalResidAndTangentOrder2(int slave, int master1, int master2); + void GlobalResidAndTangentOrder(int secondary, int primary1, int primary2); + void GlobalResidAndTangentOrder2(int secondary, int primary1, int primary2); Matrix *Ki; // pointer to objects matrix (a class Matrix) Vector *load; // pointer to objects vector (a class Vector) // variables for 2D contact Matrix stiff; // for stiff matrix Vector resid; // for force residual vector Matrix zeroMatrix; - int SlaveNodeNum; - int MasterNodeNum; - int SlaveDof; - int MasterDof; + int SecondaryNodeNum; + int PrimaryNodeNum; + int SecondaryDof; + int PrimaryDof; double *restore_shear_gap; int loctoglob[6]; }; diff --git a/SRC/interpreter/OpenSeesElementCommands.cpp b/SRC/interpreter/OpenSeesElementCommands.cpp index 073502d369..ba4ba5f28c 100644 --- a/SRC/interpreter/OpenSeesElementCommands.cpp +++ b/SRC/interpreter/OpenSeesElementCommands.cpp @@ -104,6 +104,7 @@ void* OPS_ShellMITC9(); void* OPS_ShellDKGQ(); void* OPS_ShellDKGT(); void* OPS_ShellNLDKGQ(); +void* OPS_ASDShellQ4(); void* OPS_CoupledZeroLength(); void* OPS_BeamContact2D(); void* OPS_BeamContact2Dp(); @@ -148,8 +149,11 @@ void* OPS_MixedBeamColumn2d(); void* OPS_MixedBeamColumn3d(); void* OPS_ForceBeamColumnCBDI2d(); void* OPS_ForceBeamColumnCSBDI2d(); +void* OPS_ForceBeamColumnCBDI3d(); +void* OPS_ForceBeamColumnCSBDI3d(); void* OPS_ForceBeamColumnWarping2d(); void* OPS_ElasticForceBeamColumnWarping2d(); +void* OPS_DispBeamColumn3dID(); void* OPS_DispBeamColumn2dThermal(); void* OPS_DispBeamColumn3dThermal(); void* OPS_ElasticForceBeamColumn2d(); @@ -161,6 +165,9 @@ void* OPS_FourNodeQuadWithSensitivity(); void* OPS_EnhancedQuad(); void* OPS_ConstantPressureVolumeQuad(); void* OPS_NineNodeMixedQuad(); +void* OPS_NineNodeQuad(); +void* OPS_EightNodeQuad(); +void* OPS_SixNodeTri(); void* OPS_FourNodeQuadUP(); void* OPS_BrickUP(); void* OPS_NineFourNodeQuadUP(); @@ -236,12 +243,35 @@ namespace { } } + static void* OPS_ForceBeamColumnCBDI() + { + int ndm = OPS_GetNDM(); + if(ndm == 2) { + ID info; + return OPS_ForceBeamColumnCBDI2d(); + } else { + return OPS_ForceBeamColumnCBDI3d(); + } + } + + static void* OPS_ForceBeamColumnCSBDI() + { + int ndm = OPS_GetNDM(); + if(ndm == 2) { + ID info; + return OPS_ForceBeamColumnCSBDI2d(); + } else { + return OPS_ForceBeamColumnCSBDI3d(); + } + } + static void* OPS_ForceBeamColumnThermal() { int ndm = OPS_GetNDM(); if(ndm == 2) { return OPS_ForceBeamColumn2dThermal(); } else { + return 0; //return OPS_ForceBeamColumn3dThermal(); } } @@ -449,6 +479,18 @@ namespace { } } + static void* OPS_DispBeamColumn3dID() + { + int ndm = OPS_GetNDM(); + if (ndm == 2) { + return 0; + // return OPS_DispBeamColumn2dID(); + } + else { + return OPS_DispBeamColumn3dID(); + } + } + static int setUpFunctions(void) { functionMap.insert(std::make_pair("KikuchiBearing", &OPS_KikuchiBearing)); @@ -505,6 +547,9 @@ namespace { functionMap.insert(std::make_pair("quadWithSensitivity", &OPS_FourNodeQuadWithSensitivity)); functionMap.insert(std::make_pair("quad", &OPS_FourNodeQuad)); functionMap.insert(std::make_pair("stdQuad", &OPS_FourNodeQuad)); + functionMap.insert(std::make_pair("quad9n", &OPS_NineNodeQuad)); + functionMap.insert(std::make_pair("quad8n", &OPS_EightNodeQuad)); + functionMap.insert(std::make_pair("tri6n", &OPS_SixNodeTri)); functionMap.insert(std::make_pair("dispBeamColumnWithSensitivity", &OPS_DispBeamColumnWithSensitivity)); functionMap.insert(std::make_pair("elasticForceBeamColumn", &OPS_ElasticForceBeamColumn)); functionMap.insert(std::make_pair("dispBeamColumnThermal", &OPS_DispBeamColumnThermal)); @@ -578,10 +623,13 @@ namespace { functionMap.insert(std::make_pair("ShellNL", &OPS_ShellMITC9)); functionMap.insert(std::make_pair("shellMITC9", &OPS_ShellMITC9)); functionMap.insert(std::make_pair("ShellMITC9", &OPS_ShellMITC9)); + functionMap.insert(std::make_pair("shellDKGQ", &OPS_ShellDKGQ)); functionMap.insert(std::make_pair("ShellDKGQ", &OPS_ShellDKGQ)); functionMap.insert(std::make_pair("shellDKGT", &OPS_ShellDKGT)); + functionMap.insert(std::make_pair("ShellDKGT", &OPS_ShellDKGT)); functionMap.insert(std::make_pair("ShellNLDKGQ", &OPS_ShellNLDKGQ)); functionMap.insert(std::make_pair("shellNLDKGQ", &OPS_ShellNLDKGQ)); + functionMap.insert(std::make_pair("ASDShellQ4", &OPS_ASDShellQ4)); functionMap.insert(std::make_pair("CoupledZeroLength", &OPS_CoupledZeroLength)); functionMap.insert(std::make_pair("ZeroLengthCoupled", &OPS_CoupledZeroLength)); functionMap.insert(std::make_pair("BeamContact2d", &OPS_BeamContact2D)); @@ -607,9 +655,10 @@ namespace { functionMap.insert(std::make_pair("forceBeamColumn", &OPS_ForceBeamColumn)); functionMap.insert(std::make_pair("nonlinearBeamColumn", &OPS_NonlinearBeamColumn)); functionMap.insert(std::make_pair("dispBeamColumn", &OPS_DispBeamColumn)); + functionMap.insert(std::make_pair("dispBeamColumn3dID", &OPS_DispBeamColumn3dID)); functionMap.insert(std::make_pair("dispBeamColumnNL", &OPS_DispBeamColumnNL)); - functionMap.insert(std::make_pair("forceBeamColumnCBDI", &OPS_ForceBeamColumnCBDI2d)); - functionMap.insert(std::make_pair("forceBeamColumnCSBDI", &OPS_ForceBeamColumnCSBDI2d)); + functionMap.insert(std::make_pair("forceBeamColumnCBDI", &OPS_ForceBeamColumnCBDI)); + functionMap.insert(std::make_pair("forceBeamColumnCSBDI", &OPS_ForceBeamColumnCSBDI)); functionMap.insert(std::make_pair("mixedBeamColumn", &OPS_MixedBeamColumn)); functionMap.insert(std::make_pair("zeroLength", &OPS_ZeroLength)); functionMap.insert(std::make_pair("zeroLengthSection", &OPS_ZeroLengthSection)); diff --git a/SRC/interpreter/OpenSeesOutputCommands.cpp b/SRC/interpreter/OpenSeesOutputCommands.cpp index 8b427d3ba5..c5492b9d88 100644 --- a/SRC/interpreter/OpenSeesOutputCommands.cpp +++ b/SRC/interpreter/OpenSeesOutputCommands.cpp @@ -50,6 +50,7 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #include #include #include +#include #include #include #include @@ -67,6 +68,8 @@ void* OPS_EnvelopeNodeRecorder(); void* OPS_ElementRecorder(); void* OPS_EnvelopeElementRecorder(); void* OPS_PVDRecorder(); +void* OPS_AlgorithmRecorder(); +void* OPS_RemoveRecorder(); BackgroundMesh& OPS_getBgMesh(); //void* OPS_DriftRecorder(); @@ -92,6 +95,10 @@ namespace { recordersMap.insert(std::make_pair("EnvelopeElement", &OPS_EnvelopeElementRecorder)); recordersMap.insert(std::make_pair("PVD", &OPS_PVDRecorder)); recordersMap.insert(std::make_pair("BgPVD", &OPS_PVDRecorder)); + recordersMap.insert(std::make_pair("Remove", &OPS_RemoveRecorder)); + recordersMap.insert(std::make_pair("ElementRemoval", &OPS_RemoveRecorder)); + recordersMap.insert(std::make_pair("NodeRemoval", &OPS_RemoveRecorder)); + recordersMap.insert(std::make_pair("Collapse", &OPS_RemoveRecorder)); //recordersMap.insert(std::make_pair("Drift", &OPS_DriftRecorder)); //recordersMap.insert(std::make_pair("Pattern", &OPS_PatternRecorder)); @@ -141,6 +148,14 @@ int OPS_Recorder() } } + // set recorder tag as result + int size = 1; + int tag = theRecorder->getTag(); + if (OPS_SetIntOutput(&size, &tag, true) < 0) { + opserr << "ERROR: failed to return recorder tag\n"; + return -1; + } + return 0; } @@ -1643,20 +1658,16 @@ int OPS_nodeDOFs() int OPS_nodeMass() { - if (OPS_GetNumRemainingInputArgs() < 2) { - opserr << "WARNING want - nodeMass nodeTag? nodeDOF?\n"; + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING want - nodeMass nodeTag?\n"; return -1; } - int tag, dof; + int tag; int numdata = 1; if (OPS_GetIntInput(&numdata, &tag) < 0) { - opserr << "WARNING nodeMass nodeTag? nodeDOF? \n"; - return -1; - } - if (OPS_GetIntInput(&numdata, &dof) < 0) { - opserr << "WARNING nodeMass nodeTag? nodeDOF? \n"; + opserr << "WARNING nodeMass nodeTag?\n"; return -1; } @@ -1668,17 +1679,16 @@ int OPS_nodeMass() opserr << "WARNING nodeMass node " << tag << " not found" << endln; return -1; } + int numDOF = theNode->getNumberDOF(); - if (dof < 1 || dof > numDOF) { - opserr << "WARNING nodeMass dof " << dof << " not in range" << endln; - return -1; - } - else { - const Matrix &mass = theNode->getMass(); - double value = mass(dof-1,dof-1); - if (OPS_SetDoubleOutput(&numdata, &value, true) < 0) { - opserr << "WARNING nodeMass failed to set mass\n"; - } + const Matrix &mass = theNode->getMass(); + std::vector data(numDOF); + for (int i = 0; i < numDOF; i++) + data[i] = mass(i,i); + + if (OPS_SetDoubleOutput(&numDOF, &data[0], false) < 0) { + opserr << "WARNING nodeMass failed to set mass\n"; + return -1; } return 0; @@ -1807,58 +1817,61 @@ int OPS_getEleTags() return 0; } -int OPS_getNodeTags() -{ - Domain* theDomain = OPS_GetDomain(); +int OPS_getNodeTags() { + Domain *theDomain = OPS_GetDomain(); if (theDomain == 0) return -1; std::vector nodetags; if (OPS_GetNumRemainingInputArgs() < 1) { + // return all nodes + Node *theNode; + NodeIter &nodeIter = theDomain->getNodes(); - // return all nodes - Node *theNode; - NodeIter &nodeIter = theDomain->getNodes(); - - while ((theNode = nodeIter()) != 0) { - nodetags.push_back(theNode->getTag()); - } - } else if (OPS_GetNumRemainingInputArgs() == 2) { - - // return nodes in mesh - const char* type = OPS_GetString(); - if (strcmp(type,"-mesh") == 0) { - int tag; - int num = 1; - if (OPS_GetIntInput(&num, &tag) < 0) { - opserr << "WARNING: failed to get mesh tag\n"; - return -1; - } - Mesh* msh = OPS_getMesh(tag); - if (msh == 0) { - opserr << "WARNING: mesh "<getNodeTags(); - for (int i=0; igetNewNodeTags(); - for (int i=0; igetTag()); + } + } else if (OPS_GetNumRemainingInputArgs() > 1) { + // return nodes in mesh + const char *type = OPS_GetString(); + if (strcmp(type, "-mesh") == 0) { + int numtags = OPS_GetNumRemainingInputArgs(); + std::set nodeset; + for (int i = 0; i < numtags; ++i) { + int tag; + int num = 1; + if (OPS_GetIntInput(&num, &tag) < 0) { + opserr << "WARNING: failed to get mesh tag\n"; + return -1; + } + Mesh *msh = OPS_getMesh(tag); + if (msh == 0) { + opserr << "WARNING: mesh " << tag + << " does not exist\n"; + return -1; + } + const ID &tags = msh->getNodeTags(); + for (int i = 0; i < tags.Size(); ++i) { + nodeset.insert(tags(i)); + } + const ID &newtags = msh->getNewNodeTags(); + for (int i = 0; i < newtags.Size(); ++i) { + nodeset.insert(newtags(i)); + } + } + nodetags.assign(nodeset.begin(), nodeset.end()); + } } int size = 0; - int* data = 0; + int *data = 0; if (!nodetags.empty()) { size = (int)nodetags.size(); data = &nodetags[0]; } if (OPS_SetIntOutput(&size, data, false) < 0) { - opserr << "WARNING failed to set outputs\n"; - return -1; + opserr << "WARNING failed to set outputs\n"; + return -1; } return 0; @@ -2203,7 +2216,7 @@ int OPS_sectionLocation() int data[2]; if (OPS_GetIntInput(&numdata, data) < 0) { - opserr << "WARNING sectionLocation eleTag? secNum? dof? - could not read int input? \n"; + opserr << "WARNING sectionLocation eleTag? secNum? - could not read int input? \n"; return -1; } @@ -2272,7 +2285,7 @@ int OPS_sectionWeight() int data[2]; if (OPS_GetIntInput(&numdata, data) < 0) { - opserr << "WARNING sectionWeight eleTag? secNum? dof? - could not read int input? \n"; + opserr << "WARNING sectionWeight eleTag? secNum? - could not read int input? \n"; return -1; } @@ -2324,6 +2337,174 @@ int OPS_sectionWeight() return 0; } +int OPS_sectionDisplacement() +{ + // make sure at least one other argument to contain type of system + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "WARNING want - sectionDisplacement eleTag? secNum? \n"; + return -1; + } + + //opserr << "sectionWeight: "; + //for (int i = 0; i < argc; i++) + // opserr << argv[i] << ' ' ; + //opserr << endln; + + int numdata = 2; + int data[2]; + + if (OPS_GetIntInput(&numdata, data) < 0) { + opserr << "WARNING sectionDisplacement eleTag? secNum? <-local>- could not read int input? \n"; + return -1; + } + + int tag = data[0]; + int secNum = data[1]; + bool local = false; + + if (OPS_GetNumRemainingInputArgs() > 0) { + const char* localGlobal = OPS_GetString(); + if (strstr(localGlobal,"local") != 0) + local = true; + } + + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + Element *theElement = theDomain->getElement(tag); + if (theElement == 0) { + opserr << "WARNING sectionDisplacement element with tag " << tag << " not found in domain \n"; + return -1; + } + + int argcc = 2; + char a[80] = "sectionDisplacements"; + const char *argvv[2]; + argvv[0] = a; + if (local) + argvv[1] = "local"; + else + argvv[2] = "global"; + + DummyStream dummy; + + Response *theResponse = theElement->setResponse(argvv, argcc, dummy); + if (theResponse == 0) { + return 0; + } + + theResponse->getResponse(); + Information &info = theResponse->getInformation(); + + const Matrix &theMatrix = *(info.theMatrix); + if (secNum <= 0 || secNum > theMatrix.noRows()) { + opserr << "WARNING invalid secNum\n"; + delete theResponse; + return -1; + } + + double value[3]; + value[0] = theMatrix(secNum-1,0); + value[1] = theMatrix(secNum-1,1); + value[2] = theMatrix(secNum-1,2); + + numdata = 3; + if (OPS_SetDoubleOutput(&numdata, &value[0], false) < 0) { + opserr << "WARNING failed to set output\n"; + delete theResponse; + return -1; + } + + delete theResponse; + + return 0; +} + +int OPS_cbdiDisplacement() +{ + // make sure at least one other argument to contain type of system + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "WARNING want - cbdiDisplacement eleTag? x/L? \n"; + return -1; + } + + //opserr << "sectionWeight: "; + //for (int i = 0; i < argc; i++) + // opserr << argv[i] << ' ' ; + //opserr << endln; + + int numdata = 1; + int data[1]; + double ddata[1]; + + if (OPS_GetIntInput(&numdata, data) < 0) { + opserr << "WARNING cbdiDisplacement eleTag? x/L? - could not read int input? \n"; + return -1; + } + if (OPS_GetDoubleInput(&numdata, ddata) < 0) { + opserr << "WARNING cbdiDisplacement eleTag? x/L? - could not read double input? \n"; + return -1; + } + + int tag = data[0]; + double xOverL = ddata[0]; + + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + Element *theElement = theDomain->getElement(tag); + if (theElement == 0) { + opserr << "WARNING cbdiDisplacment element with tag " << tag << " not found in domain \n"; + return -1; + } + + int argcc = 1; + char a[80] = "cbdiDisplacements"; + const char *argvv[1]; + argvv[0] = a; + + DummyStream dummy; + + Response *theResponse = theElement->setResponse(argvv, argcc, dummy); + if (theResponse == 0) { + return 0; + } + + theResponse->getResponse(); + Information &info = theResponse->getInformation(); + + const Matrix &theMatrix = *(info.theMatrix); + if (xOverL < 0.0 || xOverL > 1.0) { + opserr << "WARNING invalid xOverL\n"; + delete theResponse; + return -1; + } + + double value[3]; // Need to interpolate + int N = theMatrix.noRows(); + double dx = 1.0/(N-1); + for (int i = 0; i < N; i++) { + double xi = double(i)/(N-1); + double xf = double(i+1)/(N-1); + if (xOverL >= xi && xOverL < xf) { + value[0] = theMatrix(i,0) + (xOverL-xi)/(xf-xi)*(theMatrix(i+1,0)-theMatrix(i,0)); + value[1] = theMatrix(i,1) + (xOverL-xi)/(xf-xi)*(theMatrix(i+1,1)-theMatrix(i,1)); + value[2] = theMatrix(i,2) + (xOverL-xi)/(xf-xi)*(theMatrix(i+1,2)-theMatrix(i,2)); + } + } + + numdata = 3; + if (OPS_SetDoubleOutput(&numdata, &value[0], false) < 0) { + opserr << "WARNING failed to set output\n"; + delete theResponse; + return -1; + } + + delete theResponse; + + return 0; +} + int OPS_basicDeformation() { // make sure at least one other argument to contain type of system diff --git a/SRC/interpreter/OpenSeesPatternCommands.cpp b/SRC/interpreter/OpenSeesPatternCommands.cpp index 2369d703ad..3b3eeef727 100644 --- a/SRC/interpreter/OpenSeesPatternCommands.cpp +++ b/SRC/interpreter/OpenSeesPatternCommands.cpp @@ -279,21 +279,25 @@ int OPS_ElementalLoad() strcmp(type,"beamUniform") == 0) { if (ndm == 2) { - // wt, wa, aL, bL - double data[4] = {0.0, 0.0, 0.0, 1.0}; + // wta, waa, aL, bL, wtb, wab + double data[6] = {0.0, 0.0, 0.0, 1.0, 0.0, 0.0}; int numdata = OPS_GetNumRemainingInputArgs(); if (numdata < 1) { - opserr<<"WARNING eleLoad - beamUniform want Wy \n"; + opserr<<"WARNING eleLoad - beamUniform want Wya \n"; return -1; } - if (numdata > 4) numdata = 4; + if (numdata > 6) numdata = 6; if (OPS_GetDoubleInput(&numdata, data) < 0) { opserr<<"WARNING eleLoad - invalid value for beamUniform\n"; return -1; } for (int i=0; i 0.0 || data[3] < 1.0) - theLoad = new Beam2dPartialUniformLoad(eleLoadTag, data[0], data[1], data[2], data[3], theEleTags(i)); + if (numdata == 3 || numdata == 4) { + data[4] = data[0]; + data[5] = data[1]; + } + if (data[2] > 0.0 || data[3] < 1.0 || numdata > 4) + theLoad = new Beam2dPartialUniformLoad(eleLoadTag, data[0], data[4], data[1], data[5], data[2], data[3], theEleTags(i)); else theLoad = new Beam2dUniformLoad(eleLoadTag, data[0], data[1], theEleTags(i)); diff --git a/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp b/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp index c4a74ea1a5..b89ebe74d1 100644 --- a/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp +++ b/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp @@ -122,6 +122,7 @@ void* OPS_PathIndependentMaterial(); void* OPS_Pinching4Material(); void* OPS_ECC01(); void* OPS_SelfCenteringMaterial(); +void* OPS_ASD_SMA_3K(); void* OPS_ViscousMaterial(); void* OPS_BoucWenMaterial(); void* OPS_BWBN(); @@ -171,6 +172,7 @@ void* OPS_UVCuniaxial(); void* OPS_IMKBilin(); void* OPS_IMKPinching(); void* OPS_IMKPeakOriented(); +void* OPS_SLModel(); void* OPS_ArctangentBackbone(); void* OPS_BilinearBackbone(); @@ -279,6 +281,7 @@ namespace { uniaxialMaterialsMap.insert(std::make_pair("Pinching4", &OPS_Pinching4Material)); uniaxialMaterialsMap.insert(std::make_pair("ECC01", &OPS_ECC01)); uniaxialMaterialsMap.insert(std::make_pair("SelfCentering", &OPS_SelfCenteringMaterial)); + uniaxialMaterialsMap.insert(std::make_pair("ASD_SMA_3K", &OPS_ASD_SMA_3K)); uniaxialMaterialsMap.insert(std::make_pair("Viscous", &OPS_ViscousMaterial)); uniaxialMaterialsMap.insert(std::make_pair("BoucWen", &OPS_BoucWenMaterial)); uniaxialMaterialsMap.insert(std::make_pair("BWBN", &OPS_BWBN)); @@ -334,6 +337,7 @@ namespace { uniaxialMaterialsMap.insert(std::make_pair("IMKBilin", &OPS_IMKBilin)); uniaxialMaterialsMap.insert(std::make_pair("IMKPinching", &OPS_IMKPinching)); uniaxialMaterialsMap.insert(std::make_pair("IMKPeakOriented", &OPS_IMKPeakOriented)); + uniaxialMaterialsMap.insert(std::make_pair("SLModel", &OPS_SLModel)); return 0; } diff --git a/SRC/interpreter/PythonModule.cpp b/SRC/interpreter/PythonModule.cpp index b393f9dee0..e016c22a38 100644 --- a/SRC/interpreter/PythonModule.cpp +++ b/SRC/interpreter/PythonModule.cpp @@ -43,6 +43,7 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #include "PythonModule.h" #include "PythonStream.h" +#include // define opserr static PythonStream sserr; @@ -286,6 +287,16 @@ initopensees(void) Py_INCREF(st->error); PyModule_AddObject(pymodule, "OpenSeesError", st->error); + char version[10]; + const char *py_version = ".6"; + for (int i = 0; i < 5; ++i) { + version[i] = OPS_VERSION[i]; + } + for (int i = 0; i < 3; ++i) { + version[5 + i] = py_version[i]; + } + PyModule_AddStringConstant(pymodule, "__version__", version); + sserr.setError(st->error); Py_AtExit(cleanupFunc); diff --git a/SRC/interpreter/PythonWrapper.cpp b/SRC/interpreter/PythonWrapper.cpp index 6094df3f4a..d0aaab7b0b 100644 --- a/SRC/interpreter/PythonWrapper.cpp +++ b/SRC/interpreter/PythonWrapper.cpp @@ -1459,6 +1459,30 @@ static PyObject *Py_ops_sectionWeight(PyObject *self, PyObject *args) return wrapper->getResults(); } +static PyObject *Py_ops_sectionDisplacement(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_sectionDisplacement() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + +static PyObject *Py_ops_cbdiDisplacement(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_cbdiDisplacement() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + static PyObject *Py_ops_basicDeformation(PyObject *self, PyObject *args) { wrapper->resetCommandLine(PyTuple_Size(args), 1, args); @@ -2295,6 +2319,8 @@ PythonWrapper::addOpenSeesCommands() addCommand("sectionFlexibility", &Py_ops_sectionFlexibility); addCommand("sectionLocation", &Py_ops_sectionLocation); addCommand("sectionWeight", &Py_ops_sectionWeight); + addCommand("sectionDisplacement", &Py_ops_sectionDisplacement); + addCommand("cbdiDisplacement", &Py_ops_cbdiDisplacement); addCommand("basicDeformation", &Py_ops_basicDeformation); addCommand("basicForce", &Py_ops_basicForce); addCommand("basicStiffness", &Py_ops_basicStiffness); diff --git a/SRC/material/nD/CPlaneStrain.cpp b/SRC/material/nD/CPlaneStrain.cpp deleted file mode 100644 index 7e2f8f6bb4..0000000000 --- a/SRC/material/nD/CPlaneStrain.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** ****************************************************************** */ - -// $Revision: 1.7 $ -// $Date: 2008/10/20 22:23:03 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/J2PlaneStrain.cpp,v $ - -// -// Send strains in following format : -// -// strain_vec = { eps_00 -// eps_11 -// 2 eps_01 } <--- note the 2 -// -// set eta := 0 for rate independent case -// - -#include -#include -#include - -//static vectors and matrices -Vector CPlaneStrain :: strain_vec(3) ; -Vector CPlaneStrain :: stress_vec(3) ; -Matrix CPlaneStrain :: tangent_matrix(3,3) ; - -//null constructor -CPlaneStrain :: CPlaneStrain( ) : -Concrete( ) -{ } - -//full constructor -CPlaneStrain :: CPlaneStrain( int tag, - double E_i, - double ni_i, - double f01d_i, - double f02d_i, - double f0p_i, - double beta_i, - double An_i, - double Bn_i, - double Ap_i, - double GammaC_i, - double dchemn_i, // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - double dchemp_i, // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - int def_i, - double dpMax_i, - double dnMax_i, - bool srfCompr_i, // 11/03/2013 Diego Talledo: Apply SRF also to compression. - bool isDchemVar_i, // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - double eps_u_i // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - ): -Concrete( tag, ND_TAG_CPlaneStrain, - E_i,ni_i,f01d_i,f02d_i,f0p_i,beta_i,An_i,Bn_i,Ap_i, GammaC_i, dchemn_i, dchemp_i, def_i, dpMax_i, dnMax_i,srfCompr_i,isDchemVar_i, eps_u_i) // Talledo: da sistemare lo 0 -{ - -} - -//elastic constructor -CPlaneStrain :: -CPlaneStrain( int tag, - double E_i, - double ni_i ) : -Concrete( tag, ND_TAG_CPlaneStrain, E_i, ni_i ) -{ - -} - -//destructor -CPlaneStrain :: ~CPlaneStrain( ) -{ - -} - -//make a clone of this material -NDMaterial* CPlaneStrain :: getCopy( ) -{ - CPlaneStrain *clone; - clone = new CPlaneStrain() ; //new instance of this class - *clone = *this ; //asignment to make copy - return clone ; -} - -//send back type of material -const char* CPlaneStrain :: getType( ) const -{ - return "PlaneStrain" ; -} - -//send back order of strain in vector form -int CPlaneStrain :: getOrder( ) const -{ - return 3 ; -} - -//get the strain and integrate plasticity equations -int CPlaneStrain :: setTrialStrain( const Vector &strain_from_element) -{ - strain.Zero( ) ; - - strain(0,0) = strain_from_element(0) ; - strain(1,1) = strain_from_element(1) ; - strain(0,1) = 0.50 * strain_from_element(2) ; - strain(1,0) = strain(0,1) ; - - this->plastic_integrator( ) ; - - return 0 ; -} - -//unused trial strain functions -int CPlaneStrain :: setTrialStrain( const Vector &v, const Vector &r ) -{ - return this->setTrialStrain( v ) ; -} - -int CPlaneStrain :: setTrialStrainIncr( const Vector &v ) -{ - static Vector newStrain(3); - newStrain(0) = strain(0,0) + v(0); - newStrain(1) = strain(1,1) + v(1); - newStrain(2) = 2.0 * strain(0,1) + v(2); - - return this->setTrialStrain(newStrain); -} - -int CPlaneStrain :: setTrialStrainIncr( const Vector &v, const Vector &r ) -{ - return this->setTrialStrainIncr(v); -} - -//send back the strain -const Vector& CPlaneStrain :: getStrain( ) -{ - strain_vec(0) = strain(0,0) ; - strain_vec(1) = strain(1,1) ; - strain_vec(2) = 2.0 * strain(0,1) ; - - return strain_vec ; -} - -//send back the stress -const Vector& CPlaneStrain :: getStress( ) -{ - stress_vec(0) = stress(0,0) ; - stress_vec(1) = stress(1,1) ; - stress_vec(2) = stress(0,1) ; - - return stress_vec ; -} - -//send back the tangent -const Matrix& CPlaneStrain :: getTangent( ) -{ - // matrix to tensor mapping - // Matrix Tensor - // ------- ------- - // 0 0 0 - // 1 1 1 - // 2 0 1 ( or 1 0 ) - // - - tangent_matrix(0,0) = tangent [0][0] [0][0] ; - tangent_matrix(1,1) = tangent [1][1] [1][1] ; - tangent_matrix(2,2) = tangent [0][1] [0][1] ; - - tangent_matrix(0,1) = tangent [0][0] [1][1] ; - tangent_matrix(1,0) = tangent [1][1] [0][0] ; - - tangent_matrix(0,2) = tangent [0][0] [0][1] ; - tangent_matrix(2,0) = tangent [0][1] [0][0] ; - - tangent_matrix(1,2) = tangent [1][1] [0][1] ; - tangent_matrix(2,1) = tangent [0][1] [1][1] ; - - return tangent_matrix ; -} - -//send back the tangent -const Matrix& CPlaneStrain :: getInitialTangent( ) -{ - // matrix to tensor mapping - // Matrix Tensor - // ------- ------- - // 0 0 0 - // 1 1 1 - // 2 0 1 ( or 1 0 ) - // - - this->doInitialTangent(); - - tangent_matrix(0,0) = initialTangent [0][0] [0][0] ; - tangent_matrix(1,1) = initialTangent [1][1] [1][1] ; - tangent_matrix(2,2) = initialTangent [0][1] [0][1] ; - - tangent_matrix(0,1) = initialTangent [0][0] [1][1] ; - tangent_matrix(1,0) = initialTangent [1][1] [0][0] ; - - tangent_matrix(0,2) = initialTangent [0][0] [0][1] ; - tangent_matrix(2,0) = initialTangent [0][1] [0][0] ; - - tangent_matrix(1,2) = initialTangent [1][1] [0][1] ; - tangent_matrix(2,1) = initialTangent [0][1] [1][1] ; - - return tangent_matrix ; -} - -int -CPlaneStrain::commitState( ) -{ - epsilon_p_n = epsilon_p_nplus1 ; - rnp=rnp1p; - rnn=rnp1n; - - strain_n = strain; - stress_n = stress; - - return 0; -} - -int -CPlaneStrain::revertToLastCommit( ) { - - return 0; -} - - -int -CPlaneStrain::revertToStart( ) -{ - this->zero( ) ; - - return 0; -} - -int -CPlaneStrain::sendSelf (int commitTag, Channel &theChannel) -{ - // we place all the data needed to define material and it's state - // int a vector object - static Vector data(14); - int cnt = 0; - data(cnt++) = this->getTag(); - data(cnt++) = E ; - data(cnt++) = ni ; - data(cnt++) = f01d ; - data(cnt++) = f02d ; - data(cnt++) = f0p ; - data(cnt++) = beta ; - data(cnt++) = An ; - data(cnt++) = Bn ; - data(cnt++) = Ap ; - data(cnt++) = rnn ; - data(cnt++) = rnp ; - data(cnt++) = rnp1n; - data(cnt++) = rnp1p; - - - // send the vector object to the channel - if (theChannel.sendVector(this->getDbTag(), commitTag, data) < 0) { - opserr << "CPlaneStrain::sendSelf - failed to send vector to channel\n"; - return -1; - } - return 0; -} - -int -CPlaneStrain::recvSelf (int commitTag, Channel &theChannel, - FEM_ObjectBroker &theBroker) -{ - - // recv the vector object from the channel which defines material param and state - static Vector data(14); - if (theChannel.recvVector(this->getDbTag(), commitTag, data) < 0) { - opserr << "CPlaneStrain::recvSelf - failed to recv vector from channel\n"; - return -1; - } - - // set the material parameters and state variables - int cnt = 0; - this->setTag(data(cnt++)); - E = data(cnt++); - ni = data(cnt++); - f01d = data(cnt++); - f02d = data(cnt++); - f0p = data(cnt++); - beta = data(cnt++); - An = data(cnt++); - Bn = data(cnt++); - Ap = data(cnt++); - rnn = data(cnt++); - rnp = data(cnt++); - rnp1n= data(cnt++); - rnp1p= data(cnt++); - //rnp1n=rnn; - //rnp1p=rnp; - epsilon_p_nplus1 = epsilon_p_n; - - return 0; -} - - - - - - - - diff --git a/SRC/material/nD/CPlaneStress.cpp b/SRC/material/nD/CPlaneStress.cpp deleted file mode 100644 index a56eb2a3dc..0000000000 --- a/SRC/material/nD/CPlaneStress.cpp +++ /dev/null @@ -1,439 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** ****************************************************************** */ - -// $Revision: 1.7 $ -// $Date: 2008/10/20 22:23:03 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/J2PlaneStrain.cpp,v $ - -// -// Send strains in following format : -// -// strain_vec = { eps_00 -// eps_11 -// 2 eps_01 } <--- note the 2 -// -// set eta := 0 for rate independent case -// - -#include -#include -#include - -//static vectors and matrices -Vector CPlaneStress :: strain_vec(3) ; -Vector CPlaneStress :: stress_vec(3) ; -Matrix CPlaneStress :: tangent_matrix(3,3) ; - - -//null constructor -CPlaneStress :: CPlaneStress( ) : -Concrete( ) -{ } - - -//full constructor -CPlaneStress :: CPlaneStress( int tag, - double E_i, - double ni_i, - double f01d_i, - double f02d_i, - double f0p_i, - double beta_i, - double An_i, - double Bn_i, - double Ap_i, - double gammaC_i, - double dchemn_i, - double dchemp_i, // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - int def_i, - double dpMax_i, - double dnMax_i, - bool srfCompr_i, // 11/03/2013 Diego Talledo: Apply SRF also to compression. - bool isDchemVar_i, // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - double eps_u_i // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - ): -Concrete( tag, ND_TAG_CPlaneStress, - E_i,ni_i,f01d_i,f02d_i,f0p_i,beta_i,An_i,Bn_i,Ap_i,gammaC_i,dchemn_i,dchemp_i,def_i,dpMax_i,dnMax_i,srfCompr_i, isDchemVar_i, eps_u_i) //Talledo: da sistemare lo 0 -{ - -} - -//elastic constructor -CPlaneStress :: -CPlaneStress( int tag, - double E_i, - double ni_i ) : -Concrete( tag, ND_TAG_CPlaneStress, E_i, ni_i ) -{ - -} - -//destructor -CPlaneStress :: ~CPlaneStress( ) -{ - -} - -//make a clone of this material -NDMaterial* CPlaneStress :: getCopy( ) -{ - CPlaneStress *clone; - clone = new CPlaneStress() ; //new instance of this class - *clone = *this ; //asignment to make copy - return clone ; -} - -//send back type of material -const char* CPlaneStress :: getType( ) const -{ - return "PlaneStress" ; -} - - -//send back order of strain in vector form -int CPlaneStress :: getOrder( ) const -{ - return 3 ; -} - -//get the strain and integrate plasticity equations -int CPlaneStress :: setTrialStrain( const Vector &strain_from_element) -{ - const double tolerance = 1e-12 ; - - const int max_iterations = 25 ; - int iteration_counter = 0 ; - - int i, j, k, l ; - int ii, jj ; - - double eps22 = strain(2,2) ; - strain.Zero( ) ; - - strain(0,0) = strain_from_element(0) ; - strain(1,1) = strain_from_element(1) ; - strain(0,1) = 0.50 * strain_from_element(2) ; // eps_12 = 0.5 * gamma_12 - strain(1,0) = strain(0,1) ; - - strain(2,2) = eps22 ; - - //enforce the plane stress condition sigma_22 = 0 - //solve for epsilon_22 - iteration_counter = 0 ; - do { - - this->plastic_integrator( ) ; - - strain(2,2) -= stress(2,2) / tangent[2][2][2][2] ; - - iteration_counter++ ; - if ( iteration_counter > max_iterations ) { - /*opserr << "More than " << max_iterations ; - opserr << " iterations in setTrialStrain of CPlaneStress \n"; */ - break ; - }// end if - - } while ( fabs(stress(2,2)) > tolerance ) ; - - //modify tangent for plane stress - for ( ii = 0; ii < 3; ii++ ) { - for ( jj = 0; jj < 3; jj++ ) { - - index_map( ii, i, j ) ; - index_map( jj, k, l ) ; - - tangent[i][j][k][l] -= tangent[i][j][2][2] - * tangent[2][2][k][l] - / tangent[2][2][2][2] ; - - //minor symmetries - tangent [j][i][k][l] = tangent[i][j][k][l] ; - tangent [i][j][l][k] = tangent[i][j][k][l] ; - tangent [j][i][l][k] = tangent[i][j][k][l] ; - - } // end for jj - } // end for ii - return 0 ; -} - -//unused trial strain functions -int CPlaneStress :: setTrialStrain( const Vector &v, const Vector &r ) -{ - return this->setTrialStrain( v ) ; -} - -int CPlaneStress :: setTrialStrainIncr( const Vector &v ) -{ - static Vector newStrain(3); - newStrain(0) = strain(0,0) + v(0); - newStrain(1) = strain(1,1) + v(1); - newStrain(2) = 2.0 * strain(0,1) + v(2); - - return this->setTrialStrain(newStrain); -} - -int CPlaneStress :: setTrialStrainIncr( const Vector &v, const Vector &r ) -{ - return this->setTrialStrainIncr(v); -} - -//send back the strain -const Vector& CPlaneStress :: getStrain( ) -{ - strain_vec(0) = strain(0,0) ; - strain_vec(1) = strain(1,1) ; - strain_vec(2) = 2.0 * strain(0,1) ; - - return strain_vec ; -} - -//send back the stress -const Vector& CPlaneStress :: getStress( ) -{ - stress_vec(0) = stress(0,0) ; - stress_vec(1) = stress(1,1) ; - stress_vec(2) = stress(0,1) ; - - return stress_vec ; -} - -//send back the tangent -const Matrix& CPlaneStress :: getTangent( ) -{ - // matrix to tensor mapping - // Matrix Tensor - // ------- ------- - // 0 0 0 - // 1 1 1 - // 2 0 1 ( or 1 0 ) - // - - tangent_matrix(0,0) = tangent [0][0] [0][0] ; - tangent_matrix(1,1) = tangent [1][1] [1][1] ; - tangent_matrix(2,2) = tangent [0][1] [0][1] ; - - tangent_matrix(0,1) = tangent [0][0] [1][1] ; - tangent_matrix(1,0) = tangent [1][1] [0][0] ; - - tangent_matrix(0,2) = tangent [0][0] [0][1] ; - tangent_matrix(2,0) = tangent [0][1] [0][0] ; - - tangent_matrix(1,2) = tangent [1][1] [0][1] ; - tangent_matrix(2,1) = tangent [0][1] [1][1] ; - - return tangent_matrix ; -} - -//send back the tangent -const Matrix& CPlaneStress :: getInitialTangent( ) -{ - // matrix to tensor mapping - // Matrix Tensor - // ------- ------- - // 0 0 0 - // 1 1 1 - // 2 0 1 ( or 1 0 ) - // - - /* // modifica del 26/11/2012 - this->doInitialTangent(); - - tangent_matrix(0,0) = initialTangent [0][0] [0][0] ; - tangent_matrix(1,1) = initialTangent [1][1] [1][1] ; - tangent_matrix(2,2) = initialTangent [0][1] [0][1] ; - - tangent_matrix(0,1) = initialTangent [0][0] [1][1] ; - tangent_matrix(1,0) = initialTangent [1][1] [0][0] ; - - tangent_matrix(0,2) = initialTangent [0][0] [0][1] ; - tangent_matrix(2,0) = initialTangent [0][1] [0][0] ; - - tangent_matrix(1,2) = initialTangent [1][1] [0][1] ; - tangent_matrix(2,1) = initialTangent [0][1] [1][1] ; - */ - tangent_matrix(0,0) = tangent [0][0] [0][0] ; - tangent_matrix(1,1) = tangent [1][1] [1][1] ; - tangent_matrix(2,2) = tangent [0][1] [0][1] ; - - tangent_matrix(0,1) = tangent [0][0] [1][1] ; - tangent_matrix(1,0) = tangent [1][1] [0][0] ; - - tangent_matrix(0,2) = tangent [0][0] [0][1] ; - tangent_matrix(2,0) = tangent [0][1] [0][0] ; - - tangent_matrix(1,2) = tangent [1][1] [0][1] ; - tangent_matrix(2,1) = tangent [0][1] [1][1] ; - - return tangent_matrix ; -} - - - -int -CPlaneStress::commitState( ) -{ - commitEps22 = strain(2,2); - epsilon_p_n = epsilon_p_nplus1 ; - rnp=rnp1p; - rnn=rnp1n; - - strain_n = strain; - stress_n = stress; - - return 0; -} - -int -CPlaneStress::revertToLastCommit( ) { - strain(2,2) = commitEps22; - - return 0; -} - - -int -CPlaneStress::revertToStart( ) -{ - - commitEps22 = 0.0; - - this->zero( ) ; - - return 0; -} - -int -CPlaneStress::sendSelf (int commitTag, Channel &theChannel) -{ - // we place all the data needed to define material and it's state - // int a vector object - static Vector data(14); - int cnt = 0; - data(cnt++) = this->getTag(); - data(cnt++) = E ; - data(cnt++) = ni ; - data(cnt++) = f01d ; - data(cnt++) = f02d ; - data(cnt++) = f0p ; - data(cnt++) = beta ; - data(cnt++) = An ; - data(cnt++) = Bn ; - data(cnt++) = Ap ; - data(cnt++) = rnn ; - data(cnt++) = rnp ; - data(cnt++) = rnp1n; - data(cnt++) = rnp1p; - - - // send the vector object to the channel - if (theChannel.sendVector(this->getDbTag(), commitTag, data) < 0) { - opserr << "CPlaneStress::sendSelf - failed to send vector to channel\n"; - return -1; - } - return 0; -} - -int -CPlaneStress::recvSelf (int commitTag, Channel &theChannel, - FEM_ObjectBroker &theBroker) -{ - - // recv the vector object from the channel which defines material param and state - static Vector data(14); - if (theChannel.recvVector(this->getDbTag(), commitTag, data) < 0) { - opserr << "CPlaneStress::recvSelf - failed to recv vector from channel\n"; - return -1; - } - - // set the material parameters and state variables - int cnt = 0; - this->setTag(data(cnt++)); - E = data(cnt++); - ni = data(cnt++); - f01d = data(cnt++); - f02d = data(cnt++); - f0p = data(cnt++); - beta = data(cnt++); - An = data(cnt++); - Bn = data(cnt++); - Ap = data(cnt++); - rnn = data(cnt++); - rnp = data(cnt++); - rnp1n= data(cnt++); - rnp1p= data(cnt++); - //rnp1n=rnn; - //rnp1p=rnp; - epsilon_p_nplus1 = epsilon_p_n; - - return 0; -} - -//matrix_index ---> tensor indices i,j -// plane stress different because of condensation on tangent -// case 3 switched to 1-2 and case 4 to 3-3 -void -CPlaneStress :: index_map( int matrix_index, int &i, int &j ) -{ - switch ( matrix_index+1 ) { //add 1 for standard tensor indices - - case 1 : - i = 1 ; - j = 1 ; - break ; - - case 2 : - i = 2 ; - j = 2 ; - break ; - - case 3 : - i = 1 ; - j = 2 ; - break ; - - case 4 : - i = 3 ; - j = 3 ; - break ; - - case 5 : - i = 2 ; - j = 3 ; - break ; - - case 6 : - i = 3 ; - j = 1 ; - break ; - - default : - i = 1 ; - j = 1 ; - break ; - - } //end switch - - i-- ; //subtract 1 for C-indexing - j-- ; - - return ; -} - - - - - - - diff --git a/SRC/material/nD/CPlaneStress2d.cpp b/SRC/material/nD/CPlaneStress2d.cpp deleted file mode 100644 index 7c92f35f34..0000000000 --- a/SRC/material/nD/CPlaneStress2d.cpp +++ /dev/null @@ -1,890 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** ****************************************************************** */ - -// $Revision: 1.7 $ -// $Date: 2008/10/20 22:23:03 $ -// Written: Tesser, Talledo - -// Send strains in following format : -// -// strain_vec = { eps_00 -// eps_11 -// 2 eps_01 } <--- note the 2 - -#include -#include -#include - -//static vectors and matrices -Vector CPlaneStress2d :: strain_vec(3) ; -Vector CPlaneStress2d :: stress_vec(3) ; -Matrix CPlaneStress2d :: tangent_matrix(3,3) ; -Matrix CPlaneStress2d :: InitialStiffness2d(3,3); - -void CPlaneStress2d :: zero ( ) -{ - rnp = r0p; - rnn = r0n; - rnp1p = rnp; - rnp1n = rnn; - pStrain2d_n.Zero(); - pStrain2d_n1.Zero(); -} - -//null constructor -CPlaneStress2d :: CPlaneStress2d( ) : -Concrete( ), -stress2d(3), -strain2d(3), -pStrain2d_n(3), -pStrain2d_n1(3), -Stiffness2d(3,3) -{ - E = 0.0; - ni = 0.0; - f01d = 0.0; - f02d = 0.0; - f0p = 0.0; - beta = 0.0; - An = 0.0; - Bn = 0.0; - Ap = 0.0; - - lambda = 0.0; - shear_p = 0.0; - bulk_p = 0.0; - k_p = 0.0; - r0n = 0.0; - r0p = 0.0; - - dn = 0.0; - dp = 0.0; - //dn2 = 0.0; - //dp2 = 0.0; - rnn = r0n; - rnp1n= rnn; - rnp = r0p; - rnp1p= rnp; - //rnn2 = r0n; - //rnp2 = r0p; - - this->zero( ); - plastic_damage2D( ); -} - - -//full constructor -CPlaneStress2d :: -CPlaneStress2d(int tag,double E_i,double ni_i,double f01d_i,double f02d_i, - double f0p_i,double beta_i,double An_i,double Bn_i,double Ap_i, - double gammaC_i, double dchem_i, double dchemp_i, int def_i, double dpMax_i, double dnMax_i, bool srfCompr_i,bool isDchemVar_i,double eps_u_i) : -Concrete(tag, ND_TAG_CPlaneStress2d,E_i,ni_i,f01d_i,f02d_i,f0p_i,beta_i,An_i,Bn_i,Ap_i,gammaC_i,dchem_i,dchemp_i,def_i,dpMax_i,dnMax_i,srfCompr_i,isDchemVar_i,eps_u_i), -stress2d(3), -strain2d(3), -pStrain2d_n(3), -pStrain2d_n1(3), -Stiffness2d(3,3) -{ - E = E_i; - ni = ni_i; - f01d = f01d_i; - f02d = f02d_i; - f0p = f0p_i; - beta = beta_i; - An = An_i; - Bn = Bn_i; - Ap = Ap_i; - - lambda = E*ni/((1+ni)*(1-2*ni)); - shear_p = E/(2*(1+ni)); - bulk_p = lambda+2/3.0*shear_p; - k_p = sqrt(2.0)*(f02d-f01d)/(2*f02d-f01d); - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - if (usedEquivalentTensionDefinition == ORIGINAL) - { - r0n = sqrt(sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3); - r0p = sqrt(f0p/sqrt(E)); - } - else if (usedEquivalentTensionDefinition == HOMOGENEOUS) - { - r0n = sqrt(sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3); - r0p = sqrt(f0p); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - r0n = sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3; - r0p = f0p; - } - - dn = 0.0; - dp = 0.0; - rnn = r0n; - rnp1n = rnn; - rnp = r0p; - rnp1p = rnp; - - this->zero( ); - plastic_damage2D( ); - this->doInitialStiffness(); -} - - -//elastic constructor -CPlaneStress2d :: -CPlaneStress2d(int tag,double E_i,double ni_i ) : -Concrete(tag, ND_TAG_CPlaneStress2d,E_i,ni_i), -stress2d(3), -strain2d(3), -pStrain2d_n(3), -pStrain2d_n1(3), -Stiffness2d(3,3) -{ - E = E_i; - ni = ni_i; - f01d = -1.0e16*E; - f02d = -1.0e16*E; - f0p = 1.0e16*E; - beta = 0.0; - An = 1.0; - Bn = 1.0; - Ap = 1.0; - - lambda = E*ni/((1+ni)*(1-2*ni)); - shear_p = E/(2*(1+ni)); - bulk_p = lambda+2*shear_p/3; - k_p = 0.0; - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - if (usedEquivalentTensionDefinition == ORIGINAL) - { - r0n = sqrt(sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3); - r0p = sqrt(f0p/sqrt(E)); - } - else if (usedEquivalentTensionDefinition == HOMOGENEOUS) - { - r0n = sqrt(sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3); - r0p = sqrt(f0p); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - r0n = sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3; - r0p = f0p; - } - - dn = 0.0; - dp = 0.0; - rnn = r0n; - rnp1n=rnn; - rnp = r0p; - rnp1p=rnp; - - //dn2 = 0.0; - //dp2 = 0.0; - //rnn2 = r0n; - //rnp2 = r0p; -} - - - -//destructor -CPlaneStress2d :: ~CPlaneStress2d( ) -{ - -} - - -//make a clone of this material -NDMaterial* CPlaneStress2d :: getCopy( ) -{ - CPlaneStress2d *clone; - clone = new CPlaneStress2d() ; //new instance of this class - *clone = *this ; //asignment to make copy - return clone ; -} - - - -//send back type of material -const char* CPlaneStress2d :: getType( ) const -{ - return "PlaneStress2d" ; -} - - -//send back order of strain in vector form -int CPlaneStress2d :: getOrder( ) const -{ - return 3 ; -} - - -int CPlaneStress2d :: setTrialStrain( const Vector &strain_from_element) -{ - strain2d.Zero(); - strain2d = strain_from_element; - this -> plastic_damage2D(); - return 0 ; -} - - -//unused trial strain functions -int CPlaneStress2d :: setTrialStrain( const Vector &v, const Vector &r ) -{ - return this->setTrialStrain( v ) ; -} - -int CPlaneStress2d :: setTrialStrainIncr( const Vector &v ) -{ - static Vector newStrain(3); - newStrain(0) = strain(0,0) + v(0); - newStrain(1) = strain(1,1) + v(1); - newStrain(2) = strain(0,1) + v(2); - - return this->setTrialStrain(newStrain); -} - -int CPlaneStress2d :: setTrialStrainIncr( const Vector &v, const Vector &r ) -{ - return this->setTrialStrainIncr(v); -} - - -//send back the strain -const Vector& CPlaneStress2d :: getStrain( ) -{ - strain_vec(0) = strain2d(0) ; - strain_vec(1) = strain2d(1) ; - strain_vec(2) = strain2d(2) ; - - return strain_vec ; -} - - -//send back the stress -const Vector& CPlaneStress2d :: getStress( ) -{ - stress_vec(0) = stress2d(0) ; - stress_vec(1) = stress2d(1) ; - stress_vec(2) = stress2d(2) ; - return stress_vec ; -} - -//send back the tangent -const Matrix& CPlaneStress2d :: getTangent( ) -{ - tangent_matrix = Stiffness2d; - return tangent_matrix ; -} - - -//send back the tangent -const Matrix& CPlaneStress2d :: getInitialTangent( ) -{ - this->doInitialStiffness(); - - tangent_matrix = InitialStiffness2d; - - return tangent_matrix ; -} - -int -CPlaneStress2d :: commitState( ) -{ - rnp = rnp1p; - rnn = rnp1n; - pStrain2d_n = pStrain2d_n1; - - return 0; -} - -int -CPlaneStress2d :: revertToLastCommit( ) -{ - return 0; -} - - -int -CPlaneStress2d :: revertToStart( ) -{ - this->zero( ) ; - return 0; -} - -int -CPlaneStress2d :: sendSelf (int commitTag, Channel &theChannel) -{ - // we place all the data needed to define material and it's state - // int a vector object - static Vector data(15); - int cnt = 0; - data(cnt++) = this->getTag(); - data(cnt++) = E ; - data(cnt++) = ni ; - data(cnt++) = f01d ; - data(cnt++) = f02d ; - data(cnt++) = f0p ; - data(cnt++) = beta ; - data(cnt++) = An ; - data(cnt++) = Bn ; - data(cnt++) = Ap ; - data(cnt++) = rnn ; - data(cnt++) = rnp ; - for (int i=0; i<3; i++) - data(cnt++) = pStrain2d_n(i); - - // send the vector object to the channel - if (theChannel.sendVector(this->getDbTag(), commitTag, data) < 0) { - opserr << "CPlaneStress2d::sendSelf - failed to send vector to channel\n"; - return -1; - } - return 0; -} - -int -CPlaneStress2d :: recvSelf (int commitTag, Channel &theChannel,FEM_ObjectBroker &theBroker) -{ - - // recv the vector object from the channel which defines material param and state - static Vector data(15); - if (theChannel.recvVector(this->getDbTag(), commitTag, data) < 0) { - opserr << "CPlaneStress2d::recvSelf - failed to recv vector from channel\n"; - return -1; - } - - // set the material parameters and state variables - int cnt = 0; - this->setTag(data(cnt++)); - E = data(cnt++); - ni = data(cnt++); - f01d = data(cnt++); - f02d = data(cnt++); - f0p = data(cnt++); - beta = data(cnt++); - An = data(cnt++); - Bn = data(cnt++); - Ap = data(cnt++); - rnn = data(cnt++); - rnp = data(cnt++); - for (int i=0; i<3; i++) - pStrain2d_n(i) = data(cnt++); - rnp1n=rnn; - rnp1p=rnp; - - return 0; -} - -void CPlaneStress2d :: plastic_damage2D( ) -{ - const double tolerance = (1.0e-14)*f0p ; - int i,j,k; - Vector senp1t(3); - Matrix Stress2d(2,2); - double V[2][2]; - double dg[2],dgn[2],dgp[2]; - double sigoct,tauoct,taun,taup; - double alfa,norms,pint,lambdap; - double st[3],dea[3],ls[3],ses[3],dep[3]; - double supp1[2][2],supp2[2][2],trans[3]; - double g, rhoQ, rhoP, alfasp, alfasn, rhoL, thetaL; - - for (i=0;i<3;i++) - dep[i]=0.0; - - this->doInitialStiffness(); - senp1t = strain2d - pStrain2d_n; - senp1t = InitialStiffness2d*senp1t; - - if (beta>0.0) - { - solve_eig(senp1t(0),senp1t(2),senp1t(2),senp1t(1),V,dg); - for (i=0;i<2;i++) - dgn[i]=(dg[i]-fabs(dg[i]))/2.0; - sigoct=(dgn[0]+dgn[1])/3; - tauoct=sqrt((dgn[0]-dgn[1])*(dgn[0]-dgn[1])+dgn[0]*dgn[0]+dgn[1]*dgn[1])/3; - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - if ((usedEquivalentTensionDefinition == ORIGINAL) || (usedEquivalentTensionDefinition == HOMOGENEOUS)) - { - taun=sqrt(3.0)*(k_p*sigoct+tauoct); - if (taun >= 0) - taun = sqrt(taun); - else - taun = 0; - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - taun=sqrt(3.0)*(k_p*sigoct+tauoct); - } - - for (i=0;i<2;i++) - dgp[i]=(dg[i]+fabs(dg[i]))/2.0; - taup = ((dgp[0]*dgp[0]+dgp[1]*dgp[1]))/E-2*dgp[0]*dgp[1]*ni/E; - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - if (usedEquivalentTensionDefinition == ORIGINAL) - { - taup=sqrt(sqrt(taup)); - } - else if (usedEquivalentTensionDefinition == HOMOGENEOUS) - { - taup = sqrt(sqrt(taup*E)); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - taup=sqrt(taup*E); - } - - g=((taup/rnp)*(taup/rnp))+((taun/rnn)*(taun/rnn))-1; - if (g>tolerance) - { - rhoQ = sqrt(taup*taup+taun*taun); - rhoP = rnp*rnn*sqrt((taun*taun+taup*taup)/((taun*rnp)*(taun*rnp)+(taup*rnn)*(taup*rnn))); - if (rnn >= rnp) - { - if (rhoPrnn) - rhoP = rnn; - } - else if (rnn < rnp) - { - if (rhoP>rnp) - rhoP =rnp; - if (rhoP0) - { - lambdap=1-beta*E*pint/norms; - for (i=0;i<3;i++) - ses[i]=senp1t[i]*lambdap; - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - if ((usedEquivalentTensionDefinition == ORIGINAL) || (usedEquivalentTensionDefinition == HOMOGENEOUS)) - { - taun*=sqrt(lambdap); - taup*=sqrt(lambdap); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - taun*=lambdap; - taup*=lambdap; - } - g=(taup/rnp)*(taup/rnp)+(taun/rnn)*(taun/rnn)-1; - if (g>tolerance) - { - for (i=0;i<3;i++) - senp1t[i]=ses[i]; - trans[0] = (1/E)*ls[0]-(ni/E)*ls[1]; - trans[1] = (1/E)*ls[1]-(ni/E)*ls[0]; - trans[2] = (1/shear_p)*ls[2]; - for (i=0;i<3;i++) - { - dep[i]=beta*E*pint*trans[i]; - pStrain2d_n1(i)=pStrain2d_n(i)+dep[i]; - }; - } - else - pStrain2d_n1 = pStrain2d_n; - } - else - pStrain2d_n1 = pStrain2d_n; - } - else - pStrain2d_n1 = pStrain2d_n; - }; - solve_eig(senp1t(0),senp1t(2),senp1t(2),senp1t(1),V,dg); - for (i=0;i<2;i++) - dgn[i]=(dg[i]-fabs(dg[i]))/2; - sigoct=(dgn[0]+dgn[1])/3; - tauoct=sqrt((dgn[0]-dgn[1])*(dgn[0]-dgn[1])+dgn[0]*dgn[0]+dgn[1]*dgn[1])/3; - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - if ((usedEquivalentTensionDefinition == ORIGINAL) || (usedEquivalentTensionDefinition == HOMOGENEOUS)) - { - taun=sqrt(3.0)*(k_p*sigoct+tauoct); - if (taun >= 0) - taun = sqrt(taun); - else - taun = 0; - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - taun=sqrt(3.0)*(k_p*sigoct+tauoct); - } - for (i=0;i<2;i++) - dgp[i]=(dg[i]+fabs(dg[i]))/2; - taup = ((dgp[0]*dgp[0]+dgp[1]*dgp[1]))/E-2*dgp[0]*dgp[1]*ni/E; - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - if (usedEquivalentTensionDefinition == ORIGINAL) - { - taup=sqrt(sqrt(taup)); - } - else if (usedEquivalentTensionDefinition == HOMOGENEOUS) - { - taup = sqrt(sqrt(taup*E)); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - taup=sqrt(taup*E); - } - g=(taup/rnp)*(taup/rnp)+(taun/rnn)*(taun/rnn)-1; - if (g>tolerance) - { - rhoQ = sqrt(taup*taup+taun*taun); - rhoP = rnp*rnn*sqrt((taun*taun+taup*taup)/((taun*rnp)*(taun*rnp)+(taup*rnn)*(taup*rnn))); - if (rnn >= rnp) - { - if (rhoPrnn) - rhoP = rnn; - } - else if (rnn < rnp) - { - if (rhoP>rnp) - rhoP =rnp; - if (rhoPrhoL) && (rhoP<=rnn)) || ((rhoP>=rnn) && (rhoP=1.0) - // dn=1.0;*/ - //if (dn>=dnMax) - // dn = dnMax; - //if (dn<0.0) - // dn=0.0; - //if (rnp1p=1.0) - // dp=1.0;*/ - //// 11/01/2013 Diego Talledo: Added Negative Damage Limit - //if (dp>=dpMax) - // dp = dpMax; - //if (dp <0) - // dp=0.0; - } else - { - rnp1n=rnn; - rnp1p=rnp; - //if (rnp1n=1.0) - // dn=1.0;*/ - //if (dn>=dnMax) - // dn = dnMax; - //if (dn<0.0) - // dn=0.0; - //if (rnp1p=1.0) - // dp=1.0;*/ - //// 11/01/2013 Diego Talledo: Added Negative Damage Limit - //if (dp>=dpMax) - // dp = dpMax; - //if (dp <0) - // dp=0.0; - }; - - if (rnp1n=1.0) - dn=1.0;*/ - if (dn>=dnMax) - dn = dnMax; - if (dn<0.0) - dn=0.0; - if (rnp1p=1.0) - dp=1.0;*/ - // 11/01/2013 Diego Talledo: Added Negative Damage Limit - if (dp>=dpMax) - dp = dpMax; - if (dp <0) - dp=0.0; - - // 13/01/2013 Diego Talledo: Added Shear Retention Factor - if (gammaC <= 0.0) { - SRF12 = 0.0; - } - else { - SRF12 = 1-abs(strain2d(2))/(2*gammaC); //gammaC = epsilonREF_1,2 - if (SRF12 <= 0.0) { - SRF12 = 0.0; - } - } - - for (i=0;i<2;i++) - for (j=0;j<2;j++) - { - supp1[i][j]=0.0; - supp2[i][j]=0.0; - supp1[i][j]=supp1[i][j]+V[i][j]*dgn[j]; - supp2[i][j]=supp2[i][j]+V[i][j]*dgp[j]; - }; - for (i=0;i<2;i++) - for (j=0;j<2;j++) - { - Dn[i][j]=0.0; - Dp[i][j]=0.0; - for (k=0;k<2;k++) - { - Dn[i][j]=Dn[i][j]+supp1[i][k]*V[j][k]; - Dp[i][j]=Dp[i][j]+supp2[i][k]*V[j][k]; - }; - }; - - // 11/03/2013 Diego Talledo: Added Environmental Chemical Damage - // Compute dnstar and dpstar - dnstar = dn + dchemn - (dchemn * dn); - //dpstar = dp + dchem - (dchem * dp); - dpstar = dp + dchemp - (dchemp * dp); - - // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - // dchem variabile: retta tra dchemn e 1. Con 1 raggiunto per epsilon pari a eps_u - if (isDchemVariableSelected) { - double dchem_var = (1-dchemn)/tau_n_eps_u*rnp1n+dchemn; - dnstar = dn + dchem_var - (dchem_var * dn); - } - // Fine prova dchem variabile - - //compute Cauchy stress - Stress2d.Zero(); - for (i=0;i<2;i++) - for (j=0;j<2;j++) - { - - //Stress2d(i,j)=(1-dn)*Dn[i][j]+(1-dp)*Dp[i][j]; - // 11/03/2013 Diego Talledo: Added Environmental Chemical Damage - Stress2d(i,j)=(1-dnstar)*Dn[i][j]+(1-dpstar)*Dp[i][j]; - // 13/01/2013 Diego Talledo: Added Shear Retention Factor - if (((i==0) && (j==1)) || ((i==1) && (j==0))) - if (!srfCompr) // 11/03/2013 Diego Talledo: Apply SRF also to compression. - Stress2d(i,j)=(1-dnstar)*Dn[i][j]+(1-(1-SRF12)*dpstar)*Dp[i][j]; - else - Stress2d(i,j)=(1-(1-SRF12)*dnstar)*Dn[i][j]+(1-(1-SRF12)*dpstar)*Dp[i][j]; - } - stress2d(0) = Stress2d(0,0); - stress2d(1) = Stress2d(1,1); - stress2d(2) = Stress2d(0,1); - //compute stiffness matrix - if (dn > 0.0 && dn < 0.99999) - Stiffness2d = (1-dn) * InitialStiffness2d; - else - Stiffness2d = InitialStiffness2d; - return ; -} - -void CPlaneStress2d :: doInitialStiffness( ) -{ - InitialStiffness2d.Zero(); - InitialStiffness2d(0,0) = E/(1-(ni*ni)); - InitialStiffness2d(1,1) = InitialStiffness2d(0,0); - InitialStiffness2d(2,2) = shear_p; - InitialStiffness2d(0,1) = E*ni/(1-(ni*ni)); - InitialStiffness2d(1,0) = InitialStiffness2d(0,1); - return ; -} - -void CPlaneStress2d :: solve_eig(double A, double B, double C, double D, double V[2][2], double d[2] ) -{ - double tolerance = 0.1e-20; - double lambda1 = 0.0; - double lambda2 = 0.0; - double v1x = 0.0; - double v1y = 0.0; - double v2x = 0.0; - double v2y = 0.0; - - if(B*C <= tolerance ) - { - lambda1 = A; v1x = 1; v1y = 0; - lambda2 = D; v2x = 0; v2y = 1; - d[0] = lambda1; - d[1] = lambda2; - V[0][0] = v1x; - V[1][0] = v1y; - V[0][1] = v2x; - V[1][1] = v2y; - return; - } - double tr = A + D; - double det = A * D - B * C; - double S = sqrt( (tr/2)*(tr/2) - det ); - lambda1 = tr/2 + S; - lambda2 = tr/2 - S; - double S2 = ((A-D)/2)*((A-D)/2) + B * C; - double SS = 0.0; - if (S2 > 0.0) - SS = sqrt(S2); - if( A - D < 0 ) { - v1x = C; - v1y = - (A-D)/2 + SS; - v2x = + (A-D)/2 - SS; - v2y = B; - } else { - v2x = C; - v2y = - (A-D)/2 - SS; - v1x = + (A-D)/2 + SS; - v1y = B; - } - double n1 = sqrt(v1x*v1x+v1y*v1y); - v1x /= n1; - v1y /= n1; - double n2 = sqrt(v2x*v2x+v2y*v2y); - v2x /= n2; - v2y /= n2; - - d[0] = lambda1; - d[1] = lambda2; - - V[0][0] = v1x; - V[1][0] = v1y; - V[0][1] = v2x; - V[1][1] = v2y; -} - -// Diego Gennaio 2015 : Per implementazione Danno Globale -const Vector & CPlaneStress2d::getElasticFreeEnergy() -{ - static Vector tmp(2); // Psi0- Psi0+ - - // Variabili temporanee - Sigma Elastica + Decomposizione Spettrale - Vector sigmaElastic(3); - double V[2][2]; - double dg[2],dgn[2],dgp[2]; - double supp1[2][2],supp2[2][2],trans[3]; - - this->doInitialStiffness(); - sigmaElastic = strain2d - pStrain2d_n; - sigmaElastic = InitialStiffness2d*sigmaElastic; - - solve_eig(sigmaElastic(0),sigmaElastic(2),sigmaElastic(2),sigmaElastic(1),V,dg); - for (int i=0; i<2; i++) - dgn[i]=(dg[i]-fabs(dg[i]))/2.0; - // Calcolare DGP XXX - for (int i=0;i<2;i++) - dgp[i]=(dg[i]+fabs(dg[i]))/2.0; - - // Bring it to the reference system - for (int i=0; i<2; i++) - for (int j=0; j<2; j++) - { - supp1[i][j]=0.0; - supp2[i][j]=0.0; - supp1[i][j]=supp1[i][j]+V[i][j]*dgn[j]; - supp2[i][j]=supp2[i][j]+V[i][j]*dgp[j]; - }; - for (int i=0; i<2; i++) - for (int j=0; j<2; j++) - { - Dn[i][j]=0.0; - Dp[i][j]=0.0; - for (int k=0; k<2; k++) - { - Dn[i][j]=Dn[i][j]+supp1[i][k]*V[j][k]; - Dp[i][j]=Dp[i][j]+supp2[i][k]*V[j][k]; - }; - }; - - // Psi0- - tmp(0) = 0.5*(Dn[0][0]*(strain2d(0)-pStrain2d_n(0)) + Dn[1][1]*(strain2d(1)-pStrain2d_n(1)) + Dn[0][1]*(strain2d(2)-pStrain2d_n(2))); - // Psi9+ - tmp(1) = 0.5*(Dp[0][0]*(strain2d(0)-pStrain2d_n(0)) + Dp[1][1]*(strain2d(1)-pStrain2d_n(1)) + Dp[0][1]*(strain2d(2)-pStrain2d_n(2))); - - return tmp; -} - -const Vector & CPlaneStress2d::getDamagedFreeEnergy() -{ - static Vector tmp(2); - const Vector &ElFreeEnergy = this->getElasticFreeEnergy(); - - tmp(0) = ElFreeEnergy(0) * (1-this->dnstar); - tmp(1) = ElFreeEnergy(1) * (1-this->dpstar); - - return tmp; -} - - - diff --git a/SRC/material/nD/CThreeDimensional.cpp b/SRC/material/nD/CThreeDimensional.cpp deleted file mode 100644 index a814772501..0000000000 --- a/SRC/material/nD/CThreeDimensional.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** ****************************************************************** */ - -// $Revision: 1.6 $ -// $Date: 2005/03/25 00:34:40 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/CThreeDimensional.cpp,v $ - -// -// Send strains in following format : -// -// strain_vec = { eps_00 -// eps_11 -// eps_22 - -// 2 eps_01 -// 2 eps_12 -// 2 eps_20 } <--- note the 2 -// - -#include -#include -#include - -//static vectors and matrices -Vector CThreeDimensional :: strain_vec(6) ; -Vector CThreeDimensional :: stress_vec(6) ; -Matrix CThreeDimensional :: tangent_matrix(6,6) ; - -//null constructor -CThreeDimensional :: CThreeDimensional( ) : -Concrete( ) -{ } - -//full constructor -CThreeDimensional :: -CThreeDimensional( int tag, - double E_i, - double ni_i, - double f01d_i, - double f02d_i, - double f0p_i, - double beta_i, - double An_i, - double Bn_i, - double Ap_i, - double gammaC_i, // 14/12/2011 Diego Talledo: Added Shear Retention Factor - double dchem_i, // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - double dchemp_i, // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - int def_i, // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - double dpMax_i, // 11/01/2013 Diego Talledo: Added Positive Damage Limit - double dnMax_i, // 11/01/2013 Diego Talledo: Added Negative Damage Limit - bool srfCompr_i, // 11/03/2013 Diego Talledo: Apply SRF also to compression. - bool isDchemVar_i, // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - double eps_u_i // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - ): -Concrete( tag, ND_TAG_CThreeDimensional, - E_i,ni_i,f01d_i,f02d_i,f0p_i,beta_i,An_i,Bn_i,Ap_i,gammaC_i, dchem_i, dchemp_i, def_i, dpMax_i, dnMax_i, srfCompr_i, isDchemVar_i, eps_u_i ) -{ - -} - -//elastic constructor -CThreeDimensional :: -CThreeDimensional( int tag, - double E_i, - double ni_i ) : -Concrete( tag, ND_TAG_CThreeDimensional, E_i,ni_i ) -{ - -} - -//destructor -CThreeDimensional :: ~CThreeDimensional( ) -{ - -} - -//make a clone of this material -NDMaterial* CThreeDimensional :: getCopy( ) -{ - CThreeDimensional *clone; - clone = new CThreeDimensional( ) ; //new instance of this class - *clone = *this ; //asignment to make copy - return clone ; -} - - -//send back type of material -const char* CThreeDimensional :: getType( ) const -{ - return "ThreeDimensional" ; -} - - -//send back order of strain in vector form -int CThreeDimensional :: getOrder( ) const -{ - return 6 ; -} - - -//get the strain and integrate plasticity equations -int CThreeDimensional :: setTrialStrain( const Vector &strain_from_element) -{ - strain.Zero( ) ; - - strain(0,0) = strain_from_element(0) ; - strain(1,1) = strain_from_element(1) ; - strain(2,2) = strain_from_element(2) ; - - strain(0,1) = 0.50 * strain_from_element(3) ; - strain(1,0) = strain(0,1) ; - - strain(1,2) = 0.50 * strain_from_element(4) ; - strain(2,1) = strain(1,2) ; - - strain(2,0) = 0.50 * strain_from_element(5) ; - strain(0,2) = strain(2,0) ; - - this->plastic_integrator( ) ; - - return 0 ; -} - - -//unused trial strain functions -int CThreeDimensional :: setTrialStrain( const Vector &v, const Vector &r ) -{ - return this->setTrialStrain( v ) ; -} - -int CThreeDimensional :: setTrialStrainIncr( const Vector &v ) -{ - static Vector newStrain(6); - newStrain(0) = strain(0,0) + v(0); - newStrain(1) = strain(1,1) + v(1); - newStrain(2) = strain(2,2) + v(2); - newStrain(3) = 2.0*strain(0,1) + v(3); - newStrain(4) = 2.0*strain(1,2) + v(4); - newStrain(5) = 2.0*strain(2,0) + v(5); - - return this->setTrialStrain(newStrain); -} - -int CThreeDimensional :: setTrialStrainIncr( const Vector &v, const Vector &r ) -{ - return this->setTrialStrainIncr(v); -} - -//send back the strain -const Vector& CThreeDimensional :: getStrain( ) -{ - strain_vec(0) = strain(0,0) ; - strain_vec(1) = strain(1,1) ; - strain_vec(2) = strain(2,2) ; - - strain_vec(3) = 2.0 * strain(0,1) ; - - strain_vec(4) = 2.0 * strain(1,2) ; - - strain_vec(5) = 2.0 * strain(2,0) ; - - return strain_vec ; -} - -//send back the stress -const Vector& CThreeDimensional :: getStress( ) -{ - stress_vec(0) = stress(0,0) ; - stress_vec(1) = stress(1,1) ; - stress_vec(2) = stress(2,2) ; - - stress_vec(3) = stress(0,1) ; - - stress_vec(4) = stress(1,2) ; - - stress_vec(5) = stress(2,0) ; - - return stress_vec ; -} - -//send back the tangent -const Matrix& CThreeDimensional :: getTangent( ) -{ - // matrix to tensor mapping - // Matrix Tensor - // ------- ------- - // 0 0 0 - // 1 1 1 - // 2 2 2 - // 3 0 1 ( or 1 0 ) - // 4 1 2 ( or 2 1 ) - // 5 2 0 ( or 0 2 ) - - int ii, jj ; - int i, j, k, l ; - - for ( ii = 0; ii < 6; ii++ ) { - for ( jj = 0; jj < 6; jj++ ) { - - index_map( ii, i, j ) ; - index_map( jj, k, l ) ; - - tangent_matrix(ii,jj) = tangent[i][j][k][l] ; - - } //end for j - } //end for i - - return tangent_matrix ; -} - -//send back the tangent -const Matrix& CThreeDimensional :: getInitialTangent( ) -{ - // matrix to tensor mapping - // Matrix Tensor - // ------- ------- - // 0 0 0 - // 1 1 1 - // 2 2 2 - // 3 0 1 ( or 1 0 ) - // 4 1 2 ( or 2 1 ) - // 5 2 0 ( or 0 2 ) - - int ii, jj ; - int i, j, k, l ; - - this->doInitialTangent(); - - for ( ii = 0; ii < 6; ii++ ) { - for ( jj = 0; jj < 6; jj++ ) { - - index_map( ii, i, j ) ; - index_map( jj, k, l ) ; - - tangent_matrix(ii,jj) = initialTangent[i][j][k][l] ; - - } //end for j - } //end for i - - return tangent_matrix ; -} \ No newline at end of file diff --git a/SRC/material/nD/Concrete.cpp b/SRC/material/nD/Concrete.cpp deleted file mode 100644 index 5d47d5b9ed..0000000000 --- a/SRC/material/nD/Concrete.cpp +++ /dev/null @@ -1,1660 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** ****************************************************************** */ - -// $Revision: 1.20 $ -// $Date: 2012/06/06 12:38:59 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/Concrete.cpp,v $ -// Written: Tesser L., Talledo D.A. -// -/* ****************************************************************** ** -** ** -** Concrete: Implementation of Concrete class as Tesser et al. (2012) ** -** ** -** Two parameters damage model for isotropic material. ** -** Plasticity simplified as Faria et al. (1997) ** -** Environmental damage as Saetta et al. (1998) ** -** ** -** ****************************************************************** */ - -#include -#include -#include -#include -#include - -#include -#include - -//#include // Talledo - -#include // Tesser -#include // Talledo -using namespace std; -//using std::cerr; -//using std::ios; - -//parameters -const double Concrete :: one3 = 1.0 / 3.0 ; -const double Concrete :: two3 = 2.0 / 3.0 ; -const double Concrete :: four3 = 4.0 / 3.0 ; -const double Concrete :: root23 = sqrt( 2.0 / 3.0 ) ; - -double Concrete::initialTangent[3][3][3][3] ; //material tangent -double Concrete::IIdev[3][3][3][3] ; //rank 4 deviatoric -double Concrete::IbunII[3][3][3][3]; //rank 4 general -double Concrete::IbunI[3][3][3][3] ; //rank 4 I bun I - -#include -#define OPS_Export -#define PI 3.14159 - -static int numConcreteMaterials = 0; - -void * -OPS_NewConcreteMaterial(void) -{ - if (numConcreteMaterials == 0) { - numConcreteMaterials++; - opserr << "nDmaterial Concrete - Written by Leopoldo Tesser, Univ. Padua - Italy"; - opserr << "contact: leopoldo.tesser@dicea.unipd.it\n"; - //to be completed with reference - } - - // Pointer to a NDMaterial material that will be returned - NDMaterial *theMaterial = 0; - - int numArgs = OPS_GetNumRemainingInputArgs(); - - // Mandatory parameters - if (numArgs < 10) - { - opserr << "WARNING invalid number of input arguments for nDMaterial Concrete" << endln; - opserr << "Want: nDMaterial Concrete tag? E? ni? f01d? f02d? f0p? beta? An? Bn? Ap? <-srf gammaC?> <-dchem dchem?> <-eqTensDef def?> <-dpMax max?> <-dnMax max?>" << endln; - return 0; - } - - int tag = 0; - int numData = 1; - if (OPS_GetInt(&numData, &tag) != 0) { - opserr << "WARNING invalid material tag for nDMaterial Concrete" << endln; - return 0; - } - - double dData[9]; - numData = 9; - if (OPS_GetDouble(&numData, dData) != 0) { - opserr << "WARNING invalid material data for nDMaterial Concrete with tag: " << tag << endln; - return 0; - } - - char *Param = 0; - numData = 1; - - // Optional Parameteres - //default parameters - // 14/12/2011 Diego Talledo: Added Shear Retention Factor - double gammaC = -0.001; // (negative by default -> no influence) - // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - double dchemn = 0.0; // (zero by default -> no influence) - double dchemp = 0.0; // (zero by default -> no influence) - // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - bool dchemVariable = false; // by default dchem is constant - double eps_u = 0.0; // By default eps_u is not used - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - int def = 2; // // (2 by default -> COMPDYN definition) - // 11/01/2013 Diego Talledo: Added Negative and Positive Damage Limit - double dpMax = 0.99999; // (0.99999 by default ) - double dnMax = 0.99999; // (0.99999 by default -> as usal) - // 11/03/2013 Diego Talledo: Apply SRF also to compression. - bool srfCompr = false; // Apply only in tension by Default - - for (int ii = 1; ii < numArgs-9; ii++) { - const char *Param = OPS_GetString(); - if (strcmp(Param,"-srf") == 0 && ++ii < numArgs) { - if (OPS_GetDouble(&numData, &gammaC) != 0) { - opserr << "WARNING invalid eps_ref for nDMaterial Concrete material with tag: " << tag << endln; - return 0; - } - } else if ((strcmp(Param,"-dchem") == 0 || strcmp(Param,"-dchemn") == 0) && ++ii < numArgs) { - if (OPS_GetDouble(&numData, &dchemn) != 0) { - opserr << "WARNING invalid dchem for nDMaterial Concrete material with tag: " << tag << endln; - return 0; - } - else dchemp = dchemn; - } else if (strcmp(Param,"-dchemp") == 0 && ++ii < numArgs) { - if (OPS_GetDouble(&numData, &dchemp) != 0) { - opserr << "WARNING invalid dchemp for nDMaterial Concrete material with tag: " << tag << endln; - return 0; - } - } else if (strcmp(Param,"-dchemvar") == 0 && ++ii < numArgs) { // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - if (OPS_GetDouble(&numData, &eps_u) != 0) { - opserr << "WARNING invalid eps_u for nDMaterial Concrete material with tag: " << tag << endln; - return 0; - } else dchemVariable = true; - } else if (strcmp(Param,"-eqTensDef") == 0 && ++ii < numArgs) { - if (OPS_GetInt(&numData, &def) != 0) { - opserr << "WARNING invalid number for Eq Tens Definition for nDMaterial Concrete material with tag: " << tag << endln; - return 0; - } - } else if (strcmp(Param,"-dpMax") == 0 && ++ii < numArgs) { - if (OPS_GetDouble(&numData, &dpMax) != 0) { - opserr << "WARNING invalid dpMax for nDMaterial Concrete material with tag: " << tag << endln; - return 0; - } - } else if (strcmp(Param,"-dnMax") == 0 && ++ii < numArgs) { - if (OPS_GetDouble(&numData, &dnMax) != 0) { - opserr << "WARNING invalid dnMax for nDMaterial Concrete material with tag: " << tag << endln; - return 0; - } - } else if (strcmp(Param,"-srfCompr") == 0) { - srfCompr = true; - } - } - - theMaterial = new Concrete(tag,0,dData[0],dData[1],dData[2],dData[3],dData[4],dData[5],dData[6],dData[7],dData[8],gammaC,dchemn,dchemp,def,dpMax,dnMax,srfCompr,dchemVariable,eps_u); - - if (theMaterial == 0) { - opserr << "WARNING ran out of memory for nDMaterial Concrete with tag: " << tag << endln; - } - - return theMaterial; -} - -//zero internal variables -void Concrete :: zero ( ) -{ - epsilon_p_n.Zero( ) ; - epsilon_p_nplus1.Zero( ) ; - - stress.Zero(); - strain.Zero(); - - stress_n.Zero(); // Diego Talledo: a cosa servono stress_n e strain_n ? - strain_n.Zero(); -} - -//null constructor -Concrete :: Concrete( ) : -NDMaterial( ), -epsilon_p_n(3,3), -epsilon_p_nplus1(3,3), -stress(3,3), -strain(3,3), -stress_n(3,3), -strain_n(3,3) -{ - E = 0.0; - ni = 0.0; - f01d = 0.0; - f02d = 0.0; - f0p = 0.0; - beta = 0.0; - An = 0.0; - Bn = 0.0; - Ap = 0.0; - gammaC = 0.0; // 14/12/2011 Diego Talledo: Added Shear Retention Factor - - lambda = 0.0; - shear_p = 0.0; - bulk_p = 0.0; - k_p = 0.0; - r0n = 0.0; - r0p = 0.0; - - // 14/12/2011 Diego Talledo: Added Shear Retention Factor - SRF12 = 0.0; - SRF12 = 0.0; - SRF12 = 0.0; - - dn = 0.0; - dp = 0.0; - rnn = r0n; - rnp1n= rnn; - rnp = r0p; - rnp1p= rnp; - - // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - dchemn = 0.0; - dchemp = 0.0; - dpstar = 0.0; - dnstar = 0.0; - - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - usedEquivalentTensionDefinition = COMPDYN; // By default we use the COMPDYN implemented definition - - // 11/01/2013 Diego Talledo: Added Positive and Negative Damage Limit - dpMax = 0.99999; // Default value - dnMax = 0.99999; // Default value - - // 11/03/2013 Diego Talledo: Apply SRF also to compression. - srfCompr = false; // Default value - - this->zero( ) ; // or (*this).zero( ) - - int i, j, k, l ; - - //zero rank4 IIdev, IbunI and IbunII - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) { - for ( k = 0; k < 3; k++ ) { - for ( l = 0; l < 3; l++) { - IbunI[i][j][k][l] = 0.0 ; - IbunII[i][j][k][l] = 0.0; - IIdev[i][j][k][l] = 0.0 ; - } // end for l - } // end for k - } // end for j - } // end for i - - //form rank4 IbunI - - IbunI [0][0] [0][0] = 1.0 ; - IbunI [0][0] [1][1] = 1.0 ; - IbunI [0][0] [2][2] = 1.0 ; - IbunI [1][1] [0][0] = 1.0 ; - IbunI [1][1] [1][1] = 1.0 ; - IbunI [1][1] [2][2] = 1.0 ; - IbunI [2][2] [0][0] = 1.0 ; - IbunI [2][2] [1][1] = 1.0 ; - IbunI [2][2] [2][2] = 1.0 ; - - //form rank4 IIdev - - IIdev [0][0] [0][0] = two3 ; // 0.666667 - IIdev [0][0] [1][1] = -one3 ; //-0.333333 - IIdev [0][0] [2][2] = -one3 ; //-0.333333 - IIdev [0][1] [0][1] = 0.5 ; - IIdev [0][1] [1][0] = 0.5 ; - IIdev [0][2] [0][2] = 0.5 ; - IIdev [0][2] [2][0] = 0.5 ; - IIdev [1][0] [0][1] = 0.5 ; - IIdev [1][0] [1][0] = 0.5 ; - IIdev [1][1] [0][0] = -one3 ; //-0.333333 - IIdev [1][1] [1][1] = two3 ; // 0.666667 - IIdev [1][1] [2][2] = -one3 ; //-0.333333 - IIdev [1][2] [1][2] = 0.5 ; - IIdev [1][2] [2][1] = 0.5 ; - IIdev [2][0] [0][2] = 0.5 ; - IIdev [2][0] [2][0] = 0.5 ; - IIdev [2][1] [1][2] = 0.5 ; - IIdev [2][1] [2][1] = 0.5 ; - IIdev [2][2] [0][0] = -one3 ; //-0.333333 - IIdev [2][2] [1][1] = -one3 ; //-0.333333 - IIdev [2][2] [2][2] = two3 ; // 0.666667 - - //form rank4 IbunII - - IbunII [0][0] [0][0] = 1 ; - IbunII [0][0] [1][1] = 1 ; - IbunII [0][0] [2][2] = 1 ; - IbunII [0][1] [0][1] = 1 ; - IbunII [0][1] [1][0] = 1 ; - IbunII [0][2] [0][2] = 1 ; - IbunII [0][2] [2][0] = 1 ; - IbunII [1][0] [0][1] = 1 ; - IbunII [1][0] [1][0] = 1 ; - IbunII [1][1] [0][0] = 1 ; - IbunII [1][1] [1][1] = 1 ; - IbunII [1][1] [2][2] = 1 ; - IbunII [1][2] [1][2] = 1 ; - IbunII [1][2] [2][1] = 1 ; - IbunII [2][0] [0][2] = 1 ; - IbunII [2][0] [2][0] = 1 ; - IbunII [2][1] [1][2] = 1 ; - IbunII [2][1] [2][1] = 1 ; - IbunII [2][2] [0][0] = 1 ; - IbunII [2][2] [1][1] = 1 ; - IbunII [2][2] [2][2] = 1 ; - - plastic_integrator(); -} - -//full constructor -Concrete :: Concrete( int tag, - int classTag, - double E_i, - double ni_i, - double f01d_i, - double f02d_i, - double f0p_i, - double beta_i, - double An_i, - double Bn_i, - double Ap_i, - double gammaC_i, // 14/12/2011 Diego Talledo: Added Shear Retention Factor - double dchemn_i, // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - double dchemp_i, // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - int def_i, // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - double dpMax_i, // 11/01/2013 Diego Talledo: Added Positive Damage Limit - double dnMax_i, // 11/01/2013 Diego Talledo: Added Negative Damage Limit - bool srfCompr_i, // 11/03/2013 Diego Talledo: Apply SRF also to compression. - bool isDchemVar_i, // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - double eps_u_i // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - ) -: -NDMaterial(tag, classTag), -epsilon_p_n(3,3), -epsilon_p_nplus1(3,3), -stress(3,3), -strain(3,3), -stress_n(3,3), -strain_n(3,3) -{ - // Set INPUT Parameters - - E = E_i; - ni = ni_i; - f01d = f01d_i; - f02d = f02d_i; - f0p = f0p_i; - beta = beta_i; - An = An_i; - Bn = Bn_i; - Ap = Ap_i; - gammaC = gammaC_i; // 14/12/2011 Diego Talledo: Added Shear Retention Factor - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - if (def_i == 1) - usedEquivalentTensionDefinition = HOMOGENEOUS; - else if (def_i == 2) - usedEquivalentTensionDefinition = COMPDYN; - else - usedEquivalentTensionDefinition = ORIGINAL; - - // Calculate initial Parameters - lambda = E*ni/((1+ni)*(1-2*ni)); - shear_p = E/(2*(1+ni)); - bulk_p = lambda+2/3.0*shear_p; - k_p = sqrt(2.0)*(f02d-f01d)/(2*f02d-f01d); - if (usedEquivalentTensionDefinition == ORIGINAL) - { - r0n = sqrt(sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3); - r0p = sqrt(f0p/sqrt(E)); - } - else if (usedEquivalentTensionDefinition == HOMOGENEOUS) - { - r0n = sqrt(sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3); - r0p = sqrt(f0p); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - r0n = sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3; - r0p = f0p; - } - - // Environmental damage - dchemn = dchemn_i; // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - dchemp = dchemp_i; // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - eps_u = eps_u_i; // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - isDchemVariableSelected = isDchemVar_i; // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - if (isDchemVariableSelected) { - if ((usedEquivalentTensionDefinition == ORIGINAL) || (usedEquivalentTensionDefinition == HOMOGENEOUS)) - { - tau_n_eps_u = sqrt(sqrt(3.0)*(k_p-sqrt(2.0))*(E*(eps_u-((eps_u - f01d/E) * beta)))/3); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - tau_n_eps_u = sqrt(3.0)*(k_p-sqrt(2.0))*(E*(eps_u-((eps_u - f01d/E) * beta)))/3; - } - } - - // Initialization of damage parameters - dn = 0.0; - dp = 0.0; - rnn = r0n; - rnp1n=rnn; - rnp = r0p; - rnp1p=rnp; - // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - dnstar = 0.0; - dpstar = 0.0; - // 14/12/2011 Diego Talledo: Added Shear Retention Factor - SRF12 = 0.0; - SRF23 = 0.0; - SRF13 = 0.0; - - // 11/01/2013 Diego Talledo: Added Positive and Negative Damage Limit - dpMax = dpMax_i; - dnMax = dnMax_i; - - // 11/03/2013 Diego Talledo: Apply SRF also to compression. - srfCompr = srfCompr_i; - - this->zero( ) ; // or (*this).zero( ) - - int i, j, k, l ; - - //zero rank4 IIdev, IbunI and IbunII - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) { - for ( k = 0; k < 3; k++ ) { - for ( l = 0; l < 3; l++) { - IbunI[i][j][k][l] = 0.0 ; - IbunII[i][j][k][l] = 0.0; - IIdev[i][j][k][l] = 0.0 ; - } // end for l - } // end for k - } // end for j - } // end for i - - //form rank4 IbunI - - IbunI [0][0] [0][0] = 1.0 ; - IbunI [0][0] [1][1] = 1.0 ; - IbunI [0][0] [2][2] = 1.0 ; - IbunI [1][1] [0][0] = 1.0 ; - IbunI [1][1] [1][1] = 1.0 ; - IbunI [1][1] [2][2] = 1.0 ; - IbunI [2][2] [0][0] = 1.0 ; - IbunI [2][2] [1][1] = 1.0 ; - IbunI [2][2] [2][2] = 1.0 ; - - //form rank4 IIdev - - IIdev [0][0] [0][0] = two3 ; // 0.666667 - IIdev [0][0] [1][1] = -one3 ; //-0.333333 - IIdev [0][0] [2][2] = -one3 ; //-0.333333 - IIdev [0][1] [0][1] = 0.5 ; - IIdev [0][1] [1][0] = 0.5 ; - IIdev [0][2] [0][2] = 0.5 ; - IIdev [0][2] [2][0] = 0.5 ; - IIdev [1][0] [0][1] = 0.5 ; - IIdev [1][0] [1][0] = 0.5 ; - IIdev [1][1] [0][0] = -one3 ; //-0.333333 - IIdev [1][1] [1][1] = two3 ; // 0.666667 - IIdev [1][1] [2][2] = -one3 ; //-0.333333 - IIdev [1][2] [1][2] = 0.5 ; - IIdev [1][2] [2][1] = 0.5 ; - IIdev [2][0] [0][2] = 0.5 ; - IIdev [2][0] [2][0] = 0.5 ; - IIdev [2][1] [1][2] = 0.5 ; - IIdev [2][1] [2][1] = 0.5 ; - IIdev [2][2] [0][0] = -one3 ; //-0.333333 - IIdev [2][2] [1][1] = -one3 ; //-0.333333 - IIdev [2][2] [2][2] = two3 ; // 0.666667 - - //form rank4 IbunII - - IbunII [0][0] [0][0] = 1 ; - IbunII [0][0] [1][1] = 1 ; - IbunII [0][0] [2][2] = 1 ; - IbunII [0][1] [0][1] = 1 ; - IbunII [0][1] [1][0] = 1 ; - IbunII [0][2] [0][2] = 1 ; - IbunII [0][2] [2][0] = 1 ; - IbunII [1][0] [0][1] = 1 ; - IbunII [1][0] [1][0] = 1 ; - IbunII [1][1] [0][0] = 1 ; - IbunII [1][1] [1][1] = 1 ; - IbunII [1][1] [2][2] = 1 ; - IbunII [1][2] [1][2] = 1 ; - IbunII [1][2] [2][1] = 1 ; - IbunII [2][0] [0][2] = 1 ; - IbunII [2][0] [2][0] = 1 ; - IbunII [2][1] [1][2] = 1 ; - IbunII [2][1] [2][1] = 1 ; - IbunII [2][2] [0][0] = 1 ; - IbunII [2][2] [1][1] = 1 ; - IbunII [2][2] [2][2] = 1 ; - - plastic_integrator(); -} - -//elastic constructor -Concrete :: Concrete( int tag, - int classTag, - double E_i, - double ni_i ) : -NDMaterial(tag, classTag), -epsilon_p_n(3,3), -epsilon_p_nplus1(3,3), -stress(3,3), -strain(3,3), -stress_n(3,3), -strain_n(3,3) -{ - - // Set INPUT Parameters - - E = E_i; - ni = ni_i; - f01d = -1.0e16*E; - f02d = -1.0e16*E; - f0p = 1.0e16*E; - beta = 0.0; - An = 1.0; - Bn = 1.0; - Ap = 1.0; - gammaC = 0.0; // 14/12/2011 Diego Talledo: Added Shear Retention Factor - dchemn = 0.0; // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - dchemp = dchemn; - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - usedEquivalentTensionDefinition = COMPDYN; // By default we use the COMPDYN implemented definition - - // Calculate initial Parameters - lambda = E*ni/((1+ni)*(1-2*ni)); - shear_p = E/(2*(1+ni)); - bulk_p = lambda+2/3.0*shear_p; - k_p = sqrt(2.0)*(f02d-f01d)/(2*f02d-f01d); - if (usedEquivalentTensionDefinition == ORIGINAL) - { - r0n = sqrt(sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3); - r0p = sqrt(f0p/sqrt(E)); - } - else if (usedEquivalentTensionDefinition == HOMOGENEOUS) - { - r0n = sqrt(sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3); - r0p = sqrt(f0p); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - r0n = sqrt(3.0)*(k_p-sqrt(2.0))*f01d/3; - r0p = f0p; - } - - // Initialization of damage parameters - dn = 0.0; - dp = 0.0; - rnn = r0n; - rnp1n=rnn; - rnp = r0p; - rnp1p=rnp; - // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - dnstar = 0.0; - dpstar = 0.0; - // 14/12/2011 Diego Talledo: Added Shear Retention Factor - SRF12 = 0.0; - SRF23 = 0.0; - SRF13 = 0.0; - - // 11/01/2013 Diego Talledo: Added Positive and Negative Damage Limit - dpMax = 0.99999; // Default value - dnMax = 0.99999; // Default value - - // 11/03/2013 Diego Talledo: Apply SRF also to compression. - srfCompr = false; // Default value - - this->zero( ) ; // or (*this).zero( ) - - int i, j, k, l ; - - //zero rank4 IIdev, IbunI and IbunII - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) { - for ( k = 0; k < 3; k++ ) { - for ( l = 0; l < 3; l++) { - IbunI[i][j][k][l] = 0.0 ; - IbunII[i][j][k][l] = 0.0; - IIdev[i][j][k][l] = 0.0 ; - } // end for l - } // end for k - } // end for j - } // end for i - - //form rank4 IbunI - - IbunI [0][0] [0][0] = 1.0 ; - IbunI [0][0] [1][1] = 1.0 ; - IbunI [0][0] [2][2] = 1.0 ; - IbunI [1][1] [0][0] = 1.0 ; - IbunI [1][1] [1][1] = 1.0 ; - IbunI [1][1] [2][2] = 1.0 ; - IbunI [2][2] [0][0] = 1.0 ; - IbunI [2][2] [1][1] = 1.0 ; - IbunI [2][2] [2][2] = 1.0 ; - - //form rank4 IIdev - - IIdev [0][0] [0][0] = two3 ; // 0.666667 - IIdev [0][0] [1][1] = -one3 ; //-0.333333 - IIdev [0][0] [2][2] = -one3 ; //-0.333333 - IIdev [0][1] [0][1] = 0.5 ; - IIdev [0][1] [1][0] = 0.5 ; - IIdev [0][2] [0][2] = 0.5 ; - IIdev [0][2] [2][0] = 0.5 ; - IIdev [1][0] [0][1] = 0.5 ; - IIdev [1][0] [1][0] = 0.5 ; - IIdev [1][1] [0][0] = -one3 ; //-0.333333 - IIdev [1][1] [1][1] = two3 ; // 0.666667 - IIdev [1][1] [2][2] = -one3 ; //-0.333333 - IIdev [1][2] [1][2] = 0.5 ; - IIdev [1][2] [2][1] = 0.5 ; - IIdev [2][0] [0][2] = 0.5 ; - IIdev [2][0] [2][0] = 0.5 ; - IIdev [2][1] [1][2] = 0.5 ; - IIdev [2][1] [2][1] = 0.5 ; - IIdev [2][2] [0][0] = -one3 ; //-0.333333 - IIdev [2][2] [1][1] = -one3 ; //-0.333333 - IIdev [2][2] [2][2] = two3 ; // 0.666667 - - //form rank4 IbunII - - IbunII [0][0] [0][0] = 1 ; - IbunII [0][0] [1][1] = 1 ; - IbunII [0][0] [2][2] = 1 ; - IbunII [0][1] [0][1] = 1 ; - IbunII [0][1] [1][0] = 1 ; - IbunII [0][2] [0][2] = 1 ; - IbunII [0][2] [2][0] = 1 ; - IbunII [1][0] [0][1] = 1 ; - IbunII [1][0] [1][0] = 1 ; - IbunII [1][1] [0][0] = 1 ; - IbunII [1][1] [1][1] = 1 ; - IbunII [1][1] [2][2] = 1 ; - IbunII [1][2] [1][2] = 1 ; - IbunII [1][2] [2][1] = 1 ; - IbunII [2][0] [0][2] = 1 ; - IbunII [2][0] [2][0] = 1 ; - IbunII [2][1] [1][2] = 1 ; - IbunII [2][1] [2][1] = 1 ; - IbunII [2][2] [0][0] = 1 ; - IbunII [2][2] [1][1] = 1 ; - IbunII [2][2] [2][2] = 1 ; -} - -//destructor -Concrete :: ~Concrete( ) -{ } - -NDMaterial* -Concrete :: getCopy (const char *type) -{ - if (strcmp(type,"PlaneStress") == 0) - { - CPlaneStress *clone ; - clone = new CPlaneStress(this->getTag(), E, ni, f01d, f02d, - f0p, beta, An, Bn, Ap, gammaC, dchemn, dchemp, usedEquivalentTensionDefinition, dpMax, dnMax, srfCompr, isDchemVariableSelected, eps_u) ; - return clone ; - } - else if (strcmp(type,"PlaneStress2D") == 0) - { - CPlaneStress2d *clone ; - clone = new CPlaneStress2d(this->getTag(), E, ni, f01d, f02d, - f0p, beta, An, Bn, Ap, gammaC, dchemn, dchemp, usedEquivalentTensionDefinition, dpMax, dnMax, srfCompr, isDchemVariableSelected, eps_u) ; - return clone ; - } - else if (strcmp(type,"PlaneStrain2D") == 0 || strcmp(type,"PlaneStrain") == 0) - { - CPlaneStrain *clone ; - clone = new CPlaneStrain(this->getTag(), E, ni, f01d, f02d, - f0p, beta, An, Bn, Ap, gammaC, dchemn, dchemp, usedEquivalentTensionDefinition, dpMax, dnMax, srfCompr, isDchemVariableSelected, eps_u) ; - return clone ; - } - else if (strcmp(type,"AxiSymmetric2D") == 0 || strcmp(type,"AxiSymmetric") == 0) - { - opserr << "Concrete::getModel failed to get model: " << type << endln; - return 0; - } - else if ((strcmp(type,"ThreeDimensional") == 0) || (strcmp(type,"3D") == 0)) - { - CThreeDimensional *clone ; - clone = new CThreeDimensional(this->getTag(), E, ni, f01d, f02d, - f0p, beta, An, Bn, Ap, gammaC, dchemn, dchemp, usedEquivalentTensionDefinition, dpMax, dnMax, srfCompr, isDchemVariableSelected, eps_u) ; - return clone ; - } - else if ((strcmp(type,"PlateFiber") == 0)) - { - opserr << "Concrete::getModel failed to get model: " << type << endln; - return 0; - } - // Handle other cases - else - { - opserr << "Concrete::getModel failed to get model: " << type << endln; - return 0; - } -} - -//print out material data -void Concrete :: Print( OPS_Stream &s, int flag ) -{ - s << endln ; - s << "Concrete : " ; - s << this->getType( ) << endln ; - s << "Young Modulus = " << E << endln ; - s << "Poisson Modulus = " << ni << endln ; - s << "f01d = " << f01d << endln ; - s << "f02d = " << f02d << endln ; - s << "f0p = " << f0p << endln ; - s << "beta = " << beta << endln ; - s << "An = " << An << endln ; - s << "Bn = " << Bn << endln ; - s << "Ap = " << Ap << endln ; - // 14/12/2011 Diego Talledo: Added Shear Retention Factor - s << "gammaC = " << gammaC << endln; - // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - s << "dchemn = " << dchemn << endln; - s << "dchemp = " << dchemp << endln; - if (isDchemVariableSelected) - { - s << "dchem linearly variable " << endln; - s << "eps_u = " << eps_u << endln; - } - // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - // 10/01/2013 Diego Talledo: Added different equivalent tension definitions - if (usedEquivalentTensionDefinition == ORIGINAL) - { - s << "Using original equivalent tension definition ("; - } - else if (usedEquivalentTensionDefinition == HOMOGENEOUS) - { - s << "Using homogeneous equivalent tension definition ("; - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - s << "Using compdyn equivalent tension definition ("; - } - s << usedEquivalentTensionDefinition << ")" << endln; -} - -//--------------------Plasticity------------------------------------- - -//plasticity integration routine -void Concrete :: plastic_integrator( ) -{ - const double tolerance = (1.0e-14)*f0p ; - - static Matrix dev_strain(3,3) ; //deviatoric strain - static Matrix dev_stress(3,3) ; //deviatoric stress - - static Matrix tmp_senp1t(3,3) ; //Sigma_eff n+1 trial - - double trace = 0.0 ; //trace of strain - - int i,j,k,l; - int ii, jj ; - - double senp1t[3][3]; - double V[3][3],EE[3][3]; - double dg[3],dgn[3],dgp[3]; - double sigoct,tauoct,taun,taup; - double alfa,diag,norms,pint,lambdap; - double st[3][3],dea[3][3],ls[3][3],ses[3][3]; - double trans[3][3]; - double supp1[3][3],supp2[3][3]; - - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - { - if (i==j) - EE[i][j]=1.0; - else - EE[i][j]=0.0; - }; - }; - - double g, rhoQ, thetaQ, rhoP, alfasp, alfasn, rhoL, thetaL; - - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - dep[i][j]=0.0; - }; - - // evaluate trace of elastic strain - trace=0.0; - for (i=0;i<3;i++) - { - trace+=strain(i,i)-epsilon_p_n(i,i); - }; - - // Deviatoric strain tensor - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - dev_strain(i,j)=strain(i,j)-epsilon_p_n(i,j); - }; - for (i=0;i<3;i++) - { - dev_strain(i,i)-= 1*trace/3; - }; - - // Deviatoric Stress - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - dev_stress(i,j)=dev_strain(i,j)*2.0*shear_p; // Strain(1,2) è epsilon12, per 2 = gamma12 - }; - - // Sigma Eff (n+1,Trial) = DevStress + I * K * trace(StrainElastic) - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - senp1t[i][j]=dev_stress(i,j); - }; - for (i=0;i<3;i++) - senp1t[i][i]=senp1t[i][i]+bulk_p*trace; - - if (beta>0.0) - { - // Splitting of Trial Effective Stress in Principal System - - // Project in principal system - eigen_decomposition(senp1t,EE,V,dg); - - // Negative part of principal Trial Effective Stress - for (i=0;i<3;i++) - dgn[i]=(dg[i]-fabs(dg[i]))/2; - - // Compute tau,n - sigoct=(dgn[0]+dgn[1]+dgn[2])/3; - tauoct=sqrt((dgn[0]-dgn[1])*(dgn[0]-dgn[1])+(dgn[0]-dgn[2])*(dgn[0]-dgn[2])+(dgn[1]-dgn[2])*(dgn[1]-dgn[2]))/3; - if ((usedEquivalentTensionDefinition == ORIGINAL) || (usedEquivalentTensionDefinition == HOMOGENEOUS)) - { - taun=sqrt(3.0)*(k_p*sigoct+tauoct); - if (taun >= 0) - taun = sqrt(taun); - else - taun = 0; - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - taun=sqrt(3.0)*(k_p*sigoct+tauoct); - } - - // Positive part of principal Trial Effective Stress - for (i=0;i<3;i++) - dgp[i]=(dg[i]+fabs(dg[i]))/2; - - // Compute tau,p - for (i=0;i<3;i++) - dgp[i]=(dg[i]+fabs(dg[i]))/2; - diag=(dgp[0]+dgp[1]+dgp[2])*ni/(-E); - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - { - trans[i][j]=0.0; - if (i==j) - trans[i][i]=(dgp[i]*(1+ni)/E)+diag; - }; - }; - taup=0.0; - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - if (i==j) - taup+=trans[i][j]*dgp[i]; - }; - if (usedEquivalentTensionDefinition == ORIGINAL) - { - taup=sqrt(sqrt(taup)); - } - else if (usedEquivalentTensionDefinition == HOMOGENEOUS) - { - taup=sqrt(sqrt(taup*E)); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - taup=sqrt(taup*E); - } - - // Compute if inside damage surface - g=((taup/rnp)*(taup/rnp))+((taun/rnn)*(taun/rnn))-1; - if (g>tolerance) - { - //Q: trial - //P: intersection ellipse with line OQ - rhoQ = sqrt(taup*taup+taun*taun); - if (taun > 1e-15) { - thetaQ=atan(taup/taun); - } else { - thetaQ=PI/2.0; - } - // Modifica 26 Marzo 2012: Diego - Cambio formula per il calcolo di rhoP - //rhoP=sqrt((rnp*rnp*rnn*rnn)/(rnn*rnn*sin(thetaQ)*sin(thetaQ)+rnp*rnp*cos(thetaQ)*cos(thetaQ))); - rhoP = rnp*rnn*sqrt((taun*taun+taup*taup)/((taun*rnp)*(taun*rnp)+(taup*rnn)*(taup*rnn))); - // Diego 23 Marzo 2012: piccola modifica per problemi numerici - // (può essere che rhoP venga un pelino più piccolo di rnp o un pelino più grande di rnn) - if (rnn >= rnp) - { - if (rhoPrnn) - rhoP = rnn; - } - else if (rnn < rnp) - { - if (rhoP>rnp) - rhoP =rnp; - if (rhoP0) - { - lambdap=1-beta*E*pint/norms; - - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - ses[i][j]=senp1t[i][j]*lambdap; - - }; - if ((usedEquivalentTensionDefinition == ORIGINAL) || (usedEquivalentTensionDefinition == HOMOGENEOUS)) - { - taun*=sqrt(lambdap); - taup*=sqrt(lambdap); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - taun*=lambdap; - taup*=lambdap; - } - - // check if inside of ellipse in taup,taun space - g=(taup/rnp)*(taup/rnp)+(taun/rnn)*(taun/rnn)-1; - if (g>tolerance) - { - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - senp1t[i][j]=ses[i][j]; - }; - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - trans[i][j]=ls[i][j]*(1+ni)/E; - }; - diag=(ls[0][0]+ls[1][1]+ls[2][2])*ni/(-E); - - for (i=0;i<3;i++) - trans[i][i]=trans[i][i]+diag; - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - { - dep[i][j]=beta*E*pint*trans[i][j]; - epsilon_p_nplus1(i,j)=epsilon_p_n(i,j)+dep[i][j]; - }; - }; - } - else - { - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - epsilon_p_nplus1(i,j)=epsilon_p_n(i,j); - }; - }; - } - else { - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - epsilon_p_nplus1(i,j)=epsilon_p_n(i,j); - }; - }; - } - else - { - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - epsilon_p_nplus1(i,j)=epsilon_p_n(i,j); - }; - }; - }; - // Diego: aggiunto l'aggiornamento della matrice diagonale dg - // e il calcolo di taun - eigen_decomposition(senp1t,EE,V,dg); - for (i=0;i<3;i++) - dgn[i]=(dg[i]-fabs(dg[i]))/2.0; - sigoct=(dgn[0]+dgn[1]+dgn[2])/3.0; - tauoct=sqrt((dgn[0]-dgn[1])*(dgn[0]-dgn[1])+(dgn[0]-dgn[2])*(dgn[0]-dgn[2])+(dgn[1]-dgn[2])*(dgn[1]-dgn[2]))/3.0; - if ((usedEquivalentTensionDefinition == ORIGINAL) || (usedEquivalentTensionDefinition == HOMOGENEOUS)) - { - taun=sqrt(3.0)*(k_p*sigoct+tauoct); - if (taun >= 0) - taun = sqrt(taun); - else - taun = 0; - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - taun=sqrt(3.0)*(k_p*sigoct+tauoct); - } - - // Calcolo di taup - for (i=0;i<3;i++) - dgp[i]=(dg[i]+fabs(dg[i]))/2.0; - diag=(dgp[0]+dgp[1]+dgp[2])*ni/(-E); - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - { - trans[i][j]=0.0; - if (i==j) // Diego!!!! - trans[i][i]=dgp[i]*(1+ni)/E+diag; - }; - }; - taup=0.0; - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - if (i==j) // Diego!!!! - taup+=trans[i][j]*dgp[i]; - }; - if (usedEquivalentTensionDefinition == ORIGINAL) - { - taup=sqrt(sqrt(taup)); - } - else if (usedEquivalentTensionDefinition == HOMOGENEOUS) - { - taup=sqrt(sqrt(taup*E)); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - taup=sqrt(taup*E); - } - - // Aggiornamento di G - g=(taup/rnp)*(taup/rnp)+(taun/rnn)*(taun/rnn)-1; - if (g>tolerance) - { - // Evolution of damage - //compute alfa - //Q: trial - //P: intersection ellipse with line OQ - rhoQ = sqrt(taup*taup+taun*taun); - // Diego 23 Marzo 2012: prova modifica calcolo tangente. - // Modifica 26 Marzo 2012: Diego - Cambio formula per il calcolo di rhoP - if (taun > 1e-15) { - thetaQ=atan(taup/taun); - } else { - thetaQ=PI/2.0; - } - // Fine modifica 23 Marzo 2012 - // Modifica 26 Marzo 2012: Diego - Cambio formula per il calcolo di rhoP - //rhoP=sqrt((rnp*rnp*rnn*rnn)/(rnn*rnn*sin(thetaQ)*sin(thetaQ)+rnp*rnp*cos(thetaQ)*cos(thetaQ))); - rhoP = rnp*rnn*sqrt((taun*taun+taup*taup)/((taun*rnp)*(taun*rnp)+(taup*rnn)*(taup*rnn))); - // diego 23 Marzo 2012: piccola modifica per problemi numerici - // (può essere che rhoP venga un pelino più piccolo di rnp o un pelino più grande di rnn) - if (rnn >= rnp) - { - if (rhoPrnn) - rhoP = rnn; - } - else if (rnn < rnp) - { - if (rhoP>rnp) - rhoP =rnp; - if (rhoPrhoL) { // Diego: Versione vecchia ed eliminata il 13 marzo 2012 dell'IF - if (((rhoP>rhoL) && (rhoP<=rnn)) || ((rhoP>=rnn) && (rhoPrhoL) && (rhoP<=rnp)) || ((rhoP>=rnp) && (rhoP=dnMax) - { - dn=dnMax; - //dn = 0.99999; // togliere - }; - // Diego: controllo che il danno negativo sia maggiore di zero. 13 marzo 2012 blocco dn - if (dn<0.0) - { - dn=0.0; - }; - - // compute positive damage - if ((usedEquivalentTensionDefinition == ORIGINAL) || (usedEquivalentTensionDefinition == HOMOGENEOUS)) - { - dp=1-((r0p*r0p)/(rnp1p*rnp1p))*exp(Ap*(1-(rnp1p*rnp1p)/(r0p*r0p))); - } - else if (usedEquivalentTensionDefinition == COMPDYN) - { - dp=1-((r0p)/(rnp1p))*exp(Ap*(1-(rnp1p)/(r0p))); - } - - // Limiti su DP -> necessaria ulteriore ricerca - // 11/01/2013 Diego Talledo: Added Positive Damage Limit - if (dp>=dpMax) - { - dp=dpMax; - }; - - // 14/12/2011 Diego Talledo: Added Shear Retention Factor - if (gammaC <= 0.0) { - SRF12 = 0.0; - SRF23 = 0.0; - SRF13 = 0.0; - } - else { - SRF12 = 1-abs(strain(0,1))/gammaC; - SRF23 = 1-abs(strain(1,2))/gammaC; - SRF13 = 1-abs(strain(0,2))/gammaC; - if (SRF12 <= 0.0) { - SRF12 = 0.0; - } - if (SRF23 <= 0.0) { - SRF23 = 0.0; - } - if (SRF13 <= 0.0) { - SRF13 = 0.0; - } - } - - // Reproject in local system - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - { - supp1[i][j]=0.0; - supp2[i][j]=0.0; - supp1[i][j]=supp1[i][j]+V[i][j]*dgn[j]; - supp2[i][j]=supp2[i][j]+V[i][j]*dgp[j]; - }; - }; - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - { - Dn[i][j]=0.0; - Dp[i][j]=0.0; - for (k=0;k<3;k++) - { - Dn[i][j]=Dn[i][j]+supp1[i][k]*V[j][k]; - Dp[i][j]=Dp[i][j]+supp2[i][k]*V[j][k]; - }; - }; - }; - - // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - // Compute dnstar and dpstar - dnstar = dn + dchemn - (dchemn * dn); - dpstar = dp + dchemp - (dchemp * dp); - - // 14/07/2014 Diego Talledo: Aggiunto dchemn variabile - // dchem variabile: retta tra dchemn e 1. Con 1 raggiunto per epsilon pari a eps_u - if (isDchemVariableSelected) { - double dchem_var = (1-dchemn)/tau_n_eps_u*rnp1n+dchemn; - dnstar = dn + dchem_var - (dchem_var * dn); - } - // Fine prova dchem variabile - - // Compute Cauchy Damaged Stress - for (i=0;i<3;i++) - { - for (j=0;j<3;j++) - { - //stress(i,j)=(1-dn)*Dn[i][j]+(1-dp)*Dp[i][j]; - stress(i,j)=(1-dnstar)*Dn[i][j]+(1-dpstar)*Dp[i][j]; // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - - // 14/12/2011 Diego Talledo: Added Shear Retention Factor - if ((i==1 && j==0) || (i==0 && j==1)) { - //stress(i,j)=(1-(1-SRF12)*dnstar)*Dn[i][j]+(1-(1-SRF12)*dpstar)*Dp[i][j]; - if (!srfCompr) - stress(i,j)=(1-dnstar)*Dn[i][j]+(1-(1-SRF12)*dpstar)*Dp[i][j]; - else - stress(i,j)=(1-(1-SRF12)*dnstar)*Dn[i][j]+(1-(1-SRF12)*dpstar)*Dp[i][j]; - } - if ((i==1 && j==2) || (i==2 && j==1)) { - //stress(i,j)=(1-(1-SRF23)*dnstar)*Dn[i][j]+(1-(1-SRF23)*dpstar)*Dp[i][j]; - if (!srfCompr) - stress(i,j)=(1-dnstar)*Dn[i][j]+(1-(1-SRF23)*dpstar)*Dp[i][j]; - else - stress(i,j)=(1-(1-SRF23)*dnstar)*Dn[i][j]+(1-(1-SRF23)*dpstar)*Dp[i][j]; - } - if ((i==2 && j==0) || (i==0 && j==2)) { - //stress(i,j)=(1-(1-SRF13)*dnstar)*Dn[i][j]+(1-(1-SRF13)*dpstar)*Dp[i][j]; - if (!srfCompr) - stress(i,j)=(1-dnstar)*Dn[i][j]+(1-(1-SRF13)*dpstar)*Dp[i][j]; - else - stress(i,j)=(1-(1-SRF13)*dnstar)*Dn[i][j]+(1-(1-SRF13)*dpstar)*Dp[i][j]; - } - }; - }; - - //compute the tangent - - for ( ii = 0; ii < 6; ii++ ) { - for ( jj = 0; jj < 6; jj++ ) { - - index_map( ii, i, j ) ; - index_map( jj, k, l ) ; - - //elastic terms - //tangent[i][j][k][l] = (1-dn)*bulk_p * IbunI[i][j][k][l] ; - //tangent[i][j][k][l] += (1-dn)*(2.0*shear_p) * IIdev[i][j][k][l] ; - tangent[i][j][k][l] = (1-dnstar)*bulk_p * IbunI[i][j][k][l] ; // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - tangent[i][j][k][l] += (1-dnstar)*(2.0*shear_p) * IIdev[i][j][k][l] ; // 20/06/2012 Diego Talledo: Added Environmental Chemical Damage - - //minor symmetries - tangent [j][i][k][l] = tangent[i][j][k][l] ; - tangent [i][j][l][k] = tangent[i][j][k][l] ; - tangent [j][i][l][k] = tangent[i][j][k][l] ; - } // end for jj - } // end for ii - - return ; -} - -// set up for initial elastic -void Concrete :: doInitialTangent( ) -{ - int ii,jj,i,j,k,l; - - //compute the deviatoric strains - for ( ii = 0; ii < 6; ii++ ) { - for ( jj = 0; jj < 6; jj++ ) { - - index_map( ii, i, j ) ; - index_map( jj, k, l ) ; - - //elastic terms - initialTangent[i][j][k][l] = bulk_p * IbunI[i][j][k][l] ; - initialTangent[i][j][k][l] += (2.0*shear_p) * IIdev[i][j][k][l] ; - - //minor symmetries - initialTangent [j][i][k][l] = initialTangent[i][j][k][l] ; - initialTangent [i][j][l][k] = initialTangent[i][j][k][l] ; - initialTangent [j][i][l][k] = initialTangent[i][j][k][l] ; - } // end for jj - } // end for ii - - return ; -} - -//matrix_index ---> tensor indices i,j -void Concrete :: index_map( int matrix_index, int &i, int &j ) -{ - switch ( matrix_index+1 ) { //add 1 for standard tensor indices - - case 1 : - i = 1 ; - j = 1 ; - break ; - - case 2: - i = 2 ; - j = 2 ; - break ; - - case 3 : - i = 3 ; - j = 3 ; - break ; - - case 4 : - i = 1 ; - j = 2 ; - break ; - - case 5 : - i = 2 ; - j = 3 ; - break ; - - case 6 : - i = 3 ; - j = 1 ; - break ; - - default : - i = 1 ; - j = 1 ; - break ; - } //end switch - - i-- ; //subtract 1 for C-indexing - j-- ; - - return ; -} - -NDMaterial* -Concrete::getCopy (void) -{ - opserr << "Concrete::getCopy -- subclass responsibility\n"; - exit(-1); - return 0; -} - -const char* -Concrete::getType (void) const -{ - opserr << "Concrete::getType -- subclass responsibility\n"; - exit(-1); - return 0; -} - -int -Concrete::getOrder (void) const -{ - opserr << "Concrete::getOrder -- subclass responsibility\n"; - exit(-1); - return 0; -} - -int -Concrete::commitState( ) -{ - epsilon_p_n = epsilon_p_nplus1 ; - rnp=rnp1p; - rnn=rnp1n; - - strain_n = strain; - stress_n = stress; - - return 0; -} - - -int -Concrete::revertToLastCommit( ) -{ - return 0; -} - - -int -Concrete::revertToStart( ) -{ - this->zero( ) ; - - return 0; -} - -int -Concrete::sendSelf(int commitTag, Channel &theChannel) -{ - //opserr<<"sendSelf"<getTag(); - data(cnt++) = E; - data(cnt++) = ni; - data(cnt++) = f01d; - data(cnt++) = f02d; - data(cnt++) = f0p; - data(cnt++) = beta; - data(cnt++) = An; - data(cnt++) = Bn; - data(cnt++) = Ap; - data(cnt++) = rnn; - data(cnt++) = rnp; - data(cnt++) = rnp1n; - data(cnt++) = rnp1p; - - // send the vector object to the channel - if (theChannel.sendVector(this->getDbTag(), commitTag, data) < 0) { - opserr << "Concrete::sendSelf - failed to send vector to channel\n"; - return -1; - } - - return 0; -} - -int -Concrete::recvSelf (int commitTag, Channel &theChannel, - FEM_ObjectBroker &theBroker) -{ - //opserr<<"recvSelf"<getDbTag(), commitTag, data) < 0) { - opserr << "Concrete::recvSelf - failed to recv vector from channel\n"; - return -1; - } - - // set the material parameters and state variables - int cnt = 0; - this->setTag(data(cnt++)); - E = data(cnt++); - ni = data(cnt++); - f01d = data(cnt++); - f02d = data(cnt++); - f0p = data(cnt++); - beta = data(cnt++); - An = data(cnt++); - Bn = data(cnt++); - Ap = data(cnt++); - rnn = data(cnt++); - rnp = data(cnt++); - rnp1n= data(cnt++); - rnp1p= data(cnt++); - //rnp1n=rnn; - //rnp1p=rnp; - epsilon_p_nplus1 = epsilon_p_n; - //xi_nplus1 = xi_n; - - return 0; -} - -const Vector & Concrete::getFiberDamage() -{ - static Vector tmp(2); - tmp(0) = this->dn; - tmp(1) = this->dp; - - return tmp; -} - -const Vector & Concrete::getDamage() -{ - static Vector tmp(2); - tmp(0) = this->dn; - tmp(1) = this->dp; - - return tmp; -} - -// Diego Gennaio 2015 : Per implementazione Danno Globale -const Vector & Concrete::getElasticFreeEnergy() -{ - static Vector tmp(2); // Psi0- Psi0+ - - // Valutazione sigma effetiva elastica e decomposizione spettrale - static Matrix dev_strain(3,3) ; //deviatoric strain - static Matrix dev_stress(3,3) ; //deviatoric stress - - double trace = 0.0 ; //trace of strain - double senp1t[3][3]; - double V[3][3],EE[3][3]; - double dg[3],dgn[3],dgp[3]; - double diag; - double trans[3][3]; - double supp1[3][3],supp2[3][3]; - - // evaluate trace of elastic strain - trace=0.0; - for (int i=0;i<3;i++) - { - trace+=strain(i,i)-epsilon_p_n(i,i); // è corretta, non trial perché stato già COMMITED - }; - // Deviatoric strain tensor - for (int i=0;i<3;i++) - { - for (int j=0;j<3;j++) - dev_strain(i,j)=strain(i,j)-epsilon_p_n(i,j); - }; - for (int i=0;i<3;i++) - { - dev_strain(i,i)-= 1*trace/3; - }; - - // Deviatoric Stress - for (int i=0;i<3;i++) - { - for (int j=0;j<3;j++) - dev_stress(i,j)=dev_strain(i,j)*2.0*shear_p; // Strain(1,2) è epsilon12, per 2 = gamma12 - }; - - // Sigma Eff (n+1,Trial) = DevStress + I * K * trace(StrainElastic) - for (int i=0;i<3;i++) - { - for (int j=0;j<3;j++) - senp1t[i][j]=dev_stress(i,j); - }; - for (int i=0;i<3;i++) - senp1t[i][i]=senp1t[i][i]+bulk_p*trace; - - // Project in principal system - eigen_decomposition(senp1t,EE,V,dg); - - // Negative and Positive part of principal Effective Stress - for (int i=0;i<3;i++) { - dgn[i]=(dg[i]-fabs(dg[i]))/2; - dgp[i]=(dg[i]+fabs(dg[i]))/2; - } - diag=(dgp[0]+dgp[1]+dgp[2])*ni/(-E); - for (int i=0;i<3;i++) - { - for (int j=0;j<3;j++) - { - trans[i][j]=0.0; - if (i==j) // Diego!!!! - trans[i][i]=dgp[i]*(1+ni)/E+diag; - }; - }; - - // Reproject in local system - for (int i=0;i<3;i++) - { - for (int j=0;j<3;j++) - { - supp1[i][j]=0.0; - supp2[i][j]=0.0; - supp1[i][j]=supp1[i][j]+V[i][j]*dgn[j]; - supp2[i][j]=supp2[i][j]+V[i][j]*dgp[j]; - }; - }; - for (int i=0;i<3;i++) - { - for (int j=0;j<3;j++) - { - Dn[i][j]=0.0; - Dp[i][j]=0.0; - for (int k=0;k<3;k++) - { - Dn[i][j]=Dn[i][j]+supp1[i][k]*V[j][k]; - Dp[i][j]=Dp[i][j]+supp2[i][k]*V[j][k]; - }; - }; - }; - - tmp(0) = tmp(1) = 0.0; - for (int i = 0; i <3; i++) - { - for (int j = 0; j < 3; j++) - { - // Psi0- - tmp(0)+=Dn[i][j]*(strain(i,j)-epsilon_p_n(i,j)); - // Psi0+ - tmp(1)+=Dp[i][j]*(strain(i,j)-epsilon_p_n(i,j)); - } - } - tmp(0)*=0.5; - tmp(1)*=0.5; - - return tmp; -} - -const Vector & Concrete::getDamagedFreeEnergy() -{ - static Vector tmp(2); - const Vector &ElFreeEnergy = this->getElasticFreeEnergy(); - - tmp(0) = ElFreeEnergy(0) * (1-this->dn); - tmp(1) = ElFreeEnergy(1) * (1-this->dp); - - return tmp; -} diff --git a/SRC/material/nD/CycLiqCP.h b/SRC/material/nD/CycLiqCP.h index f2c259ffdd..69200a7e4a 100644 --- a/SRC/material/nD/CycLiqCP.h +++ b/SRC/material/nD/CycLiqCP.h @@ -40,7 +40,7 @@ #include #include -#include +//#include #include diff --git a/SRC/material/nD/CycLiqCP3D.h b/SRC/material/nD/CycLiqCP3D.h index 8a5939c60f..af49a18781 100644 --- a/SRC/material/nD/CycLiqCP3D.h +++ b/SRC/material/nD/CycLiqCP3D.h @@ -1,116 +1,115 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** ****************************************************************** */ - -// $Revision: 1 $ -// $Date: 2012-09-01 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/soil/CycLiqCP3D.h,v $ - -// Written: Rui Wang, Tsinghua University, September, 2012 -// -// Cyclic constitutive model for liquefaction of sand -// -// -// Please refer to Zhang and Wang, 2012 "Large post-liquefaction deformation of sand, part I: physical mechanism, constitutive description and numerical algorithm" -// Acta Geotechnica -// -// Cutting Plane Integration Scheme -// -// - -#ifndef CycLiqCP3D_h -#define CycLiqCP3D_h - - - -#include -#include -#include - -#include -#include -#include -#include - -#include - -class CycLiqCP3D : public CycLiqCP { - -//-------------------Declarations------------------------------- - - public : - - //null constructor - CycLiqCP3D() ; - - //full constructor - CycLiqCP3D( int tag, - double G01, - double kappa1, - double h1, - double Mfc1, //critical state - double dre11, - double Mdc1, - double dre21, - double rdr1, - double eta1, - double dir1, - double ein1, //initial void ratio - double rho1=0.0) ; - - //destructor - ~CycLiqCP3D( ) ; - - const char *getClassType(void) const {return "CycLiqCP3D";}; - - //make a clone of this material - NDMaterial* getCopy (); - - //send back type of material - const char* getType( ) const ; - - //send back order of strain in vector form - int getOrder( ) const ; - - //get the strain and integrate plasticity equations - int setTrialStrain( const Vector &strain_from_element) ; - - //unused trial strain functions - int setTrialStrain( const Vector &v, const Vector &r ) ; - int setTrialStrainIncr( const Vector &v ) ; - int setTrialStrainIncr( const Vector &v, const Vector &r ) ; - - //send back the strain - const Vector& getStrain( ) ; - - //send back the stress - const Vector& getStress( ) ; - - //send back the tangent - const Matrix& getTangent( ) ; - const Matrix& getInitialTangent( ) ; +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** ****************************************************************** */ + +// $Revision: 1 $ +// $Date: 2012-09-01 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/soil/CycLiqCP3D.h,v $ + +// Written: Rui Wang, Tsinghua University, September, 2012 +// +// Cyclic constitutive model for liquefaction of sand +// +// +// Please refer to Zhang and Wang, 2012 "Large post-liquefaction deformation of sand, part I: physical mechanism, constitutive description and numerical algorithm" +// Acta Geotechnica +// +// Cutting Plane Integration Scheme +// +// + +#ifndef CycLiqCP3D_h +#define CycLiqCP3D_h + + + +#include +#include +#include + +#include +#include +#include + +#include + +class CycLiqCP3D : public CycLiqCP { + +//-------------------Declarations------------------------------- + + public : + + //null constructor + CycLiqCP3D() ; + + //full constructor + CycLiqCP3D( int tag, + double G01, + double kappa1, + double h1, + double Mfc1, //critical state + double dre11, + double Mdc1, + double dre21, + double rdr1, + double eta1, + double dir1, + double ein1, //initial void ratio + double rho1=0.0) ; + + //destructor + ~CycLiqCP3D( ) ; + + const char *getClassType(void) const {return "CycLiqCP3D";}; + + //make a clone of this material + NDMaterial* getCopy (); + + //send back type of material + const char* getType( ) const ; + + //send back order of strain in vector form + int getOrder( ) const ; + + //get the strain and integrate plasticity equations + int setTrialStrain( const Vector &strain_from_element) ; + + //unused trial strain functions + int setTrialStrain( const Vector &v, const Vector &r ) ; + int setTrialStrainIncr( const Vector &v ) ; + int setTrialStrainIncr( const Vector &v, const Vector &r ) ; + + //send back the strain + const Vector& getStrain( ) ; + + //send back the stress + const Vector& getStress( ) ; + + //send back the tangent + const Matrix& getTangent( ) ; + const Matrix& getInitialTangent( ) ; int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, - FEM_ObjectBroker &theBroker); - - private: - - //static vectors and matrices sent back in get functions - static Vector strain_vec ; //strain in vector notation - static Vector stress_vec ; //stress in vector notation - static Matrix tangent_matrix ; //material tangent in matrix notation - -} ; //end of CycLiqCP declarations - -#endif + FEM_ObjectBroker &theBroker); + + private: + + //static vectors and matrices sent back in get functions + static Vector strain_vec ; //strain in vector notation + static Vector stress_vec ; //stress in vector notation + static Matrix tangent_matrix ; //material tangent in matrix notation + +} ; //end of CycLiqCP declarations + +#endif diff --git a/SRC/material/nD/CycLiqCPPlaneStrain.cpp b/SRC/material/nD/CycLiqCPPlaneStrain.cpp index 602d030e84..a573a6befc 100644 --- a/SRC/material/nD/CycLiqCPPlaneStrain.cpp +++ b/SRC/material/nD/CycLiqCPPlaneStrain.cpp @@ -310,4 +310,4 @@ CycLiqCPPlaneStrain::recvSelf (int commitTag, Channel &theChannel, return 0; -} \ No newline at end of file +} diff --git a/SRC/material/nD/CycLiqCPPlaneStrain.h b/SRC/material/nD/CycLiqCPPlaneStrain.h index 6061e52b64..5eafb5fa10 100644 --- a/SRC/material/nD/CycLiqCPPlaneStrain.h +++ b/SRC/material/nD/CycLiqCPPlaneStrain.h @@ -1,116 +1,116 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** ****************************************************************** */ - -// $Revision: 1 $ -// $Date: 2012-09-01 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/soil/CycLiqCPPlaneStrain.h,v $ - -// Written: Rui Wang, Tsinghua University, September, 2012 -// -// Cyclic constitutive model for liquefaction of sand -// -// -// Please refer to Zhang and Wang, 2012 "Large post-liquefaction deformation of sand, part I: physical mechanism, constitutive description and numerical algorithm" -// Acta Geotechnica -// -// Cutting Plane Integration Scheme -// -// - -#ifndef CycLiqCPPlaneStrain_h -#define CycLiqCPPlaneStrain_h - - - -#include -#include -#include - -#include -#include -#include -#include - -#include - -class CycLiqCPPlaneStrain : public CycLiqCP { - -//-------------------Declarations------------------------------- - - public : - - //null constructor - CycLiqCPPlaneStrain() ; - - //full constructor - CycLiqCPPlaneStrain(int tag, - double G01, - double kappa1, - double h1, - double Mfc1, //critical state - double dre11, - double Mdc1, - double dre21, - double rdr1, - double eta1, - double dir1, - double ein1, //initial void ratio - double rho1=0.0) ; - - //destructor - ~CycLiqCPPlaneStrain( ) ; - - const char *getClassType(void) const {return "CycLiqCPPlaneStrain";}; - - //make a clone of this material - NDMaterial* getCopy (); - - //send back type of material - const char* getType( ) const ; - - //send back order of strain in vector form - int getOrder( ) const ; - - //get the strain and integrate plasticity equations - int setTrialStrain( const Vector &strain_from_element) ; - - //unused trial strain functions - int setTrialStrain( const Vector &v, const Vector &r ) ; - int setTrialStrainIncr( const Vector &v ) ; - int setTrialStrainIncr( const Vector &v, const Vector &r ) ; - - //send back the strain - const Vector& getStrain( ) ; - - //send back the stress - const Vector& getStress( ) ; - - //send back the tangent - const Matrix& getTangent( ) ; - const Matrix& getInitialTangent( ) ; +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** ****************************************************************** */ + +// $Revision: 1 $ +// $Date: 2012-09-01 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/soil/CycLiqCPPlaneStrain.h,v $ + +// Written: Rui Wang, Tsinghua University, September, 2012 +// +// Cyclic constitutive model for liquefaction of sand +// +// +// Please refer to Zhang and Wang, 2012 "Large post-liquefaction deformation of sand, part I: physical mechanism, constitutive description and numerical algorithm" +// Acta Geotechnica +// +// Cutting Plane Integration Scheme +// +// + +#ifndef CycLiqCPPlaneStrain_h +#define CycLiqCPPlaneStrain_h + + + +#include +#include +#include + +#include +#include +//#include +#include + +#include + +class CycLiqCPPlaneStrain : public CycLiqCP { + +//-------------------Declarations------------------------------- + + public : + + //null constructor + CycLiqCPPlaneStrain() ; + + //full constructor + CycLiqCPPlaneStrain(int tag, + double G01, + double kappa1, + double h1, + double Mfc1, //critical state + double dre11, + double Mdc1, + double dre21, + double rdr1, + double eta1, + double dir1, + double ein1, //initial void ratio + double rho1=0.0) ; + + //destructor + ~CycLiqCPPlaneStrain( ) ; + + const char *getClassType(void) const {return "CycLiqCPPlaneStrain";}; + + //make a clone of this material + NDMaterial* getCopy (); + + //send back type of material + const char* getType( ) const ; + + //send back order of strain in vector form + int getOrder( ) const ; + + //get the strain and integrate plasticity equations + int setTrialStrain( const Vector &strain_from_element) ; + + //unused trial strain functions + int setTrialStrain( const Vector &v, const Vector &r ) ; + int setTrialStrainIncr( const Vector &v ) ; + int setTrialStrainIncr( const Vector &v, const Vector &r ) ; + + //send back the strain + const Vector& getStrain( ) ; + + //send back the stress + const Vector& getStress( ) ; + + //send back the tangent + const Matrix& getTangent( ) ; + const Matrix& getInitialTangent( ) ; int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, - FEM_ObjectBroker &theBroker); - - private: - - //static vectors and matrices sent back in get functions - static Vector strain_vec ; //strain in vector notation - static Vector stress_vec ; //stress in vector notation - static Matrix tangent_matrix ; //material tangent in matrix notation - -} ; //end of CycLiqCPPlaneStrain declarations - -#endif + FEM_ObjectBroker &theBroker); + + private: + + //static vectors and matrices sent back in get functions + static Vector strain_vec ; //strain in vector notation + static Vector stress_vec ; //stress in vector notation + static Matrix tangent_matrix ; //material tangent in matrix notation + +} ; //end of CycLiqCPPlaneStrain declarations + +#endif diff --git a/SRC/material/nD/CycLiqCPSP.h b/SRC/material/nD/CycLiqCPSP.h index 3c62f0dd94..015e579e7c 100644 --- a/SRC/material/nD/CycLiqCPSP.h +++ b/SRC/material/nD/CycLiqCPSP.h @@ -38,7 +38,7 @@ #include #include -#include +//#include #include diff --git a/SRC/material/nD/CycLiqCPSP3D.h b/SRC/material/nD/CycLiqCPSP3D.h index b1ce69f03c..01583d97a7 100644 --- a/SRC/material/nD/CycLiqCPSP3D.h +++ b/SRC/material/nD/CycLiqCPSP3D.h @@ -1,121 +1,121 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** ****************************************************************** */ - -// $Revision: 1 $ -// $Date: 2012-09-01 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/soil/CycLiqCPSP3D.h,v $ - -// Written: Rui Wang, Tsinghua University, August, 2013 -// -// Cyclic constitutive model for post-liquefaction shear deformationof sand -// -// -// Cutting Plane Integration Scheme -// -// - -#ifndef CycLiqCPSP3D_h -#define CycLiqCPSP3D_h - - - -#include -#include -#include - -#include -#include -#include -#include - -#include - -class CycLiqCPSP3D : public CycLiqCPSP { - -//-------------------Declarations------------------------------- - - public : - - //null constructor - CycLiqCPSP3D() ; - - //full constructor - CycLiqCPSP3D( int tag, - double G01, - double kappa1, - double h1, - double Mfc1, //critical state - double dre11, - double Mdc1, - double dre21, - double rdr1, - double eta1, - double dir1, - double lamdac1, - double ksi1, - double e01, - double nb1, - double nd1, - double ein1, //initial void ratio - double rho1=0.0) ; - - //destructor - ~CycLiqCPSP3D( ) ; - - const char *getClassType(void) const {return "CycLiqCPSP3D";}; - - //make a clone of this material - NDMaterial* getCopy (); - - //send back type of material - const char* getType( ) const ; - - //send back order of strain in vector form - int getOrder( ) const ; - - //get the strain and integrate plasticity equations - int setTrialStrain( const Vector &strain_from_element) ; - - //unused trial strain functions - int setTrialStrain( const Vector &v, const Vector &r ) ; - int setTrialStrainIncr( const Vector &v ) ; - int setTrialStrainIncr( const Vector &v, const Vector &r ) ; - - //send back the strain - const Vector& getStrain( ) ; - - //send back the stress - const Vector& getStress( ) ; - - //send back the tangent - const Matrix& getTangent( ) ; - const Matrix& getInitialTangent( ) ; +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** ****************************************************************** */ + +// $Revision: 1 $ +// $Date: 2012-09-01 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/soil/CycLiqCPSP3D.h,v $ + +// Written: Rui Wang, Tsinghua University, August, 2013 +// +// Cyclic constitutive model for post-liquefaction shear deformationof sand +// +// +// Cutting Plane Integration Scheme +// +// + +#ifndef CycLiqCPSP3D_h +#define CycLiqCPSP3D_h + + + +#include +#include +#include + +#include +#include +//#include +#include + +#include + +class CycLiqCPSP3D : public CycLiqCPSP { + +//-------------------Declarations------------------------------- + + public : + + //null constructor + CycLiqCPSP3D() ; + + //full constructor + CycLiqCPSP3D( int tag, + double G01, + double kappa1, + double h1, + double Mfc1, //critical state + double dre11, + double Mdc1, + double dre21, + double rdr1, + double eta1, + double dir1, + double lamdac1, + double ksi1, + double e01, + double nb1, + double nd1, + double ein1, //initial void ratio + double rho1=0.0) ; + + //destructor + ~CycLiqCPSP3D( ) ; + + const char *getClassType(void) const {return "CycLiqCPSP3D";}; + + //make a clone of this material + NDMaterial* getCopy (); + + //send back type of material + const char* getType( ) const ; + + //send back order of strain in vector form + int getOrder( ) const ; + + //get the strain and integrate plasticity equations + int setTrialStrain( const Vector &strain_from_element) ; + + //unused trial strain functions + int setTrialStrain( const Vector &v, const Vector &r ) ; + int setTrialStrainIncr( const Vector &v ) ; + int setTrialStrainIncr( const Vector &v, const Vector &r ) ; + + //send back the strain + const Vector& getStrain( ) ; + + //send back the stress + const Vector& getStress( ) ; + + //send back the tangent + const Matrix& getTangent( ) ; + const Matrix& getInitialTangent( ) ; int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, - FEM_ObjectBroker &theBroker); - - - - - private: - - //static vectors and matrices sent back in get functions - static Vector strain_vec ; //strain in vector notation - static Vector stress_vec ; //stress in vector notation - static Matrix tangent_matrix ; //material tangent in matrix notation - -} ; //end of CycLiqCPSP declarations - -#endif + FEM_ObjectBroker &theBroker); + + + + + private: + + //static vectors and matrices sent back in get functions + static Vector strain_vec ; //strain in vector notation + static Vector stress_vec ; //stress in vector notation + static Matrix tangent_matrix ; //material tangent in matrix notation + +} ; //end of CycLiqCPSP declarations + +#endif diff --git a/SRC/material/nD/CycLiqCPSPPlaneStrain.h b/SRC/material/nD/CycLiqCPSPPlaneStrain.h index d8ccd476e2..9d660fa1a0 100644 --- a/SRC/material/nD/CycLiqCPSPPlaneStrain.h +++ b/SRC/material/nD/CycLiqCPSPPlaneStrain.h @@ -1,120 +1,120 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** ****************************************************************** */ - -// $Revision: 1 $ -// $Date: 2012-09-01 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/soil/CycLiqCPSPPlaneStrain.h,v $ - -// Written: Rui Wang, Tsinghua University, August, 2013 -// -// Cyclic constitutive model for post-liquefaction shear deformationof sand -// -// -// -// Cutting Plane Integration Scheme -// -// - -#ifndef CycLiqCPSPPlaneStrain_h -#define CycLiqCPSPPlaneStrain_h - - - -#include -#include -#include - -#include -#include -#include -#include - -#include - -class CycLiqCPSPPlaneStrain : public CycLiqCPSP { - -//-------------------Declarations------------------------------- - - public : - - //null constructor - CycLiqCPSPPlaneStrain() ; - - //full constructor - CycLiqCPSPPlaneStrain( int tag, - double G01, - double kappa1, - double h1, - double Mfc1, //critical state - double dre11, - double Mdc1, - double dre21, - double rdr1, - double eta1, - double dir1, - double lamdac1, - double ksi1, - double e01, - double nb1, - double nd1, - double ein1, //initial void ratio - double rho1=0.0) ; - - //destructor - ~CycLiqCPSPPlaneStrain( ) ; - - const char *getClassType(void) const {return "CycLiqCPSPPlaneStrain";}; - - //make a clone of this material - NDMaterial* getCopy (); - - //send back type of material - const char* getType( ) const ; - - //send back order of strain in vector form - int getOrder( ) const ; - - //get the strain and integrate plasticity equations - int setTrialStrain( const Vector &strain_from_element) ; - - //unused trial strain functions - int setTrialStrain( const Vector &v, const Vector &r ) ; - int setTrialStrainIncr( const Vector &v ) ; - int setTrialStrainIncr( const Vector &v, const Vector &r ) ; - - //send back the strain - const Vector& getStrain( ) ; - - //send back the stress - const Vector& getStress( ) ; - - //send back the tangent - const Matrix& getTangent( ) ; - const Matrix& getInitialTangent( ) ; +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** ****************************************************************** */ + +// $Revision: 1 $ +// $Date: 2012-09-01 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/soil/CycLiqCPSPPlaneStrain.h,v $ + +// Written: Rui Wang, Tsinghua University, August, 2013 +// +// Cyclic constitutive model for post-liquefaction shear deformationof sand +// +// +// +// Cutting Plane Integration Scheme +// +// + +#ifndef CycLiqCPSPPlaneStrain_h +#define CycLiqCPSPPlaneStrain_h + + + +#include +#include +#include + +#include +#include +//#include +#include + +#include + +class CycLiqCPSPPlaneStrain : public CycLiqCPSP { + +//-------------------Declarations------------------------------- + + public : + + //null constructor + CycLiqCPSPPlaneStrain() ; + + //full constructor + CycLiqCPSPPlaneStrain( int tag, + double G01, + double kappa1, + double h1, + double Mfc1, //critical state + double dre11, + double Mdc1, + double dre21, + double rdr1, + double eta1, + double dir1, + double lamdac1, + double ksi1, + double e01, + double nb1, + double nd1, + double ein1, //initial void ratio + double rho1=0.0) ; + + //destructor + ~CycLiqCPSPPlaneStrain( ) ; + + const char *getClassType(void) const {return "CycLiqCPSPPlaneStrain";}; + + //make a clone of this material + NDMaterial* getCopy (); + + //send back type of material + const char* getType( ) const ; + + //send back order of strain in vector form + int getOrder( ) const ; + + //get the strain and integrate plasticity equations + int setTrialStrain( const Vector &strain_from_element) ; + + //unused trial strain functions + int setTrialStrain( const Vector &v, const Vector &r ) ; + int setTrialStrainIncr( const Vector &v ) ; + int setTrialStrainIncr( const Vector &v, const Vector &r ) ; + + //send back the strain + const Vector& getStrain( ) ; + + //send back the stress + const Vector& getStress( ) ; + + //send back the tangent + const Matrix& getTangent( ) ; + const Matrix& getInitialTangent( ) ; int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, - FEM_ObjectBroker &theBroker); - - - private: - - //static vectors and matrices sent back in get functions - static Vector strain_vec ; //strain in vector notation - static Vector stress_vec ; //stress in vector notation - static Matrix tangent_matrix ; //material tangent in matrix notation - -} ; //end of CycLiqCPSPPlaneStrain declarations - -#endif + FEM_ObjectBroker &theBroker); + + + private: + + //static vectors and matrices sent back in get functions + static Vector strain_vec ; //strain in vector notation + static Vector stress_vec ; //stress in vector notation + static Matrix tangent_matrix ; //material tangent in matrix notation + +} ; //end of CycLiqCPSPPlaneStrain declarations + +#endif diff --git a/SRC/material/nD/IncrementalElasticIsotropicThreeDimensional.cpp b/SRC/material/nD/IncrementalElasticIsotropicThreeDimensional.cpp new file mode 100644 index 0000000000..87753db450 --- /dev/null +++ b/SRC/material/nD/IncrementalElasticIsotropicThreeDimensional.cpp @@ -0,0 +1,459 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +#include +#include +#include +#include +#include + +bool IncrementalElasticIsotropicThreeDimensional::printnow = true; +// Vector IncrementalElasticIsotropicThreeDimensional::sigma(6); +Matrix IncrementalElasticIsotropicThreeDimensional::D(6,6); + +void *OPS_IncrementalElasticIsotropicThreeDimensional(void) +{ + NDMaterial *theMaterial = 0; + + int numArgs = OPS_GetNumRemainingInputArgs(); + + + if (numArgs < 3) { + opserr << "Want: nDMaterial IncrementalElasticIsotropic3D $tag $E $V <$rho>" << endln; + return 0; + } + + int iData[1]; + double dData[3]; + dData[2] = 0.0; + + int numData = 1; + if (OPS_GetInt(&numData, iData) != 0) { + opserr << "WARNING invalid integer tag: nDMaterial IncrementalElasticIsotropic3D \n"; + return 0; + } + + if (numArgs > 3) + numData = 3; + else + numData = 2; + + if (OPS_GetDouble(&numData, dData) != 0) { + opserr << "WARNING invalid data: nDMaterial IncrementalElasticIsotropic3D : " << iData[0] <<"\n"; + return 0; + } + + theMaterial = new IncrementalElasticIsotropicThreeDimensional(iData[0], dData[0], dData[1], dData[2]); + + return theMaterial; +} + + + +IncrementalElasticIsotropicThreeDimensional::IncrementalElasticIsotropicThreeDimensional(int tag, double E, double nu, double rho) : + ElasticIsotropicMaterial (tag, ND_TAG_IncrementalElasticIsotropicThreeDimensional, E, nu, rho), + epsilon(6), epsilon_n(6), sigma(6), sigma_n(6) +{ + epsilon.Zero(); + sigma.Zero(); + sigma_n.Zero(); + epsilon_n.Zero(); +} + +IncrementalElasticIsotropicThreeDimensional::IncrementalElasticIsotropicThreeDimensional(): + ElasticIsotropicMaterial (0, ND_TAG_IncrementalElasticIsotropicThreeDimensional, 0.0, 0.0), + epsilon(6), epsilon_n(6), sigma(6), sigma_n(6) +{ + epsilon.Zero(); + sigma.Zero(); + sigma_n.Zero(); + epsilon_n.Zero(); +} + +IncrementalElasticIsotropicThreeDimensional::~IncrementalElasticIsotropicThreeDimensional () +{ + +} + +int +IncrementalElasticIsotropicThreeDimensional::setTrialStrain (const Vector &strain) +{ + epsilon = strain; + + // static Vector depsilon(6); + // depsilon.Zero(); + + // sigma = sigma_n; + + + // depsilon = epsilon - epsilon_n; + + // double mu2 = E/(1.0+v); + // double lam = v*mu2/(1.0-2.0*v); + // double mu = 0.50*mu2; + // mu2 += lam; + + // double deps0 = depsilon(0); + // double deps1 = depsilon(1); + // double deps2 = depsilon(2); + + // D(0,0) = D(1,1) = D(2,2) = mu2; + // D(0,1) = D(1,0) = D(0,2) = D(2,0) = D(1,2) = D(2,1) = lam; + // D(3,3) = mu; + // D(4,4) = mu; + // D(5,5) = mu; + + // //dsigma = D*depsilon; + // sigma(0) = sigma(0) + mu2*deps0 + lam*(deps1 + deps2); + // sigma(1) = sigma(1) + mu2*deps1 + lam*(deps0 + deps2); + // sigma(2) = sigma(2) + mu2*deps2 + lam*(deps0 + deps1); + // sigma(3) = sigma(3) + mu*depsilon(3); + // sigma(4) = sigma(4) + mu*depsilon(4); + // sigma(5) = sigma(5) + mu*depsilon(5); + + return 0; +} + +int +IncrementalElasticIsotropicThreeDimensional::setTrialStrain (const Vector &strain, const Vector &rate) +{ + epsilon = strain; + + // static Vector depsilon(6); + // depsilon.Zero(); + + // sigma = sigma_n; + + + // depsilon = epsilon - epsilon_n; + + // double mu2 = E/(1.0+v); + // double lam = v*mu2/(1.0-2.0*v); + // double mu = 0.50*mu2; + // mu2 += lam; + + // double deps0 = depsilon(0); + // double deps1 = depsilon(1); + // double deps2 = depsilon(2); + + // D(0,0) = D(1,1) = D(2,2) = mu2; + // D(0,1) = D(1,0) = D(0,2) = D(2,0) = D(1,2) = D(2,1) = lam; + // D(3,3) = mu; + // D(4,4) = mu; + // D(5,5) = mu; + + // //dsigma = D*depsilon; + // sigma(0) = sigma(0) + mu2*deps0 + lam*(deps1 + deps2); + // sigma(1) = sigma(1) + mu2*deps1 + lam*(deps0 + deps2); + // sigma(2) = sigma(2) + mu2*deps2 + lam*(deps0 + deps1); + // sigma(3) = sigma(3) + mu*depsilon(3); + // sigma(4) = sigma(4) + mu*depsilon(4); + // sigma(5) = sigma(5) + mu*depsilon(5); + + return 0; +} + +int +IncrementalElasticIsotropicThreeDimensional::setTrialStrainIncr (const Vector &strain) +{ + epsilon += strain; + return 0; +} + +int +IncrementalElasticIsotropicThreeDimensional::setTrialStrainIncr (const Vector &strain, const Vector &rate) +{ + epsilon += strain; + return 0; +} + +const Matrix& +IncrementalElasticIsotropicThreeDimensional::getTangent (void) +{ + double mu2 = E/(1.0+v); + double lam = v*mu2/(1.0-2.0*v); + double mu = 0.50*mu2; + mu2 += lam; + + D(0,0) = D(1,1) = D(2,2) = mu2; + D(0,1) = D(1,0) = D(0,2) = D(2,0) = D(1,2) = D(2,1) = lam; + D(3,3) = mu; + D(4,4) = mu; + D(5,5) = mu; + + return D; +} + +const Matrix& +IncrementalElasticIsotropicThreeDimensional::getInitialTangent (void) +{ + // return this->getTangent(); + double mu2 = E/(1.0+v); + double lam = v*mu2/(1.0-2.0*v); + double mu = 0.50*mu2; + mu2 += lam; + + D(0,0) = D(1,1) = D(2,2) = mu2; + D(0,1) = D(1,0) = D(0,2) = D(2,0) = D(1,2) = D(2,1) = lam; + D(3,3) = mu; + D(4,4) = mu; + D(5,5) = mu; + + return D; +} + +const Vector& +IncrementalElasticIsotropicThreeDimensional::getStress (void) +{ + static Vector depsilon(6); + depsilon.Zero(); + + sigma = sigma_n; + + depsilon = epsilon - epsilon_n; + + double mu2 = E/(1.0+v); + double lam = v*mu2/(1.0-2.0*v); + double mu = 0.50*mu2; + mu2 += lam; + + double deps0 = depsilon(0); + double deps1 = depsilon(1); + double deps2 = depsilon(2); + + D(0,0) = D(1,1) = D(2,2) = mu2; + D(0,1) = D(1,0) = D(0,2) = D(2,0) = D(1,2) = D(2,1) = lam; + D(3,3) = mu; + D(4,4) = mu; + D(5,5) = mu; + + //dsigma = D*depsilon; + sigma(0) = sigma(0) + mu2*deps0 + lam*(deps1 + deps2); + sigma(1) = sigma(1) + mu2*deps1 + lam*(deps0 + deps2); + sigma(2) = sigma(2) + mu2*deps2 + lam*(deps0 + deps1); + sigma(3) = sigma(3) + mu*depsilon(3); + sigma(4) = sigma(4) + mu*depsilon(4); + sigma(5) = sigma(5) + mu*depsilon(5); + + // if(printnow) + // { + // // opserr << " [[[[[[[[[ sigma = " << sigma << endln; + // printnow = false; + // } + + return sigma; +} + +const Vector& +IncrementalElasticIsotropicThreeDimensional::getStrain (void) +{ + return epsilon_n; +} + +int +IncrementalElasticIsotropicThreeDimensional::commitState (void) +{ + epsilon_n=epsilon; + sigma_n=sigma; + // printnow = true; + return 0; +} + +int +IncrementalElasticIsotropicThreeDimensional::revertToLastCommit (void) +{ + epsilon=epsilon_n; + sigma=sigma_n; + return 0; +} + +int +IncrementalElasticIsotropicThreeDimensional::revertToStart (void) +{ + epsilon.Zero(); + epsilon_n.Zero(); + sigma.Zero(); + sigma_n.Zero(); + return 0; +} + +NDMaterial* +IncrementalElasticIsotropicThreeDimensional::getCopy (void) +{ + IncrementalElasticIsotropicThreeDimensional *theCopy = + new IncrementalElasticIsotropicThreeDimensional (this->getTag(), E, v, rho); + + theCopy->epsilon = epsilon; + theCopy->epsilon_n = epsilon_n; + theCopy->sigma = sigma; + theCopy->sigma_n = sigma_n; + + return theCopy; +} + + +NDMaterial* +IncrementalElasticIsotropicThreeDimensional::getCopy (const char *type) +{ + return this->getCopy(); +} + +const char* +IncrementalElasticIsotropicThreeDimensional::getType (void) const +{ + return "ThreeDimensional"; +} + +int +IncrementalElasticIsotropicThreeDimensional::getOrder (void) const +{ + return 6; +} + +int +IncrementalElasticIsotropicThreeDimensional::sendSelf(int commitTag, Channel &theChannel) +{ + static Vector data(28); + + data(0) = this->getTag(); + data(1) = E; + data(2) = v; + data(3) = rho; + data(4) = epsilon(0); + data(5) = epsilon(1); + data(6) = epsilon(2); + data(7) = epsilon(3); + data(8) = epsilon(4); + data(9) = epsilon(5); + data(10) = epsilon_n(0); + data(11) = epsilon_n(1); + data(12) = epsilon_n(2); + data(13) = epsilon_n(3); + data(14) = epsilon_n(4); + data(15) = epsilon_n(5); + data(16) = sigma(0); + data(17) = sigma(1); + data(18) = sigma(2); + data(19) = sigma(3); + data(20) = sigma(4); + data(21) = sigma(5); + data(22) = sigma_n(0); + data(23) = sigma_n(1); + data(24) = sigma_n(2); + data(25) = sigma_n(3); + data(26) = sigma_n(4); + data(27) = sigma_n(5); + + int res = theChannel.sendVector(this->getDbTag(), commitTag, data); + if (res < 0) { + opserr << "IncrementalElasticIsotropicThreeDimensional::sendSelf -- could not send Vector\n"; + return res; + } + + return res; +} + +int +IncrementalElasticIsotropicThreeDimensional::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + static Vector data(28); + + int res = theChannel.recvVector(this->getDbTag(), commitTag, data); + if (res < 0) { + opserr << "IncrementalElasticIsotropicThreeDimensional::sendSelf -- could not send Vector\n"; + return res; + } + + this->setTag((int)data(0)); + E = data(1); + v = data(2); + rho = data(3); + + epsilon(0) = data(4) ; + epsilon(1) = data(5) ; + epsilon(2) = data(6) ; + epsilon(3) = data(7) ; + epsilon(4) = data(8) ; + epsilon(5) = data(9) ; + epsilon_n(0) = data(10) ; + epsilon_n(1) = data(11) ; + epsilon_n(2) = data(12) ; + epsilon_n(3) = data(13) ; + epsilon_n(4) = data(14) ; + epsilon_n(5) = data(15) ; + sigma(0) = data(16) ; + sigma(1) = data(17) ; + sigma(2) = data(18) ; + sigma(3) = data(19) ; + sigma(4) = data(20) ; + sigma(5) = data(21) ; + sigma_n(0) = data(22) ; + sigma_n(1) = data(23) ; + sigma_n(2) = data(24) ; + sigma_n(3) = data(25) ; + sigma_n(4) = data(26) ; + sigma_n(5) = data(27) ; + + return res; +} + + +const Vector& +IncrementalElasticIsotropicThreeDimensional::getStressSensitivity(int gradIndex, + bool conditional) +{ + sigma.Zero(); + + return sigma; +} + + +Response* +IncrementalElasticIsotropicThreeDimensional::setResponse (const char **argv, int argc, OPS_Stream &output) +{ + if (strcmp(argv[0],"stress") == 0 || strcmp(argv[0],"stresses") == 0) + { + return new MaterialResponse(this, 1, this->getStress()); + } + else if (strcmp(argv[0],"strain") == 0 || strcmp(argv[0],"strains") == 0) + return new MaterialResponse(this, 2, this->getStrain()); + else + return 0; +} + +int +IncrementalElasticIsotropicThreeDimensional::getResponse(int responseID, Information &matInfo) +{ + switch (responseID) { + case -1: + return -1; + case 1: + if (matInfo.theVector != 0) + *(matInfo.theVector) = getStress(); + return 0; + case 2: + if (matInfo.theVector != 0) + *(matInfo.theVector) = getStrain(); + return 0; + default: + return -1; + } +} \ No newline at end of file diff --git a/SRC/material/nD/IncrementalElasticIsotropicThreeDimensional.h b/SRC/material/nD/IncrementalElasticIsotropicThreeDimensional.h new file mode 100644 index 0000000000..ed28f71cb6 --- /dev/null +++ b/SRC/material/nD/IncrementalElasticIsotropicThreeDimensional.h @@ -0,0 +1,94 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.6 $ +// $Date: 2006-08-04 18:18:37 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/ElasticIsotropicPlaneStress2D.h,v $ + +#ifndef IncrementalElasticIsotropicThreeDimensional_h +#define IncrementalElasticIsotropicThreeDimensional_h + +// Written: fmk +// Created: 10/11 +// +// Description: +// +// What: "@(#) ElasticIsotropicThreeDimesnional.h, revA" + +#include + +#include +#include +#include + +class IncrementalElasticIsotropicThreeDimensional : public ElasticIsotropicMaterial +{ + public: + IncrementalElasticIsotropicThreeDimensional(int tag, double E, double nu, double rho); + IncrementalElasticIsotropicThreeDimensional(); + ~IncrementalElasticIsotropicThreeDimensional(); + + const char *getClassType(void) const {return "IncrementalElasticIsotropicThreeDimensional";}; + + int setTrialStrain (const Vector &v); + int setTrialStrain (const Vector &v, const Vector &r); + int setTrialStrainIncr (const Vector &v); + int setTrialStrainIncr (const Vector &v, const Vector &r); + const Matrix &getTangent (void); + const Matrix &getInitialTangent (void); + + const Vector &getStress (void); + const Vector &getStrain (void); + + int commitState (void); + int revertToLastCommit (void); + int revertToStart (void); + + NDMaterial *getCopy (void); + virtual NDMaterial *getCopy (const char *type); + + const char *getType (void) const; + int getOrder (void) const; + + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + + Response *setResponse (const char **argv, int argc, OPS_Stream &output); + int getResponse (int responseID, Information &matInformation); + + + const Vector& getStressSensitivity(int gradIndex, + bool conditional); + + + protected: + + private: + static Matrix D; // Elastic constants + Vector epsilon; // Trial strains + Vector epsilon_n; // Committed strain + Vector sigma; // Trial stress vector + Vector sigma_n; // Committed stress + + static bool printnow; +}; + +#endif diff --git a/SRC/material/nD/J2PlaneStress.cpp b/SRC/material/nD/J2PlaneStress.cpp index 46c8e2fbd1..7a3c03fb5a 100644 --- a/SRC/material/nD/J2PlaneStress.cpp +++ b/SRC/material/nD/J2PlaneStress.cpp @@ -123,7 +123,7 @@ int J2PlaneStress :: getOrder( ) const //get the strain and integrate plasticity equations int J2PlaneStress :: setTrialStrain( const Vector &strain_from_element ) { - const double tolerance = 1e-12 ; + const double tolerance = (1.0e-8)*sigma_0 ; const int max_iterations = 25 ; int iteration_counter = 0 ; diff --git a/SRC/material/nD/Makefile b/SRC/material/nD/Makefile index b82825fdcf..71316ff9f5 100644 --- a/SRC/material/nD/Makefile +++ b/SRC/material/nD/Makefile @@ -41,6 +41,7 @@ OBJS = NDMaterial.o \ ElasticIsotropicPlaneStress2D.o \ ElasticIsotropicPlateFiber.o \ ElasticIsotropicThreeDimensional.o \ + IncrementalElasticIsotropicThreeDimensional.o \ ElasticOrthotropicMaterial.o \ ElasticOrthotropicThreeDimensional.o \ PressureDependentElastic3D.o \ diff --git a/SRC/material/nD/NDMaterial.cpp b/SRC/material/nD/NDMaterial.cpp index 6753017160..90cde0751c 100644 --- a/SRC/material/nD/NDMaterial.cpp +++ b/SRC/material/nD/NDMaterial.cpp @@ -208,8 +208,6 @@ NDMaterial::getStrain(void) return errVector; } - - //Functions for obtaining and updating temperature-dependent information Added by L.Jiang [SIF] double NDMaterial::getThermalTangentAndElongation(double &TempT, double &ET, double &Elong) @@ -234,8 +232,7 @@ NDMaterial::getTempAndElong() //end of adding thermo-mechanical functions, L.Jiang [SIF] Response* -NDMaterial::setResponse (const char **argv, int argc, - OPS_Stream &output) +NDMaterial::setResponse (const char **argv, int argc, OPS_Stream &output) { Response *theResponse =0; const char *matType = this->getType(); @@ -297,14 +294,19 @@ NDMaterial::setResponse (const char **argv, int argc, } //opserr<<"tempElong "<getTempAndElong()<getTempAndElong()); - } + //end of adding output request,L.Jiang [SIF] else if (strcmp(argv[0], "Tangent") == 0 || strcmp(argv[0], "tangent") == 0) { const Matrix &res = this->getTangent(); theResponse = new MaterialResponse(this, 4, this->getTangent()); - } - //end of adding output request,L.Jiang [SIF] + //default damage output - added by V.K. Papanikolaou [AUTh] - start + else if (strcmp(argv[0], "Damage") == 0 || strcmp(argv[0], "damage") == 0) { + static Vector vec = Vector(3); + for (int i = 0; i < 3; i++) vec[i] = 0; + theResponse = new MaterialResponse(this, 5, vec); // zero vector + } + //default damage output - added by V.K. Papanikolaou [AUTh] - end output.endTag(); // NdMaterialOutput @@ -326,8 +328,6 @@ NDMaterial::getResponse (int responseID, Information &matInfo) } } - - // AddingSensitivity:BEGIN //////////////////////////////////////// const Vector & NDMaterial::getStressSensitivity(int gradIndex, bool conditional) @@ -355,18 +355,21 @@ NDMaterial::getDampTangentSensitivity(int gradIndex) static Matrix dummy(1,1); return dummy; } + const Matrix & NDMaterial::getTangentSensitivity(int gradIndex) { static Matrix dummy(1,1); return dummy; } + const Matrix & NDMaterial::getInitialTangentSensitivity(int gradIndex) { static Matrix dummy(1,1); return dummy; } + int NDMaterial::commitSensitivity(const Vector & strainSensitivity, int gradIndex, int numGrads) { diff --git a/SRC/material/nD/NDMaterial.h b/SRC/material/nD/NDMaterial.h index 59e1ebde8e..007f4fde63 100644 --- a/SRC/material/nD/NDMaterial.h +++ b/SRC/material/nD/NDMaterial.h @@ -82,19 +82,18 @@ class NDMaterial : public Material virtual const char *getType(void) const = 0; virtual int getOrder(void) const {return 0;}; //?? - virtual Response *setResponse (const char **argv, int argc, - OPS_Stream &s); + virtual Response *setResponse (const char **argv, int argc, OPS_Stream &s); virtual int getResponse (int responseID, Information &matInformation); -// AddingSensitivity:BEGIN ////////////////////////////////////////// - virtual const Vector & getStressSensitivity (int gradIndex, bool conditional); - virtual const Vector & getStrainSensitivity (int gradIndex); - virtual const Matrix & getTangentSensitivity (int gradIndex); - virtual const Matrix & getInitialTangentSensitivity (int gradIndex); - virtual const Matrix & getDampTangentSensitivity(int gradIndex); - virtual double getRhoSensitivity (int gradIndex); - virtual int commitSensitivity (const Vector & strainGradient, int gradIndex, int numGrads); -// AddingSensitivity:END /////////////////////////////////////////// + // AddingSensitivity:BEGIN ////////////////////////////////////////// + virtual const Vector & getStressSensitivity (int gradIndex, bool conditional); + virtual const Vector & getStrainSensitivity (int gradIndex); + virtual const Matrix & getTangentSensitivity (int gradIndex); + virtual const Matrix & getInitialTangentSensitivity (int gradIndex); + virtual const Matrix & getDampTangentSensitivity (int gradIndex); + virtual double getRhoSensitivity (int gradIndex); + virtual int commitSensitivity (const Vector & strainGradient, int gradIndex, int numGrads); + // AddingSensitivity:END /////////////////////////////////////////// protected: diff --git a/SRC/material/nD/PlaneStressUserMaterial.cpp b/SRC/material/nD/PlaneStressUserMaterial.cpp index aa977e4fb3..a56c9bb683 100644 --- a/SRC/material/nD/PlaneStressUserMaterial.cpp +++ b/SRC/material/nD/PlaneStressUserMaterial.cpp @@ -373,68 +373,117 @@ PlaneStressUserMaterial::sendSelf(int commitTag, Channel &theChannel) } int -PlaneStressUserMaterial::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +PlaneStressUserMaterial::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) { - int res = 0; + int res = 0; - int dataTag = this->getDbTag(); + int dataTag = this->getDbTag(); - static ID idData(3); + static ID idData(3); - res = theChannel.recvID(dataTag, commitTag, idData); - if (res < 0) { - opserr << "PlaneStressUserMaterial::recvSelf -- could not recv ID" << endln; - return res; - } + res = theChannel.recvID(dataTag, commitTag, idData); + if (res < 0) { + opserr << "PlaneStressUserMaterial::recvSelf -- could not recv ID" << endln; + return res; + } - this->setTag(idData(0)); - - if (nstatevs != idData(1)) - { - nstatevs = idData(1); - if (statev0 != 0) delete statev0; - statev0 = new Vector(nstatevs); - if (statev != 0) delete statev; - statev = new Vector(nstatevs); - if (statevdata != 0) delete statevdata; - statevdata = new double[nstatevs]; - } - - if (nprops != idData(2)) + this->setTag(idData(0)); + + if (nstatevs != idData(1)) + { + nstatevs = idData(1); + if (statev0 != 0) delete statev0; + statev0 = new Vector(nstatevs); + if (statev != 0) delete statev; + statev = new Vector(nstatevs); + if (statevdata != 0) delete statevdata; + statevdata = new double[nstatevs]; + } + + if (nprops != idData(2)) + { + nprops = idData(2); + if (vprops != 0) delete vprops; + vprops = new Vector(nprops); + if (props != 0) delete props; + props = new double[nprops]; + } + + res = theChannel.recvVector(dataTag, commitTag, strain0); + if (res < 0) { + opserr << "PlaneStressUserMaterial::recvSelf -- could not recv data" << endln; + return res; + } + + res = theChannel.recvVector(dataTag, commitTag, stress0); + if (res < 0) { + opserr << "PlaneStressUserMaterial::recvSelf -- could not recv data" << endln; + return res; + } + + res = theChannel.recvVector(dataTag, commitTag, *statev0); + if (res < 0) { + opserr << "PlaneStressUserMaterial::recvSelf -- could not recv data" << endln; + return res; + } + + res = theChannel.recvVector(dataTag, commitTag, *vprops); + if (res < 0) { + opserr << "PlaneStressUserMaterial::recvSelf -- could not recv data" << endln; + return res; + } + + setInitials(); + + return res; +} + + //cracking output - added by V.K. Papanikolaou [AUTh] - start + const Vector& PlaneStressUserMaterial::getCracking() { - nprops = idData(2); - if (vprops != 0) delete vprops; - vprops = new Vector(nprops); - if (props != 0) delete props; - props = new double[nprops]; - } + static Vector vec = Vector(3); - res = theChannel.recvVector(dataTag, commitTag, strain0); - if (res < 0) { - opserr << "PlaneStressUserMaterial::recvSelf -- could not recv data" << endln; - return res; - } + vec(0) = statevdata[27]; // crack 0/1 in direction 1 - res = theChannel.recvVector(dataTag, commitTag, stress0); - if (res < 0) { - opserr << "PlaneStressUserMaterial::recvSelf -- could not recv data" << endln; - return res; - } + if ((vec(0) != 0) && (vec(0) != 1)) vec(0) = 0; // clean unwanted values + + vec(1) = statevdata[38]; // crack 0/1 in direction 2 + + if ((vec(1) != 0) && (vec(1) != 1)) vec(1) = 0; // clean unwanted values + + vec(2) = statevdata[15] * 180 / 3.14159; // crack angle (degrees) - res = theChannel.recvVector(dataTag, commitTag, *statev0); - if (res < 0) { - opserr << "PlaneStressUserMaterial::recvSelf -- could not recv data" << endln; - return res; + vec(2) = (int)(vec(2) * 100.0) / 100.0; // round to 2 decimals + + if (vec(2) >= 360) vec(2) -= 360; // fix angle for over 360 degrees + + if ((vec(0) == 0) && (vec(1) == 0)) vec(2) = 0; // zero angle for no cracking + + return vec; } + //cracking output - added by V.K. Papanikolaou [AUTh] - end + + //set/getresponse - added by V.K. Papanikolaou [AUTh] - start + Response* + PlaneStressUserMaterial::setResponse(const char** argv, int argc, OPS_Stream& output) + { + Response* theResponse = 0; + const Vector& res = this->getCracking(); + theResponse = new MaterialResponse(this, 1, res); - res = theChannel.recvVector(dataTag, commitTag, *vprops); - if (res < 0) { - opserr << "PlaneStressUserMaterial::recvSelf -- could not recv data" << endln; - return res; + return theResponse; } - setInitials(); + int + PlaneStressUserMaterial::getResponse(int responseID, Information & matInfo) + { + switch (responseID) { + case 1: + return matInfo.setVector(this->getCracking()); - return res; -} + default: + return -1; + } + } + //set/getResponse - added by V.K. Papanikolaou [AUTh] - end diff --git a/SRC/material/nD/PlaneStressUserMaterial.h b/SRC/material/nD/PlaneStressUserMaterial.h index 60355200ae..dc3d2ef13e 100644 --- a/SRC/material/nD/PlaneStressUserMaterial.h +++ b/SRC/material/nD/PlaneStressUserMaterial.h @@ -87,6 +87,15 @@ class PlaneStressUserMaterial: public NDMaterial{ int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + //cracking output - added by V.K. Papanikolaou [AUTh] - start + const Vector& getCracking(); + //cracking output - added by V.K. Papanikolaou [AUTh] - end + + //set/getResponse - added by V.K. Papanikolaou [AUTh] - start + Response* setResponse(const char** argv, int argc, OPS_Stream& s); + int getResponse(int responseID, Information& matInformation); + //set/getResponse - added by V.K. Papanikolaou [AUTh] - end + private : Vector strain0, strain, stress0, stress; Matrix tangent, eTangent; diff --git a/SRC/material/nD/PlateFromPlaneStressMaterial.cpp b/SRC/material/nD/PlateFromPlaneStressMaterial.cpp index f0e3ae797f..d6282b50c7 100644 --- a/SRC/material/nD/PlateFromPlaneStressMaterial.cpp +++ b/SRC/material/nD/PlateFromPlaneStressMaterial.cpp @@ -383,4 +383,26 @@ PlateFromPlaneStressMaterial::recvSelf(int commitTag, Channel &theChannel, FEM_O return res; } - + +//setResponse - added by V.K. Papanikolaou [AUTh] - start +Response* +PlateFromPlaneStressMaterial::setResponse(const char** argv, int argc, OPS_Stream& output) +{ + if (strcmp(argv[0], "Tangent") == 0 || strcmp(argv[0], "tangent") == 0 || + strcmp(argv[0], "stress") == 0 || strcmp(argv[0], "stresses") == 0 || + strcmp(argv[0], "strain") == 0 || strcmp(argv[0], "strains") == 0) { + + return NDMaterial::setResponse(argv, argc, output); // for stresses/strains, get response from NDMaterial + } + + // for material-specific output + + Response *theResponse = 0; + theResponse = theMat->setResponse(argv, argc, output); + + if (theResponse == 0) + return NDMaterial::setResponse(argv, argc, output); // not implemented, get default (zero) response from NDMaterial + + return theResponse; // implemented, get damage response from theMat +} +//setResponse - added by V.K. Papanikolaou [AUTh] - end diff --git a/SRC/material/nD/PlateFromPlaneStressMaterial.h b/SRC/material/nD/PlateFromPlaneStressMaterial.h index 7ea34094f6..4e562cc2d8 100644 --- a/SRC/material/nD/PlateFromPlaneStressMaterial.h +++ b/SRC/material/nD/PlateFromPlaneStressMaterial.h @@ -92,6 +92,10 @@ class PlateFromPlaneStressMaterial: public NDMaterial{ int sendSelf(int commitTag, Channel &theChannel); int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + //setResponse - added by V.K. Papanikolaou [AUTh] - start + Response* setResponse(const char** argv, int argc, OPS_Stream& s); + //setResponse - added by V.K. Papanikolaou [AUTh] - end + private : NDMaterial *theMat ; //pointer to three dimensional material double gmod; diff --git a/SRC/material/nD/TclModelBuilderNDMaterialCommand.cpp b/SRC/material/nD/TclModelBuilderNDMaterialCommand.cpp index b56afafe5e..fa54b73b9f 100644 --- a/SRC/material/nD/TclModelBuilderNDMaterialCommand.cpp +++ b/SRC/material/nD/TclModelBuilderNDMaterialCommand.cpp @@ -95,6 +95,7 @@ extern void * OPS_NewPlasticDamageConcrete3d(void); extern void * OPS_NewPlasticDamageConcretePlaneStress(void); extern void *OPS_ElasticIsotropicMaterial(void); extern void *OPS_ElasticIsotropic3D(void); +extern void *OPS_IncrementalElasticIsotropicThreeDimensional(void); extern void *OPS_ElasticOrthotropicMaterial(void); extern void *OPS_DruckerPragerMaterial(void); extern void *OPS_BoundingCamClayMaterial(void); @@ -564,6 +565,16 @@ TclModelBuilderNDMaterialCommand (ClientData clientData, Tcl_Interp *interp, int return TCL_ERROR; } + else if ((strcmp(argv[1],"IncrementalElasticIsotropic3D") == 0) || (strcmp(argv[1],"incrementalElasticIsotropic3D") == 0)) { + + void *theMat = OPS_IncrementalElasticIsotropicThreeDimensional(); + if (theMat != 0) + theMaterial = (NDMaterial *)theMat; + else + return TCL_ERROR; + } + + else if (strcmp(argv[1],"PressureDependentElastic3D") == 0) { if (argc < 6) { opserr << "WARNING insufficient arguments\n"; diff --git a/SRC/material/nD/UWmaterials/BoundingCamClay3D.h b/SRC/material/nD/UWmaterials/BoundingCamClay3D.h index 5d248ae1a4..4c6eef9e50 100644 --- a/SRC/material/nD/UWmaterials/BoundingCamClay3D.h +++ b/SRC/material/nD/UWmaterials/BoundingCamClay3D.h @@ -33,7 +33,7 @@ #include #include -#include +#include "BoundingCamClay.h" class BoundingCamClay3D : public BoundingCamClay { diff --git a/SRC/material/nD/UWmaterials/BoundingCamClayPlaneStrain.h b/SRC/material/nD/UWmaterials/BoundingCamClayPlaneStrain.h index 7f4bea7758..a0f92af50f 100644 --- a/SRC/material/nD/UWmaterials/BoundingCamClayPlaneStrain.h +++ b/SRC/material/nD/UWmaterials/BoundingCamClayPlaneStrain.h @@ -29,7 +29,7 @@ #include #include -#include +#include "BoundingCamClay.h" class BoundingCamClayPlaneStrain : public BoundingCamClay { diff --git a/SRC/material/nD/UWmaterials/DruckerPrager3D.h b/SRC/material/nD/UWmaterials/DruckerPrager3D.h index 3e99523b73..45a48d0405 100644 --- a/SRC/material/nD/UWmaterials/DruckerPrager3D.h +++ b/SRC/material/nD/UWmaterials/DruckerPrager3D.h @@ -32,7 +32,7 @@ #include #include -#include +#include "DruckerPrager.h" class DruckerPrager3D : public DruckerPrager { diff --git a/SRC/material/nD/UWmaterials/DruckerPragerPlaneStrain.h b/SRC/material/nD/UWmaterials/DruckerPragerPlaneStrain.h index 17e198ec6d..a438d47e69 100644 --- a/SRC/material/nD/UWmaterials/DruckerPragerPlaneStrain.h +++ b/SRC/material/nD/UWmaterials/DruckerPragerPlaneStrain.h @@ -29,7 +29,7 @@ #include #include -#include +#include "DruckerPrager.h" class DruckerPragerPlaneStrain : public DruckerPrager { diff --git a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.cpp b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.cpp index 8b11bf5d8c..50fa9f415d 100644 --- a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.cpp +++ b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.cpp @@ -132,6 +132,53 @@ J2CyclicBoundingSurface::J2CyclicBoundingSurface(int tag, calcInitialTangent(); } +//full constructor +J2CyclicBoundingSurface::J2CyclicBoundingSurface(int tag, int classTag, + double G, + double K, + double su, + double rho, + double h, + double m, + double h0, + double chi, + double beta) + : + NDMaterial(tag, classTag), + m_sigma0_n(6), m_sigma0_np1(6), m_stress_n(6), m_stress_np1(6), m_strain_np1(6), + m_strain_n(6), m_strainRate_n(6), m_strainRate_n1(6), m_Cep(6, 6), m_Ce(6, 6), + m_D(6, 6), m_stress_vis_n(6), m_stress_vis_n1(6), m_stress_t_n1(6) +{ + double m_poiss = (3.*K - 2.*G) / 2. / (3. * K + G); + + if (m_poiss > 0.5) { + opserr << "\n ERROR! J2CyclicBoundingSurface Poiss can not be grater than 0.50!" << endln; + exit(-1); + return; + } + + m_su = su; + m_bulk = K; // E / 3 / (1-2*nu) + m_shear = G; // E / 2 / (1 + nu); + m_R = sqrt(8. / 3.)*su; + m_density = rho; + m_kappa_inf = 1.0e10; + m_h_par = h; + m_m_par = m; + m_h0_par = h0; + m_beta = beta; + m_kappa_n = m_kappa_inf; + m_kappa_np1 = m_kappa_inf; + m_psi_n = 2.*m_shear; + m_chi = chi; + + m_isElast2Plast = false; + debugFlag = false; + small = 1.0e-10; + + calcInitialTangent(); +} + //destructor J2CyclicBoundingSurface :: ~J2CyclicBoundingSurface() diff --git a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.h b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.h index 8b93c37379..43ea436af3 100644 --- a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.h +++ b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.h @@ -47,7 +47,7 @@ class J2CyclicBoundingSurface : public NDMaterial { J2CyclicBoundingSurface(); //full constructor - J2CyclicBoundingSurface(int tag, + J2CyclicBoundingSurface(int tag, double G, double K, double su, @@ -58,6 +58,16 @@ class J2CyclicBoundingSurface : public NDMaterial { double chi, double beta); + J2CyclicBoundingSurface(int tag, int classTag, + double G, + double K, + double su, + double rho, + double h, + double m, + double h0, + double chi, + double beta); //destructor virtual ~J2CyclicBoundingSurface(); diff --git a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.cpp b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.cpp new file mode 100644 index 0000000000..59ff7c992c --- /dev/null +++ b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.cpp @@ -0,0 +1,123 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// Written: UW Computational Geomechanics Group +// Pedro Arduino (*), ALborz Ghofrani(*) +// (*) University of Washington +// March 2020 +// +// Description: This file contains the implementation of the J2CyclicBoundingSurface3D class. +#include "J2CyclicBoundingSurface3D.h" + +// full constructor +J2CyclicBoundingSurface3D::J2CyclicBoundingSurface3D( int tag, double G, double K, double su, double rho, double h, double m, double h0, double chi, double beta) + :J2CyclicBoundingSurface (tag, ND_TAG_J2CyclicBoundingSurface3D, G, K, su, rho, h, m, h0, chi, beta) +{ +} + +// null constructor +J2CyclicBoundingSurface3D::J2CyclicBoundingSurface3D() + : J2CyclicBoundingSurface() +{ +} + +// destructor +J2CyclicBoundingSurface3D::~J2CyclicBoundingSurface3D() +{ +} + +// make a clone of this material +NDMaterial* +J2CyclicBoundingSurface3D::getCopy() +{ + J2CyclicBoundingSurface3D *clone; + clone = new J2CyclicBoundingSurface3D(); + *clone = *this; + return clone; +} + +// send back type of material +const char* +J2CyclicBoundingSurface3D::getType() const +{ + return "ThreeDimensional"; +} + +// send back order of strain +int +J2CyclicBoundingSurface3D::getOrder() const +{ + return 6; +} + +// get the strain and integrate plasticity equations +int +J2CyclicBoundingSurface3D::setTrialStrain(const Vector &strain_from_element) +{ + m_strain_np1 = strain_from_element; + this->integrate(); + + return 0; +} + +// unused trial strain functions +int +J2CyclicBoundingSurface3D::setTrialStrain(const Vector &v, const Vector &r) +{ + m_strainRate_n1 = r; + m_strain_np1 = v; + this->integrate(); + + return 0; +} + +// send back the strain +const Vector& +J2CyclicBoundingSurface3D::getStrain() +{ + return m_strain_np1; +} + +// send back the stress +const Vector& +J2CyclicBoundingSurface3D::getStress() +{ + //return m_stress_np1; + return m_stress_t_n1; +} + +// send back the tangent +const Matrix& +J2CyclicBoundingSurface3D::getTangent() +{ + Matrix C(6, 6); + C = J2CyclicBoundingSurface::getTangent(); + return C; +} + +// send back the tangent +const Matrix& +J2CyclicBoundingSurface3D::getInitialTangent() +{ + Matrix C(6, 6); + J2CyclicBoundingSurface::calcInitialTangent(); + C = m_Ce; + return C; +} \ No newline at end of file diff --git a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.h b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.h new file mode 100644 index 0000000000..dd26e4968d --- /dev/null +++ b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.h @@ -0,0 +1,74 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// Written: UW Computational Geomechanics Group +// Pedro Arduino (*), ALborz Ghofrani(*) +// (*) University of Washington +// March 2020 +// +// Description: This file contains the class definition for J2CyclicBoundingSurface3D. +#ifndef J2CyclicBoundingSurface3D_h +#define J2CyclicBoundingSurface3D_h + +#include +#include +#include + +#include + +class J2CyclicBoundingSurface3D : public J2CyclicBoundingSurface +{ + public : + + //full constructor + J2CyclicBoundingSurface3D(int tag, double G, double K, double su, double rho, double h, double m, double h0, double chi, double beta); + + //null constructor + J2CyclicBoundingSurface3D(); + + //destructor + ~J2CyclicBoundingSurface3D(); + + NDMaterial *getCopy(void); + const char *getType(void) const; + int getOrder(void) const; + + int setTrialStrain(const Vector &strain_from_element); + + // Unused trialStrain functions + int setTrialStrain(const Vector &v, const Vector &r); + + //send back the strain + const Vector& getStrain(); + + //send back the stress + const Vector& getStress(); + const Vector& getStressToRecord(); + + //send back the tangent + const Matrix& getTangent(); + const Matrix& getInitialTangent(); + + private : + +}; + + +#endif diff --git a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.cpp b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.cpp new file mode 100644 index 0000000000..e53eb0ff05 --- /dev/null +++ b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.cpp @@ -0,0 +1,158 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// Written: UW Computational Geomechanics Group +// Pedro Arduino (*), ALborz Ghofrani(*) +// (*) University of Washington +// March 2020 +// +// Description: This file contains the implementation of the ManzariDafaliasPlaneStrain class. + +#include "J2CyclicBoundingSurfacePlaneStrain.h" + +//static vectors and matrices +Vector J2CyclicBoundingSurfacePlaneStrain::strain(3); +Vector J2CyclicBoundingSurfacePlaneStrain::stress(3); +Matrix J2CyclicBoundingSurfacePlaneStrain::tangent(3, 3); + +// full constructor +J2CyclicBoundingSurfacePlaneStrain::J2CyclicBoundingSurfacePlaneStrain(int tag, double G, double K, double su, double rho, double h, double m, double h0, double chi, double beta) +:J2CyclicBoundingSurface(tag, ND_TAG_J2CyclicBoundingSurfacePlaneStrain, G, K, su, rho, h, m, h0, chi, beta) +{ +} + +// null constructor +J2CyclicBoundingSurfacePlaneStrain::J2CyclicBoundingSurfacePlaneStrain() + : J2CyclicBoundingSurface() +{ +} + +// destructor +J2CyclicBoundingSurfacePlaneStrain::~J2CyclicBoundingSurfacePlaneStrain() +{ +} + +// make a clone of this material +NDMaterial* +J2CyclicBoundingSurfacePlaneStrain::getCopy() +{ + J2CyclicBoundingSurfacePlaneStrain *clone; + clone = new J2CyclicBoundingSurfacePlaneStrain(); + *clone = *this; + return clone; +} + +// send back type of material +const char* +J2CyclicBoundingSurfacePlaneStrain::getType() const +{ + return "PlaneStrain"; +} + +// send back order of strain +int +J2CyclicBoundingSurfacePlaneStrain::getOrder() const +{ + return 3; +} + +// get the strain and integrate plasticity equations +int +J2CyclicBoundingSurfacePlaneStrain::setTrialStrain(const Vector &strain_from_element) +{ + m_strain_np1.Zero(); + m_strain_np1(0) = strain_from_element(0); + m_strain_np1(1) = strain_from_element(1); + m_strain_np1(3) = strain_from_element(2); + + this->integrate(); + + return 0; +} + +// unused trial strain functions +int +J2CyclicBoundingSurfacePlaneStrain::setTrialStrain(const Vector &v, const Vector &r) +{ + return this->setTrialStrain(v); +} + +// send back the strain +const Vector& +J2CyclicBoundingSurfacePlaneStrain::getStrain() +{ + strain(0) = m_strain_np1(0); + strain(1) = m_strain_np1(1); + strain(2) = m_strain_np1(3); + + return strain; +} + +// send back the stress +const Vector& +J2CyclicBoundingSurfacePlaneStrain::getStress() +{ + stress(0) = m_stress_t_n1(0); + stress(1) = m_stress_t_n1(1); + stress(2) = m_stress_t_n1(3); + + return stress; +} + +// send back the tangent +const Matrix& +J2CyclicBoundingSurfacePlaneStrain::getTangent() +{ + Matrix C(6,6); + C = J2CyclicBoundingSurface::getTangent(); + + tangent(0,0) = C(0,0); + tangent(0,1) = C(0,1); + tangent(0,2) = C(0,3); + tangent(1,0) = C(1,0); + tangent(1,1) = C(1,1); + tangent(1,2) = C(1,3); + tangent(2,0) = C(3,0); + tangent(2,1) = C(3,1); + tangent(2,2) = C(3,3); + + return tangent; +} + +// send back the tangent +const Matrix& +J2CyclicBoundingSurfacePlaneStrain::getInitialTangent() +{ + Matrix C(6, 6); + J2CyclicBoundingSurface::calcInitialTangent(); + C = m_Ce; + + tangent(0,0) = C(0,0); + tangent(0,1) = C(0,1); + tangent(0,2) = C(0,3); + tangent(1,0) = C(1,0); + tangent(1,1) = C(1,1); + tangent(1,2) = C(1,3); + tangent(2,0) = C(3,0); + tangent(2,1) = C(3,1); + tangent(2,2) = C(3,3); + + return tangent; +} diff --git a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.h b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.h new file mode 100644 index 0000000000..1fada49184 --- /dev/null +++ b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.h @@ -0,0 +1,81 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// Written: UW Computational Geomechanics Group +// Pedro Arduino (*), ALborz Ghofrani(*) +// (*) University of Washington +// March 2020 +// +// Description: This file contains the class definition for J2CyclicBoundingSurfacePlaneStrain. + +#ifndef J2CyclicBoundingSurfacePS_h +#define J2CyclicBoundingSurfacePS_h + +#include +#include +#include + +#include +#include +#include + +#include + +class J2CyclicBoundingSurfacePlaneStrain : public J2CyclicBoundingSurface +{ + public : + + //full constructor + J2CyclicBoundingSurfacePlaneStrain(int tag, double G, double K, double su, double rho, double h, double m, double h0, double chi, double beta); + + //null constructor + J2CyclicBoundingSurfacePlaneStrain(); + + //destructor + ~J2CyclicBoundingSurfacePlaneStrain(); + + NDMaterial *getCopy(void); + const char *getType(void) const; + int getOrder(void) const; + + int setTrialStrain(const Vector &strain_from_element); + + // Unused trialStrain functions + int setTrialStrain(const Vector &v, const Vector &r); + + //send back the strain + const Vector& getStrain(); + + //send back the stress + const Vector& getStress(); + + //send back the tangent + const Matrix& getTangent(); + const Matrix& getInitialTangent(); + + private : + + // static vectors and matrices + static Vector strain; + static Vector stress; + static Matrix tangent; +}; + +#endif diff --git a/SRC/material/nD/UWmaterials/Makefile b/SRC/material/nD/UWmaterials/Makefile index 854148d00d..08464240d8 100644 --- a/SRC/material/nD/UWmaterials/Makefile +++ b/SRC/material/nD/UWmaterials/Makefile @@ -17,7 +17,9 @@ OBJS = BoundingCamClay.o \ ManzariDafaliasPlaneStrainRO.o\ PM4Sand.o\ PM4Silt.o\ - J2CyclicBoundingSurface.o + J2CyclicBoundingSurface.o\ + J2CyclicBoundingSurface3D.o\ + J2CyclicBoundingSurfacePlaneStrain.o all: $(OBJS) diff --git a/SRC/material/nD/UWmaterials/ManzariDafalias3D.h b/SRC/material/nD/UWmaterials/ManzariDafalias3D.h index 8341b85d3e..d4807db53d 100644 --- a/SRC/material/nD/UWmaterials/ManzariDafalias3D.h +++ b/SRC/material/nD/UWmaterials/ManzariDafalias3D.h @@ -29,7 +29,7 @@ #include #include -#include +#include "ManzariDafalias.h" class ManzariDafalias3D : public ManzariDafalias { diff --git a/SRC/material/nD/UWmaterials/ManzariDafalias3DRO.h b/SRC/material/nD/UWmaterials/ManzariDafalias3DRO.h index 746eba80a8..ae80bbc248 100644 --- a/SRC/material/nD/UWmaterials/ManzariDafalias3DRO.h +++ b/SRC/material/nD/UWmaterials/ManzariDafalias3DRO.h @@ -29,7 +29,7 @@ #include #include -#include +#include "ManzariDafaliasRO.h" class ManzariDafalias3DRO : public ManzariDafaliasRO { diff --git a/SRC/material/nD/UWmaterials/ManzariDafaliasPlaneStrain.h b/SRC/material/nD/UWmaterials/ManzariDafaliasPlaneStrain.h index a40d3531ea..46dc4c03bb 100644 --- a/SRC/material/nD/UWmaterials/ManzariDafaliasPlaneStrain.h +++ b/SRC/material/nD/UWmaterials/ManzariDafaliasPlaneStrain.h @@ -33,7 +33,7 @@ #include #include -#include +#include "ManzariDafalias.h" class ManzariDafaliasPlaneStrain : public ManzariDafalias { diff --git a/SRC/material/nD/UWmaterials/ManzariDafaliasPlaneStrainRO.h b/SRC/material/nD/UWmaterials/ManzariDafaliasPlaneStrainRO.h index 72978f01aa..834759c1f7 100644 --- a/SRC/material/nD/UWmaterials/ManzariDafaliasPlaneStrainRO.h +++ b/SRC/material/nD/UWmaterials/ManzariDafaliasPlaneStrainRO.h @@ -33,7 +33,7 @@ #include #include -#include +#include "ManzariDafaliasRO.h" class ManzariDafaliasPlaneStrainRO : public ManzariDafaliasRO { diff --git a/SRC/material/nD/UWmaterials/ManzariDafaliasRO.h b/SRC/material/nD/UWmaterials/ManzariDafaliasRO.h index cbb9b2badb..81ac4b009f 100644 --- a/SRC/material/nD/UWmaterials/ManzariDafaliasRO.h +++ b/SRC/material/nD/UWmaterials/ManzariDafaliasRO.h @@ -42,7 +42,7 @@ #include #include -#include +#include "ManzariDafalias.h" #include diff --git a/SRC/material/nD/reinforcedConcretePlaneStress/FEM_ObjectBrokerAllClasses.cpp b/SRC/material/nD/reinforcedConcretePlaneStress/FEM_ObjectBrokerAllClasses.cpp deleted file mode 100644 index 980430379d..0000000000 --- a/SRC/material/nD/reinforcedConcretePlaneStress/FEM_ObjectBrokerAllClasses.cpp +++ /dev/null @@ -1,1917 +0,0 @@ -/* ****************************************************************** ** -** OpenSees - Open System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// $Revision: 1.2 $ -// $Date: 2010-02-04 19:10:34 $ -// $Source: /usr/local/cvs/OpenSees/SRC/material/nD/reinforcedConcretePlaneStress/FEM_ObjectBrokerAllClasses.cpp,v $ - -// Written: fmk -// Revision: A -// -// Purpose: This file contains the class definition for FEM_ObjectBrokerAllClasses. -// FEM_ObjectBrokerAllClasses is is an object broker class for the finite element -// method. All methods are virtual to allow for subclasses; which can be -// used by programmers when introducing new subclasses of the main objects. -// -// What: "@(#) FEM_ObjectBrokerAllClasses.C, revA" - - -#include - -// ActorTypes -#include - -// Convergence tests -#include -#include -#include -#include - -// graph numbering schemes -#include -#include -#include - - -// uniaxial material model header files -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//PY springs: RWBoulanger and BJeremic -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -// Sections -#include -#include -#include -//#include -#include -//#include -#include -#include -#include -#include -#include -#include - -// NDMaterials -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include //JZhong 2003.10 -#include //JZhong 2004.05 -#include //JZhong 2004.11 -#include //JZhong 2004.11 -#include //ALaskar 2007.09 -#include //ALaskar 2007.09 -#include //ALaskar 2007.09 -#include //ALaskar 2007.09 - -#include -#include -#include - -// Fibers -#include -#include -// element header files -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include // Arash - - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -// node header files -#include - - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -// mp_constraint header files -#include -#include - -// sp_constraint header files -#include -#include -#include -#include - -// nodal load header files -#include - -// elemental load header files -#include -#include -#include -#include -#include -#include - -// matrix, vector & id header files -#include -#include -#include - -// subdomain header files -#include - -// constraint handler header files -#include -#include -#include -#include -#include - -// dof numberer header files -#include -#include - -// analysis model header files -#include - -// equi soln algo header files -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include - -// domain decomp soln algo header files -#include - -// integrator header files -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _PARALLEL_PROCESSING -#include -#endif -// system of eqn header files -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -// load patterns -#include -#include -#include -#include -#include - -#include -#include -#include - -// time series -#include -#include -#include -#include -#include -#include - -// time series integrators -#include - -#ifdef _PETSC -#include -#include -#include -#include -#endif - - -#ifdef _MUMPS -#include -#include -#ifdef _PARALLEL_PROCESSING -#include -#include -#endif -#endif - -#ifdef _PARALLEL_PROCESSING -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#include - -#include - -typedef struct uniaxialPackage { - int classTag; - char *libName; - char *funcName; - UniaxialMaterial *(*funcPtr)(void); - struct uniaxialPackage *next; -} UniaxialPackage; - -static UniaxialPackage *theUniaxialPackage = NULL; - - - -FEM_ObjectBrokerAllClasses::FEM_ObjectBrokerAllClasses() -:lastLinearSolver(0),lastDomainSolver(0) -{ - -} - - -FEM_ObjectBrokerAllClasses::~FEM_ObjectBrokerAllClasses() -{ - -} - - -Actor * -FEM_ObjectBrokerAllClasses::getNewActor(int classTag, Channel *theChannel) -{ - switch(classTag) { - -#ifdef _PARALLEL_PROCESSING - case ACTOR_TAGS_SUBDOMAIN: - return new ActorSubdomain(*theChannel, *this); -#endif - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewActor - "; - opserr << " - no ActorType type exists for class tag "; - opserr << classTag << endln; - return 0; - } -} - - -PartitionedModelBuilder * -FEM_ObjectBrokerAllClasses::getPtrNewPartitionedModelBuilder(Subdomain &theSubdomain, - int classTag) -{ - switch(classTag) { - /* - case PartitionedModelBuilder_TAGS_PartitionedQuick2dFrameModel: - return new PartitionedQuick2dFrame(theSubdomain); - */ - - default: - opserr << "FEM_ObjectBrokerAllClasses::getPtrNewPartitionedModelBuilder - "; - opserr << " - no PartitionedModelBuilder type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -GraphNumberer * -FEM_ObjectBrokerAllClasses::getPtrNewGraphNumberer(int classTag) -{ - switch(classTag) { - case GraphNUMBERER_TAG_RCM: - return new RCM(); - - - case GraphNUMBERER_TAG_MyRCM: - return new MyRCM(); - - - case GraphNUMBERER_TAG_SimpleNumberer: - return new SimpleNumberer(); - - - default: - opserr << "ObjectBrokerAllClasses::getPtrNewGraphNumberer - "; - opserr << " - no GraphNumberer type exists for class tag " ; - opserr << classTag << endln; - return 0; - - } -} - -/***************************************** - * - * METHODS TO GET NEW MODELLING CLASSES - * - *****************************************/ - - - - - - - - -Element * -FEM_ObjectBrokerAllClasses::getNewElement(int classTag) -{ - switch(classTag) { - - case ELE_TAG_Truss: - return new Truss(); - - case ELE_TAG_TrussSection: - return new TrussSection(); - - case ELE_TAG_CorotTruss: - return new CorotTruss(); - - case ELE_TAG_CorotTrussSection: - return new CorotTrussSection(); - - case ELE_TAG_ZeroLength: - return new ZeroLength(); - - case ELE_TAG_ZeroLengthSection: - return new ZeroLengthSection(); - - //case ELE_TAG_ZeroLengthND: - //return new ZeroLengthND(); - - case ELE_TAG_FourNodeQuadUP: - return new FourNodeQuadUP(); - - case ELE_TAG_FourNodeQuad: - return new FourNodeQuad(); - - case ELE_TAG_ElasticBeam2d: - return new ElasticBeam2d(); - - case ELE_TAG_ElasticBeam3d: - return new ElasticBeam3d(); - - case ELE_TAG_ForceBeamColumn2d: - return new ForceBeamColumn2d(); - - case ELE_TAG_ForceBeamColumn3d: - return new ForceBeamColumn3d(); - - case ELE_TAG_DispBeamColumn2d: - return new DispBeamColumn2d(); - - case ELE_TAG_DispBeamColumn3d: - return new DispBeamColumn3d(); - - case ELE_TAG_EnhancedQuad: - return new EnhancedQuad(); - - case ELE_TAG_NineNodeMixedQuad: - return new NineNodeMixedQuad(); - - case ELE_TAG_ConstantPressureVolumeQuad: - return new ConstantPressureVolumeQuad(); - - case ELE_TAG_Brick: - return new Brick(); - - case ELE_TAG_ShellMITC4: - return new ShellMITC4(); - - case ELE_TAG_BbarBrick: - return new BbarBrick(); - - case ELE_TAG_Joint2D: // Arash - return new Joint2D(); // Arash - - - case ELE_TAG_Nine_Four_Node_QuadUP: - return new NineFourNodeQuadUP(); - - case ELE_TAG_BrickUP: - return new BrickUP(); - - case ELE_TAG_Twenty_Eight_Node_BrickUP: - return new TwentyEightNodeBrickUP(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewElement - "; - opserr << " - no Element type exists for class tag " ; - opserr << classTag << endln; - return 0; - - } -} - -Node * -FEM_ObjectBrokerAllClasses::getNewNode(int classTag) -{ - switch(classTag) { - case NOD_TAG_Node: - return new Node(classTag); - - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewNode - "; - opserr << " - no Node type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -MP_Constraint * -FEM_ObjectBrokerAllClasses::getNewMP(int classTag) -{ - switch(classTag) { - case CNSTRNT_TAG_MP_Constraint: - return new MP_Constraint( 0 , classTag); - - case CNSTRNT_TAG_MP_Joint2D: // Arash - return new MP_Joint2D(); // Arash - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewMP - "; - opserr << " - no MP_Constraint type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -SP_Constraint * -FEM_ObjectBrokerAllClasses::getNewSP(int classTag) -{ - switch(classTag) { - case CNSTRNT_TAG_SP_Constraint: - return new SP_Constraint(classTag); - - case CNSTRNT_TAG_ImposedMotionSP: - return new ImposedMotionSP(); - - case CNSTRNT_TAG_ImposedMotionSP1: - return new ImposedMotionSP1(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewSP - "; - opserr << " - no SP_Constraint type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - -NodalLoad * -FEM_ObjectBrokerAllClasses::getNewNodalLoad(int classTag) -{ - switch(classTag) { - case LOAD_TAG_NodalLoad: - return new NodalLoad(classTag); - - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewNodalLoad - "; - opserr << " - no NodalLoad type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -ElementalLoad * -FEM_ObjectBrokerAllClasses::getNewElementalLoad(int classTag) -{ - switch(classTag) { - - case LOAD_TAG_Beam2dUniformLoad: - return new Beam2dUniformLoad(); - - case LOAD_TAG_Beam2dPointLoad: - return new Beam2dPointLoad(); - - case LOAD_TAG_Beam3dUniformLoad: - return new Beam3dUniformLoad(); - - case LOAD_TAG_Beam3dPointLoad: - return new Beam3dPointLoad(); - - case LOAD_TAG_BrickSelfWeight: - return new BrickSelfWeight(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewNodalLoad - "; - opserr << " - no NodalLoad type exists for class tag "; - opserr << classTag << endln; - return 0; - - } - - return 0; -} - -CrdTransf2d* -FEM_ObjectBrokerAllClasses::getNewCrdTransf2d(int classTag) -{ - switch(classTag) { - case CRDTR_TAG_LinearCrdTransf2d: - return new LinearCrdTransf2d(); - case CRDTR_TAG_PDeltaCrdTransf2d: - return new PDeltaCrdTransf2d(); -#ifdef _COROTATIONAL - case CRDTR_TAG_CorotCrdTransf2d: - return new CorotCrdTransf2d(); -#endif - default: - opserr << "FEM_ObjectBrokerAllClasses::getCrdTransf2d - "; - opserr << " - no CrdTransf2d type exists for class tag "; - opserr << classTag << endln; - return 0; - } - -} - -CrdTransf3d* -FEM_ObjectBrokerAllClasses::getNewCrdTransf3d(int classTag) -{ - switch(classTag) { - case CRDTR_TAG_LinearCrdTransf3d: - return new LinearCrdTransf3d(); - case CRDTR_TAG_PDeltaCrdTransf3d: - return new PDeltaCrdTransf3d(); -#ifdef _COROTATIONAL - case CRDTR_TAG_CorotCrdTransf3d: - return new CorotCrdTransf3d(); -#endif - default: - opserr << "FEM_ObjectBrokerAllClasses::getCrdTransf3d - "; - opserr << " - no CrdTransf3d type exists for class tag "; - opserr << classTag << endln; - return 0; - } - -} - -BeamIntegration * -FEM_ObjectBrokerAllClasses::getNewBeamIntegration(int classTag) -{ - switch(classTag) { - case BEAM_INTEGRATION_TAG_Lobatto: - return new LobattoBeamIntegration(); - - case BEAM_INTEGRATION_TAG_Legendre: - return new LegendreBeamIntegration(); - - case BEAM_INTEGRATION_TAG_Radau: - return new RadauBeamIntegration(); - - case BEAM_INTEGRATION_TAG_NewtonCotes: - return new NewtonCotesBeamIntegration(); - - case BEAM_INTEGRATION_TAG_HingeMidpoint: - return new HingeMidpointBeamIntegration(); - - case BEAM_INTEGRATION_TAG_HingeRadau: - return new HingeRadauBeamIntegration(); - - case BEAM_INTEGRATION_TAG_HingeRadauTwo: - return new HingeRadauTwoBeamIntegration(); - - case BEAM_INTEGRATION_TAG_HingeEndpoint: - return new HingeEndpointBeamIntegration(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getBeamIntegration - "; - opserr << " - no BeamIntegration type exists for class tag "; - opserr << classTag << endln; - return 0; - } -} - - -UniaxialMaterial * -FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) -{ - switch(classTag) { - case MAT_TAG_ElasticMaterial: - return new ElasticMaterial(); // values set in recvSelf - - case MAT_TAG_Elastic2Material: - return new Elastic2Material(); - - case MAT_TAG_ElasticPPMaterial: - return new ElasticPPMaterial(); // values set in recvSelf - - case MAT_TAG_ParallelMaterial: - return new ParallelMaterial(); - - case MAT_TAG_Concrete01: - return new Concrete01(); - - case MAT_TAG_ConcreteZ01: - return new ConcreteZ01(); - - case MAT_TAG_ConcreteZ02: - return new ConcreteZ02(); - - case MAT_TAG_ConcreteL01: - return new ConcreteL01(); - - case MAT_TAG_Steel01: - return new Steel01(); - - case MAT_TAG_SteelZ01: - return new SteelZ01(); - - case MAT_TAG_TendonL01: - return new TendonL01(); - - case MAT_TAG_Hardening: - return new HardeningMaterial(); - - //PY springs: RWBoulanger and BJeremic - case MAT_TAG_PySimple1: - return new PySimple1(); - - case MAT_TAG_PyLiq1: - return new PyLiq1(); - - case MAT_TAG_TzSimple1: - return new TzSimple1(); - - case MAT_TAG_TzLiq1: - return new TzLiq1(); - - case MAT_TAG_QzSimple1: - return new QzSimple1(); - - - case MAT_TAG_Hysteretic: - return new HystereticMaterial(); - - case MAT_TAG_EPPGap: - return new EPPGapMaterial(); - - case MAT_TAG_Viscous: - return new ViscousMaterial(); - - case MAT_TAG_PathIndependent: - return new PathIndependentMaterial(); - - case MAT_TAG_SeriesMaterial: - return new SeriesMaterial(); - - case MAT_TAG_CableMaterial: - return new CableMaterial(); - - case MAT_TAG_ENTMaterial: - return new ENTMaterial(); - - case MAT_TAG_FedeasBond1: - return new FedeasBond1Material(); - - case MAT_TAG_FedeasBond2: - return new FedeasBond2Material(); - - case MAT_TAG_FedeasConcrete1: - return new FedeasConcr1Material(); - - case MAT_TAG_FedeasConcrete2: - return new FedeasConcr2Material(); - - case MAT_TAG_FedeasConcrete3: - return new FedeasConcr3Material(); - - case MAT_TAG_FedeasHardening: - return new FedeasHardeningMaterial(); - - case MAT_TAG_FedeasHysteretic1: - return new FedeasHyster1Material(); - - case MAT_TAG_FedeasHysteretic2: - return new FedeasHyster2Material(); - - case MAT_TAG_FedeasSteel1: - return new FedeasSteel1Material(); - - case MAT_TAG_FedeasSteel2: - return new FedeasSteel2Material(); - - case MAT_TAG_DrainBilinear: - return new DrainBilinearMaterial(); - - case MAT_TAG_DrainClough1: - return new DrainClough1Material(); - - case MAT_TAG_DrainClough2: - return new DrainClough2Material(); - - case MAT_TAG_DrainPinch1: - return new DrainPinch1Material(); - - case MAT_TAG_MinMax: - return new MinMaxMaterial(); - - default: - - UniaxialPackage *matCommands = theUniaxialPackage; - bool found = false; - while (matCommands != NULL && found == false) { - if ((matCommands->classTag == classTag) && (matCommands->funcPtr != 0)){ - UniaxialMaterial *result = (*(matCommands->funcPtr))(); - return result; - } - matCommands = matCommands->next; - } - - opserr << "FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial - "; - opserr << " - no UniaxialMaterial type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - -SectionForceDeformation * -FEM_ObjectBrokerAllClasses::getNewSection(int classTag) -{ - switch(classTag) { - case SEC_TAG_Elastic2d: - return new ElasticSection2d(); - - case SEC_TAG_Elastic3d: - return new ElasticSection3d(); - - case SEC_TAG_Generic1d: - return new GenericSection1d(); - - //case SEC_TAG_GenericNd: - //return new GenericSectionNd(); - - case SEC_TAG_Aggregator: - return new SectionAggregator(); - - //case SEC_TAG_Fiber: - //return new FiberSection(); - - case SEC_TAG_FiberSection2d: - return new FiberSection2d(); - - case SEC_TAG_FiberSection3d: - return new FiberSection3d(); - - case SEC_TAG_ElasticPlateSection: - return new ElasticPlateSection(); - - case SEC_TAG_ElasticMembranePlateSection: - return new ElasticMembranePlateSection(); - - case SEC_TAG_MembranePlateFiberSection: - return new MembranePlateFiberSection(); - - case SEC_TAG_Bidirectional: - return new Bidirectional(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewSection - "; - opserr << " - no section type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - -NDMaterial* -FEM_ObjectBrokerAllClasses::getNewNDMaterial(int classTag) -{ - switch(classTag) { - case ND_TAG_ElasticIsotropicPlaneStrain2d: - return new ElasticIsotropicPlaneStrain2D(); - - case ND_TAG_ElasticIsotropicPlaneStress2d: - return new ElasticIsotropicPlaneStress2D(); - - case ND_TAG_ElasticIsotropicAxiSymm: - return new ElasticIsotropicAxiSymm(); - - case ND_TAG_ElasticIsotropicPlateFiber: - return new ElasticIsotropicPlateFiber(); - - case ND_TAG_ElasticIsotropic3D: - return new ElasticIsotropic3D(); - - case ND_TAG_J2PlaneStrain: - return new J2PlaneStrain(); - - case ND_TAG_J2PlaneStress: - return new J2PlaneStress(); - - case ND_TAG_J2AxiSymm: - return new J2AxiSymm(); - - case ND_TAG_J2PlateFiber: - return new J2PlateFiber(); - - case ND_TAG_J2ThreeDimensional: - return new J2ThreeDimensional(); - - case ND_TAG_PlaneStressMaterial: - return new PlaneStressMaterial(); - - case ND_TAG_PlateFiberMaterial: - return new PlateFiberMaterial(); - - case ND_TAG_FluidSolidPorousMaterial: - return new FluidSolidPorousMaterial(); - - case ND_TAG_PressureDependMultiYield: - return new PressureDependMultiYield(); - - case ND_TAG_PressureIndependMultiYield: - return new PressureIndependMultiYield(); - - case ND_TAG_FeapMaterial03: - return new FeapMaterial03(); - - case ND_TAG_ReinforceConcretePlaneStress: - return new ReinforceConcretePlaneStress(); - - case ND_TAG_FAReinforceConcretePlaneStress: - return new FAReinforceConcretePlaneStress(); - - case ND_TAG_RAFourSteelRCPlaneStress: - return new RAFourSteelRCPlaneStress(); - - case ND_TAG_FAFourSteelRCPlaneStress: - return new FAFourSteelRCPlaneStress(); - - case ND_TAG_PrestressConcretePlaneStress: - return new PrestressConcretePlaneStress(); - - case ND_TAG_FAPrestressConcretePlaneStress: - return new FAPrestressConcretePlaneStress(); - - case ND_TAG_RAFourSteelPCPlaneStress: - return new RAFourSteelPCPlaneStress(); - - case ND_TAG_FAFourSteelPCPlaneStress: - return new FAFourSteelPCPlaneStress(); - - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewNDMaterial - "; - opserr << " - no NDMaterial type exists for class tag "; - opserr << classTag << endln; - return 0; - } -} - -Fiber* -FEM_ObjectBrokerAllClasses::getNewFiber(int classTag) -{ - switch(classTag) { - case FIBER_TAG_Uniaxial2d: - return new UniaxialFiber2d(); - - case FIBER_TAG_Uniaxial3d: - return new UniaxialFiber3d(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewFiber - "; - opserr << " - no Fiber type exists for class tag "; - opserr << classTag << endln; - return 0; - } -} - -ConvergenceTest * -FEM_ObjectBrokerAllClasses::getNewConvergenceTest(int classTag) -{ - switch(classTag) { - case CONVERGENCE_TEST_CTestNormUnbalance: - return new CTestNormUnbalance(); - - case CONVERGENCE_TEST_CTestNormDispIncr: - return new CTestNormDispIncr(); - - case CONVERGENCE_TEST_CTestEnergyIncr: - return new CTestEnergyIncr(); - - case CONVERGENCE_TEST_CTestNormDispIncrVaryIter: - return new CTestNormDispIncrVaryIter(); - - - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewConvergenceTest - "; - opserr << " - no ConvergenceTest type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -LoadPattern * -FEM_ObjectBrokerAllClasses::getNewLoadPattern(int classTag) -{ - switch(classTag) { - case PATTERN_TAG_LoadPattern: - return new LoadPattern(); - - case PATTERN_TAG_UniformExcitation: - return new UniformExcitation(); - - case PATTERN_TAG_MultiSupportPattern: - return new MultiSupportPattern(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getPtrLoadPattern - "; - opserr << " - no Load type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -GroundMotion * -FEM_ObjectBrokerAllClasses::getNewGroundMotion(int classTag) -{ - switch(classTag) { - - case GROUND_MOTION_TAG_GroundMotion: - return new GroundMotion(GROUND_MOTION_TAG_GroundMotion); - - case GROUND_MOTION_TAG_InterpolatedGroundMotion: - return new GroundMotion(GROUND_MOTION_TAG_InterpolatedGroundMotion); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getPtrGroundMotion - "; - opserr << " - no Load type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - -TimeSeries * -FEM_ObjectBrokerAllClasses::getNewTimeSeries(int classTag) -{ - switch(classTag) { - case TSERIES_TAG_LinearSeries: - return new LinearSeries; - - case TSERIES_TAG_RectangularSeries: - return new RectangularSeries; - - case TSERIES_TAG_PathTimeSeries: - return new PathTimeSeries; - - case TSERIES_TAG_PathSeries: - return new PathSeries; - - case TSERIES_TAG_ConstantSeries: - return new ConstantSeries; - - case TSERIES_TAG_TrigSeries: - return new TrigSeries; - - default: - opserr << "FEM_ObjectBrokerAllClasses::getPtrTimeSeries - "; - opserr << " - no Load type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - -TimeSeriesIntegrator * -FEM_ObjectBrokerAllClasses::getNewTimeSeriesIntegrator(int classTag) -{ - switch(classTag) { - case TIMESERIES_INTEGRATOR_TAG_Trapezoidal: - return new TrapezoidalTimeSeriesIntegrator(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getPtrTimeSeriesIntegrator - "; - opserr << " - no Load type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -Matrix * -FEM_ObjectBrokerAllClasses::getPtrNewMatrix(int classTag, int noRows, int noCols) -{ - switch(classTag) { - case MATRIX_TAG_Matrix: - return new Matrix(noRows,noCols); - - - default: - opserr << "FEM_ObjectBrokerAllClasses::getPtrNewMatrix - "; - opserr << " - no NodalLoad type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -Vector * -FEM_ObjectBrokerAllClasses::getPtrNewVector(int classTag, int size) -{ - switch(classTag) { - case VECTOR_TAG_Vector: - return new Vector(size); - - - default: - opserr << "FEM_ObjectBrokerAllClasses::getPtrNewVector - "; - opserr << " - no Vector type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -ID * -FEM_ObjectBrokerAllClasses::getPtrNewID(int classTag, int size) -{ - switch(classTag) { - case ID_TAG_ID: - return new ID(size); - - - default: - opserr << "FEM_ObjectBrokerAllClasses::getPtrNewID - "; - opserr << " - no ID type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - -/***************************************** - * - * METHODS TO GET NEW OUTPUT CLASS OBJECTS - * - *****************************************/ - -OPS_Stream * -FEM_ObjectBrokerAllClasses::getPtrNewStream(int classTag) -{ - switch(classTag) { - case OPS_STREAM_TAGS_StandardStream: - return new StandardStream(); - - case OPS_STREAM_TAGS_FileStream: - return new FileStream(); - - case OPS_STREAM_TAGS_XmlFileStream: - return new XmlFileStream(); - - case OPS_STREAM_TAGS_DataFileStream: - return new DataFileStream(); - - case OPS_STREAM_TAGS_DatabaseStream: - return new DatabaseStream(); - - case OPS_STREAM_TAGS_DummyStream: - return new DummyStream(); - - - - default: - opserr << "FEM_ObjectBrokerAllClasses::getPtrNewStream - "; - opserr << " - no DataOutputHandler type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - -Recorder * -FEM_ObjectBrokerAllClasses::getPtrNewRecorder(int classTag) -{ - switch(classTag) { - case RECORDER_TAGS_ElementRecorder: - return new ElementRecorder(); - - case RECORDER_TAGS_NodeRecorder: - return new NodeRecorder(); - - case RECORDER_TAGS_EnvelopeNodeRecorder: - return new EnvelopeNodeRecorder(); - - case RECORDER_TAGS_EnvelopeElementRecorder: - return new EnvelopeElementRecorder(); - - - case RECORDER_TAGS_TclFeViewer: - return new TclFeViewer(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewConstraintHandler - "; - opserr << " - no ConstraintHandler type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - - -/***************************************** - * - * METHODS TO GET NEW ANALYSIS CLASSES - * - *****************************************/ - -ConstraintHandler * -FEM_ObjectBrokerAllClasses::getNewConstraintHandler(int classTag) -{ - switch(classTag) { - case HANDLER_TAG_PlainHandler: - return new PlainHandler(); - - case HANDLER_TAG_PenaltyConstraintHandler: - return new PenaltyConstraintHandler(1.0e12, 1.0e12); - - case HANDLER_TAG_LagrangeConstraintHandler: - return new LagrangeConstraintHandler(1.0, 1.0); - - case HANDLER_TAG_TransformationConstraintHandler: - return new TransformationConstraintHandler(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewConstraintHandler - "; - opserr << " - no ConstraintHandler type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -DOF_Numberer * -FEM_ObjectBrokerAllClasses::getNewNumberer(int classTag) -{ - switch(classTag) { - case NUMBERER_TAG_DOF_Numberer: - return new DOF_Numberer(); - - - case NUMBERER_TAG_PlainNumberer: - return new PlainNumberer(); - - -#ifdef _PARALLEL_PROCESSING - case NUMBERER_TAG_ParallelNumberer: - return new ParallelNumberer(); -#endif - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewConstraintHandler - "; - opserr << " - no ConstraintHandler type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -AnalysisModel * -FEM_ObjectBrokerAllClasses::getNewAnalysisModel(int classTag) -{ - switch(classTag) { - case AnaMODEL_TAGS_AnalysisModel: - return new AnalysisModel(); - - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewAnalysisModel - "; - opserr << " - no AnalysisModel type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -EquiSolnAlgo * -FEM_ObjectBrokerAllClasses::getNewEquiSolnAlgo(int classTag) -{ - switch(classTag) { - case EquiALGORITHM_TAGS_Linear: - return new Linear(); - - case EquiALGORITHM_TAGS_NewtonRaphson: - return new NewtonRaphson(); - - case EquiALGORITHM_TAGS_NewtonLineSearch: - return new NewtonLineSearch(); - - case EquiALGORITHM_TAGS_KrylovNewton: - return new KrylovNewton(); - - case EquiALGORITHM_TAGS_ModifiedNewton: - return new ModifiedNewton(); - - case EquiALGORITHM_TAGS_Broyden: - return new Broyden(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewEquiSolnAlgo - "; - opserr << " - no EquiSolnAlgo type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -LineSearch * -FEM_ObjectBrokerAllClasses::getLineSearch(int classTag) -{ - switch(classTag) { - - case LINESEARCH_TAGS_BisectionLineSearch: - return new BisectionLineSearch(); - - case LINESEARCH_TAGS_InitialInterpolatedLineSearch: - return new InitialInterpolatedLineSearch(); - - case LINESEARCH_TAGS_RegulaFalsiLineSearch: - return new RegulaFalsiLineSearch(); - - case LINESEARCH_TAGS_SecantLineSearch: - return new SecantLineSearch(); - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewEquiSolnAlgo - "; - opserr << " - no EquiSolnAlgo type exists for class tag "; - opserr << classTag << endln; - return 0; - } -} - - -DomainDecompAlgo * -FEM_ObjectBrokerAllClasses::getNewDomainDecompAlgo(int classTag) -{ - switch(classTag) { - case DomDecompALGORITHM_TAGS_DomainDecompAlgo: - return new DomainDecompAlgo(); - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewDomainDecompAlgo - "; - opserr << " - no DomainDecompAlgo type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -StaticIntegrator * -FEM_ObjectBrokerAllClasses::getNewStaticIntegrator(int classTag) -{ - switch(classTag) { - case INTEGRATOR_TAGS_LoadControl: - return new LoadControl(1.0,1,1.0,.10); // must recvSelf - -#ifdef _PARALLEL_PROCESSING - case INTEGRATOR_TAGS_DistributedDisplacementControl: - return new DistributedDisplacementControl(); // must recvSelf -#endif - - case INTEGRATOR_TAGS_ArcLength: - return new ArcLength(1.0); // must recvSelf - - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewStaticIntegrator - "; - opserr << " - no StaticIntegrator type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -TransientIntegrator * -FEM_ObjectBrokerAllClasses::getNewTransientIntegrator(int classTag) -{ - switch(classTag) { - case INTEGRATOR_TAGS_Newmark: - return new Newmark(); - - case INTEGRATOR_TAGS_CentralDifferenceNoDamping: - return new CentralDifferenceNoDamping(); // must recvSelf - - case INTEGRATOR_TAGS_CentralDifferenceAlternative: - return new CentralDifferenceAlternative(); // must recvSelf - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewTransientIntegrator - "; - opserr << " - no TransientIntegrator type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -IncrementalIntegrator * -FEM_ObjectBrokerAllClasses::getNewIncrementalIntegrator(int classTag) -{ - switch(classTag) { - case INTEGRATOR_TAGS_LoadControl: - return new LoadControl(1.0,1,1.0,1.0); // must recvSelf - - - case INTEGRATOR_TAGS_ArcLength: - return new ArcLength(1.0); // must recvSelf - - case INTEGRATOR_TAGS_Newmark: - return new Newmark(); - -#ifdef _PARALLEL_PROCESSING - case INTEGRATOR_TAGS_DistributedDisplacementControl: - return new DistributedDisplacementControl(); // must recvSelf -#endif - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewIncrementalIntegrator - "; - opserr << " - no IncrementalIntegrator type exists for class tag "; - opserr << classTag << endln; - return 0; - - } -} - - -LinearSOESolver * -FEM_ObjectBrokerAllClasses::getNewLinearSolver(void) -{ - return lastLinearSolver; -} - -LinearSOE * -FEM_ObjectBrokerAllClasses::getNewLinearSOE(int classTagSOE, - int classTagSolver) -{ - LinearSOE *theSOE =0; -// SlowLinearSOESolver *theSlowSolver =0; - FullGenLinSolver *theGenSolver =0; - BandGenLinSolver *theGenBandSolver =0; - BandSPDLinSolver *theBandSPDSolver =0; - ProfileSPDLinSolver *theProfileSPDSolver =0; - SuperLU *theSparseGenLinSolver =0; - -#ifdef _PETSC - PetscSolver *thePetscSolver = 0; -#endif - -#ifdef _PARALLEL_PROCESSING - DistributedSuperLU *theDistributedSparseGenLinSolver =0; - DistributedDiagonalSolver *theDistributedDiagonalSolver =0; -#ifdef _MUMPS - MumpsParallelSolver *theMumpsSolver = 0; -#endif -#endif - - /* - case LinSOE_TAGS_SlowLinearSOE: - if (classTagSolver == SOLVER_TAGS_SlowLinearSOESolver) { - theSlowSolver = new SlowLinearSOESolver(); - theSOE = new SlowLinearSOE(*theSlowSolver); - lastLinearSolver = theSlowSolver; - return theSOE; - } else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no SlowLinearSOESolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } - - */ - - - switch(classTagSOE) { - case LinSOE_TAGS_FullGenLinSOE: - - if (classTagSolver == SOLVER_TAGS_FullGenLinLapackSolver) { - theGenSolver = new FullGenLinLapackSolver(); - theSOE = new FullGenLinSOE(*theGenSolver); - lastLinearSolver = theGenSolver; - return theSOE; - } else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no FullGenLinSOESolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } - - - case LinSOE_TAGS_BandGenLinSOE: - - if (classTagSolver == SOLVER_TAGS_BandGenLinLapackSolver) { - theGenBandSolver = new BandGenLinLapackSolver(); - theSOE = new BandGenLinSOE(*theGenBandSolver); - lastLinearSolver = theGenBandSolver; - return theSOE; - } else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no BandGenLinSolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } - - case LinSOE_TAGS_BandSPDLinSOE: - - if (classTagSolver == SOLVER_TAGS_BandSPDLinLapackSolver) { - theBandSPDSolver = new BandSPDLinLapackSolver(); - theSOE = new BandSPDLinSOE(*theBandSPDSolver); - lastLinearSolver = theBandSPDSolver; - return theSOE; - } else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no BandSPDLinSOESolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } - - case LinSOE_TAGS_ProfileSPDLinSOE: - - if (classTagSolver == SOLVER_TAGS_ProfileSPDLinDirectSolver) { - theProfileSPDSolver = new ProfileSPDLinDirectSolver(); - theSOE = new ProfileSPDLinSOE(*theProfileSPDSolver); - lastLinearSolver = theProfileSPDSolver; - return theSOE; - } else if (classTagSolver == SOLVER_TAGS_ProfileSPDLinSubstrSolver) { - theProfileSPDSolver = new ProfileSPDLinSubstrSolver(); - theSOE = new ProfileSPDLinSOE(*theProfileSPDSolver); - lastLinearSolver = theProfileSPDSolver; - return 0; - } - else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no ProfileSPD_LinSolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } - - -#ifdef _PETSC - case LinSOE_TAGS_PetscSOE: - - if (classTagSolver == SOLVER_TAGS_PetscSolver) { - thePetscSolver = new PetscSolver(); - theSOE = new PetscSOE(*thePetscSolver); - return theSOE; - } else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no PetscSolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } -#endif - -#ifdef _PARALLEL_PROCESSING - -#ifdef _MUMPS - case LinSOE_TAGS_MumpsParallelSOE: - if (classTagSolver == SOLVER_TAGS_MumpsParallelSolver) { - theMumpsSolver = new MumpsParallelSolver(); - theSOE = new MumpsParallelSOE(*theMumpsSolver); - lastLinearSolver = theMumpsSolver; - return theSOE; - } else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no DistributedBandGenLinSolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } -#endif - - case LinSOE_TAGS_DistributedBandGenLinSOE: - - if (classTagSolver == SOLVER_TAGS_BandGenLinLapackSolver) { - theGenBandSolver = new BandGenLinLapackSolver(); - theSOE = new DistributedBandGenLinSOE(*theGenBandSolver); - lastLinearSolver = theGenBandSolver; - return theSOE; - } else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no DistributedBandGenLinSolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } - - case LinSOE_TAGS_DistributedBandSPDLinSOE: - - if (classTagSolver == SOLVER_TAGS_BandSPDLinLapackSolver) { - theBandSPDSolver = new BandSPDLinLapackSolver(); - theSOE = new DistributedBandSPDLinSOE(*theBandSPDSolver); - lastLinearSolver = theBandSPDSolver; - return theSOE; - } else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no DistributedBandSPDLinSolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } - - - case LinSOE_TAGS_DistributedProfileSPDLinSOE: - - if (classTagSolver == SOLVER_TAGS_ProfileSPDLinDirectSolver) { - theProfileSPDSolver = new ProfileSPDLinDirectSolver(); - theSOE = new DistributedProfileSPDLinSOE(*theProfileSPDSolver); - lastLinearSolver = theProfileSPDSolver; - return theSOE; - } else if (classTagSolver == SOLVER_TAGS_ProfileSPDLinSubstrSolver) { - theProfileSPDSolver = new ProfileSPDLinSubstrSolver(); - theSOE = new DistributedProfileSPDLinSOE(*theProfileSPDSolver); - lastLinearSolver = theProfileSPDSolver; - return 0; - } - else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no ProfileSPD_LinSolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } - - case LinSOE_TAGS_DistributedDiagonalSOE: - - if (classTagSolver == SOLVER_TAGS_DistributedDiagonalSolver) { - theDistributedDiagonalSolver = new DistributedDiagonalSolver(); - theSOE = new DistributedDiagonalSOE(*theDistributedDiagonalSolver); - lastLinearSolver = theDistributedDiagonalSolver; - return theSOE; - } else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no DistributedSparseGenLinSolverSolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } - - case LinSOE_TAGS_DistributedSparseGenColLinSOE: - - if (classTagSolver == SOLVER_TAGS_SuperLU) { - theSparseGenLinSolver = new SuperLU(); - theSOE = new DistributedSparseGenColLinSOE(*theSparseGenLinSolver); - lastLinearSolver = theSparseGenLinSolver; - return theSOE; - } else if (classTagSolver == SOLVER_TAGS_DistributedSuperLU) { - theDistributedSparseGenLinSolver = new DistributedSuperLU(); - theSOE = new DistributedSparseGenColLinSOE(*theDistributedSparseGenLinSolver); - lastLinearSolver = theSparseGenLinSolver; - return theSOE; - } else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no DistributedSparseGenLinSolverSolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } - -#else - case LinSOE_TAGS_SparseGenColLinSOE: - - if (classTagSolver == SOLVER_TAGS_SuperLU) { - theSparseGenLinSolver = new SuperLU(); - theSOE = new SparseGenColLinSOE(*theSparseGenLinSolver); - lastLinearSolver = theSparseGenLinSolver; - return theSOE; - } else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no SparseGenLinSolverSolver type exists for class tag "; - opserr << classTagSolver << endln; - return 0; - } - -#endif - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no LinearSOE type exists for class tag "; - opserr << classTagSOE << endln; - return 0; - - - } -} - - - - -DomainSolver * -FEM_ObjectBrokerAllClasses::getNewDomainSolver(void) -{ - return lastDomainSolver; -} - -LinearSOE * -FEM_ObjectBrokerAllClasses::getPtrNewDDLinearSOE(int classTagSOE, - int classTagDDSolver) -{ - ProfileSPDLinSubstrSolver *theProfileSPDSolver =0; - - switch(classTagSOE) { - case LinSOE_TAGS_ProfileSPDLinSOE: - - if (classTagDDSolver == SOLVER_TAGS_ProfileSPDLinSubstrSolver) { - theProfileSPDSolver = new ProfileSPDLinSubstrSolver(); - LinearSOE *theSOE = new ProfileSPDLinSOE(*theProfileSPDSolver); - lastDomainSolver = theProfileSPDSolver; - return theSOE; - } - else { - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no ProfileSPD Domain Solver type exists for class tag "; - opserr << classTagDDSolver << endln; - return 0; - } - - - default: - opserr << "FEM_ObjectBrokerAllClasses::getNewLinearSOE - "; - opserr << " - no LinearSOE type exists for class tag "; - opserr << classTagSOE << endln; - return 0; - - } -} - - -DomainDecompositionAnalysis * -FEM_ObjectBrokerAllClasses::getNewDomainDecompAnalysis(int classTag, - Subdomain &theSubdomain) -{ - switch(classTag) { - case DomDecompANALYSIS_TAGS_DomainDecompositionAnalysis: - return new DomainDecompositionAnalysis(theSubdomain); - -#ifdef _PARALLEL_PROCESSING - case ANALYSIS_TAGS_StaticDomainDecompositionAnalysis: - return new StaticDomainDecompositionAnalysis(theSubdomain); - - case ANALYSIS_TAGS_TransientDomainDecompositionAnalysis: - return new TransientDomainDecompositionAnalysis(theSubdomain); -#endif - - default: - opserr << "ObjectBrokerAllClasses::getNewDomainDecompAnalysis "; - opserr << " - no DomainDecompAnalysis type exists for class tag " ; - opserr << classTag << endln; - return 0; - - } -} - - -Subdomain * -FEM_ObjectBrokerAllClasses::getSubdomainPtr(int classTag) -{ - opserr << "FEM_ObjectBrokerAllClasses: NOT IMPLEMENTED YET"; - return 0; -} - - -int -FEM_ObjectBrokerAllClasses::addUniaxialMaterial(int classTag, - const char *lib, - const char *funcName, - UniaxialMaterial *(*funcPtr)(void)) -{ - // check to see if it's already added - - UniaxialPackage *matCommands = theUniaxialPackage; - bool found = false; - while (matCommands != NULL && found == false) { - if ((strcmp(lib, matCommands->libName) == 0) && (strcmp(funcName, matCommands->funcName) == 0)) { - return 0; - } - } - - // - // if funPtr == 0; go get the handle - // - - void *libHandle; - if (funcPtr == 0) { - if (getLibraryFunction(lib, funcName, &libHandle, (void **)&funcPtr) != 0) { - opserr << "FEM_ObjectBrokerAllClasses::addUniaxialMaterial - could not find function\n"; - return -1; - } - } - - // - // add the new funcPtr - // - - char *libNameCopy = new char[strlen(lib)+1]; - char *funcNameCopy = new char[strlen(funcName)+1]; - UniaxialPackage *theMat = new UniaxialPackage; - if (libNameCopy == 0 || funcNameCopy == 0 || theMat == 0) { - opserr << "FEM_ObjectBrokerAllClasses::addUniaxialMaterial - could not add lib, out of memory\n"; - return -1; - } - strcpy(libNameCopy, lib); - strcpy(funcNameCopy, funcName); - - theMat->classTag = classTag; - theMat->funcName = funcNameCopy; - theMat->libName = libNameCopy; - theMat->funcPtr = funcPtr; - theMat->next = theUniaxialPackage; - theUniaxialPackage = theMat; - - return 0; - -} - - -Parameter * -FEM_ObjectBrokerAllClasses::getParameter(int classTag) -{ - Parameter *theRes = 0; - - switch(classTag) { - case PARAMETER_TAG_Parameter: - theRes = new Parameter; - break; - - case PARAMETER_TAG_MaterialStageParameter: - theRes = new MaterialStageParameter(); - break; - - case PARAMETER_TAG_MatParameter: - theRes = new MatParameter(); - break; - - default: - ; - } - - return theRes; -} - diff --git a/SRC/material/nD/soil/FluidSolidPorousMaterial.cpp b/SRC/material/nD/soil/FluidSolidPorousMaterial.cpp index f4086573e6..17562612be 100644 --- a/SRC/material/nD/soil/FluidSolidPorousMaterial.cpp +++ b/SRC/material/nD/soil/FluidSolidPorousMaterial.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/SRC/material/nD/soil/FluidSolidPorousMaterial.h b/SRC/material/nD/soil/FluidSolidPorousMaterial.h index 9bed81e728..ab3bda8002 100644 --- a/SRC/material/nD/soil/FluidSolidPorousMaterial.h +++ b/SRC/material/nD/soil/FluidSolidPorousMaterial.h @@ -14,8 +14,9 @@ #define FluidSolidPorousMaterial_h #include -#include #include +#include "soil/T2Vector.h" +class MultiYieldSurface; class Response; diff --git a/SRC/material/nD/soil/MultiYieldSurfaceClay.cpp b/SRC/material/nD/soil/MultiYieldSurfaceClay.cpp index 8c4c3b5945..2a678dd738 100644 --- a/SRC/material/nD/soil/MultiYieldSurfaceClay.cpp +++ b/SRC/material/nD/soil/MultiYieldSurfaceClay.cpp @@ -22,6 +22,8 @@ #include #include #include +#include + #include #include #include diff --git a/SRC/material/nD/soil/MultiYieldSurfaceClay.h b/SRC/material/nD/soil/MultiYieldSurfaceClay.h index d0d520ecce..552bdb2059 100644 --- a/SRC/material/nD/soil/MultiYieldSurfaceClay.h +++ b/SRC/material/nD/soil/MultiYieldSurfaceClay.h @@ -18,8 +18,9 @@ #define MultiYieldSurfaceClay_h #include -#include #include +#include "soil/T2Vector.h" +class MultiYieldSurface; #define ND_TAG_MultiYieldSurfaceClay 10284765 diff --git a/SRC/material/nD/soil/PressureDependMultiYield.cpp b/SRC/material/nD/soil/PressureDependMultiYield.cpp index bc0b908853..b9370510f6 100644 --- a/SRC/material/nD/soil/PressureDependMultiYield.cpp +++ b/SRC/material/nD/soil/PressureDependMultiYield.cpp @@ -12,7 +12,9 @@ #include #include + #include +#include #include #include #include diff --git a/SRC/material/nD/soil/PressureDependMultiYield.h b/SRC/material/nD/soil/PressureDependMultiYield.h index b6efdd24ea..4fda9f5e97 100644 --- a/SRC/material/nD/soil/PressureDependMultiYield.h +++ b/SRC/material/nD/soil/PressureDependMultiYield.h @@ -15,9 +15,11 @@ #define PressureDependMultiYield_h #include -#include +#include "soil/T2Vector.h" #include +class MultiYieldSurface; + class PressureDependMultiYield : public NDMaterial { public: diff --git a/SRC/material/nD/soil/PressureDependMultiYield02.cpp b/SRC/material/nD/soil/PressureDependMultiYield02.cpp index 1e3e2d9c33..e6fbddb260 100644 --- a/SRC/material/nD/soil/PressureDependMultiYield02.cpp +++ b/SRC/material/nD/soil/PressureDependMultiYield02.cpp @@ -19,6 +19,7 @@ #include #include #include +#include int PressureDependMultiYield02::matCount=0; int* PressureDependMultiYield02::loadStagex = 0; //=0 if elastic; =1 if plastic diff --git a/SRC/material/nD/soil/PressureDependMultiYield02.h b/SRC/material/nD/soil/PressureDependMultiYield02.h index ca360fef9a..e08d1218c8 100644 --- a/SRC/material/nD/soil/PressureDependMultiYield02.h +++ b/SRC/material/nD/soil/PressureDependMultiYield02.h @@ -14,8 +14,10 @@ #define PressureDependMultiYield02_h #include -#include #include +#include "soil/T2Vector.h" + +class MultiYieldSurface; class PressureDependMultiYield02 : public NDMaterial { diff --git a/SRC/material/nD/soil/PressureDependMultiYield03.cpp b/SRC/material/nD/soil/PressureDependMultiYield03.cpp index eb5bac312d..bbf3077266 100644 --- a/SRC/material/nD/soil/PressureDependMultiYield03.cpp +++ b/SRC/material/nD/soil/PressureDependMultiYield03.cpp @@ -13,6 +13,8 @@ #include #include #include +#include + #include #include #include diff --git a/SRC/material/nD/soil/PressureDependMultiYield03.h b/SRC/material/nD/soil/PressureDependMultiYield03.h index 9d0f98858f..5ae2b57223 100644 --- a/SRC/material/nD/soil/PressureDependMultiYield03.h +++ b/SRC/material/nD/soil/PressureDependMultiYield03.h @@ -14,8 +14,10 @@ #define PressureDependMultiYield03_h #include -#include #include +#include "soil/T2Vector.h" + +class MultiYieldSurface; class PressureDependMultiYield03 : public NDMaterial { diff --git a/SRC/material/nD/soil/PressureIndependMultiYield.cpp b/SRC/material/nD/soil/PressureIndependMultiYield.cpp index 2b56e4ac27..23dd735cb9 100644 --- a/SRC/material/nD/soil/PressureIndependMultiYield.cpp +++ b/SRC/material/nD/soil/PressureIndependMultiYield.cpp @@ -18,6 +18,8 @@ #include #include #include +#include + Matrix PressureIndependMultiYield::theTangent(6,6); T2Vector PressureIndependMultiYield::subStrainRate; diff --git a/SRC/material/nD/soil/PressureIndependMultiYield.h b/SRC/material/nD/soil/PressureIndependMultiYield.h index 80ca251af6..d4101607b1 100644 --- a/SRC/material/nD/soil/PressureIndependMultiYield.h +++ b/SRC/material/nD/soil/PressureIndependMultiYield.h @@ -7,15 +7,16 @@ // Description: This file contains the class prototype for PressureIndependMultiYield. // -// What: "@(#) PressureIndependMultiYield.h, revA" - +// What: "@(#) PressureIndependMultiYield.h, revA" #ifndef PressureIndependMultiYield_h #define PressureIndependMultiYield_h #include -#include +#include "soil/T2Vector.h" #include +class MultiYieldSurface; + class PressureIndependMultiYield : public NDMaterial { public: diff --git a/SRC/material/nD/soil/TclUpdateMaterialStageCommand.cpp b/SRC/material/nD/soil/TclUpdateMaterialStageCommand.cpp index 2290daa2be..15d0050cec 100644 --- a/SRC/material/nD/soil/TclUpdateMaterialStageCommand.cpp +++ b/SRC/material/nD/soil/TclUpdateMaterialStageCommand.cpp @@ -78,6 +78,8 @@ TclModelBuilderUpdateMaterialStageCommand(ClientData clientData, theDomain->removeParameter(parTag); + delete theParameter; + return TCL_OK; } diff --git a/SRC/material/section/FiberSection2d.cpp b/SRC/material/section/FiberSection2d.cpp index c35b0098d3..dd5eed2bd5 100644 --- a/SRC/material/section/FiberSection2d.cpp +++ b/SRC/material/section/FiberSection2d.cpp @@ -943,10 +943,10 @@ FiberSection2d::setResponse(const char **argv, int argc, int count = 0; return theResponse = new MaterialResponse(this, 7, count); } - //by SAJalali - else if ((strcmp(argv[0], "energy") == 0) || (strcmp(argv[0], "Energy") == 0)) { - return theResponse = new MaterialResponse(this, 8, getEnergy()); - } + //by SAJalali + else if ((strcmp(argv[0], "energy") == 0) || (strcmp(argv[0], "Energy") == 0)) { + return theResponse = new MaterialResponse(this, 8, getEnergy()); + } // If not a fiber response, call the base class method return SectionForceDeformation::setResponse(argv, argc, output); diff --git a/SRC/material/section/FiberSection2dThermal.cpp b/SRC/material/section/FiberSection2dThermal.cpp index 485eacc1f1..82cff6d7dd 100644 --- a/SRC/material/section/FiberSection2dThermal.cpp +++ b/SRC/material/section/FiberSection2dThermal.cpp @@ -67,7 +67,7 @@ void* OPS_FiberSection2dThermal() FiberSection2dThermal::FiberSection2dThermal(int tag, int num, Fiber **fibers): SectionForceDeformation(tag, SEC_TAG_FiberSection2dThermal), numFibers(num), sizeFibers(num), theMaterials(0), matData(0),DataMixed(27),AverageThermalElong(2), QzBar(0.0), ABar(0.0), - yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), dedh(2), sT(0)//,theTemperatures(temperatures),theTemperatureFactor(0) + yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), sT(0), Fiber_Tangent(0), Fiber_ElongP(0), dedh(2)//,theTemperatures(temperatures),theTemperatureFactor(0) { if (numFibers != 0) { theMaterials = new UniaxialMaterial *[numFibers]; @@ -145,7 +145,7 @@ FiberSection2dThermal::FiberSection2dThermal(int tag, int num): numFibers(0), sizeFibers(num), theMaterials(0), matData(0), DataMixed(27),AverageThermalElong(2), QzBar(0.0), ABar(0.0), yBar(0.0), - sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), dedh(2), sT(0) + sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), sT(0), Fiber_Tangent(0), Fiber_ElongP(0), dedh(2) { if(sizeFibers > 0) { theMaterials = new UniaxialMaterial *[sizeFibers]; @@ -204,7 +204,7 @@ FiberSection2dThermal::FiberSection2dThermal(int tag, int num, UniaxialMaterial SectionIntegration &si): SectionForceDeformation(tag, SEC_TAG_FiberSection2dThermal), numFibers(num), sizeFibers(num), theMaterials(0), matData(0),DataMixed(27),AverageThermalElong(2), - yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), dedh(2)//,theTemperature(0) + yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), sT(0), Fiber_Tangent(0), Fiber_ElongP(0), dedh(2)//,theTemperature(0) { if (numFibers != 0) { theMaterials = new UniaxialMaterial *[numFibers]; @@ -286,7 +286,7 @@ FiberSection2dThermal::FiberSection2dThermal(int tag, int num, UniaxialMaterial FiberSection2dThermal::FiberSection2dThermal(): SectionForceDeformation(0, SEC_TAG_FiberSection2dThermal), numFibers(0), sizeFibers(0), theMaterials(0), matData(0),DataMixed(27),AverageThermalElong(2), - yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), dedh(2)//, theTemperatures(0),theTemperatureFactor(0) + yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), Fiber_Tangent(0), Fiber_ElongP(0), dedh(2)//, theTemperatures(0),theTemperatureFactor(0) { s = new Vector(sData, 2); ks = new Matrix(kData, 2, 2); @@ -1303,11 +1303,12 @@ FiberSection2dThermal::setParameter(const char **argv, int argc, Parameter ¶ } // Check if it belongs to the section integration - else if (strstr(argv[0],"integration") != 0) + if (strstr(argv[0],"integration") != 0) { if (sectionIntegr != 0) return sectionIntegr->setParameter(&argv[1], argc-1, param); else return -1; + } int ok = 0; diff --git a/SRC/material/section/FiberSection3dThermal.cpp b/SRC/material/section/FiberSection3dThermal.cpp index dddf18e250..a1aa2ec19b 100644 --- a/SRC/material/section/FiberSection3dThermal.cpp +++ b/SRC/material/section/FiberSection3dThermal.cpp @@ -52,7 +52,7 @@ FiberSection3dThermal::FiberSection3dThermal(int tag, int num, Fiber **fibers): SectionForceDeformation(tag, SEC_TAG_FiberSection3dThermal), numFibers(num), sizeFibers(num), theMaterials(0), matData(0), QzBar(0.0), QyBar(0.0), ABar(0.0), - yBar(0.0), zBar(0.0), e(3), eCommit(3), s(0), ks(0), sT(0) + yBar(0.0), zBar(0.0), e(3), eCommit(3), s(0), ks(0), sT(0), Fiber_T(0), Fiber_TMax(0) { if (numFibers != 0) { theMaterials = new UniaxialMaterial *[numFibers]; @@ -137,8 +137,31 @@ FiberSection3dThermal::FiberSection3dThermal(int tag, int num): SectionForceDeformation(tag, SEC_TAG_FiberSection3dThermal), numFibers(0), sizeFibers(num), theMaterials(0), matData(0), QzBar(0.0), QyBar(0.0), ABar(0.0), - yBar(0.0), zBar(0.0), e(3), eCommit(3), s(0), ks(0), sT(0) + yBar(0.0), zBar(0.0), e(3), eCommit(3), s(0), ks(0), sT(0), Fiber_T(0), Fiber_TMax(0) { + if(sizeFibers != 0) { + theMaterials = new UniaxialMaterial *[sizeFibers]; + + if (theMaterials == 0) { + opserr << "FiberSection3dThermal::FiberSection3dThermal -- failed to allocate Material pointers\n"; + exit(-1); + } + + matData = new double [sizeFibers*3]; + + if (matData == 0) { + opserr << "FiberSection3dThermal::FiberSection3dThermal -- failed to allocate double array for material data\n"; + exit(-1); + } + + for (int i = 0; i < sizeFibers; i++) { + matData[i*3] = 0.0; + matData[i*3+1] = 0.0; + matData[i*3+2] = 0.0; + theMaterials[i] = 0; + } + } + s = new Vector(sData, 3); ks = new Matrix(kData, 3, 3); @@ -179,7 +202,7 @@ FiberSection3dThermal::FiberSection3dThermal(): SectionForceDeformation(0, SEC_TAG_FiberSection3dThermal), numFibers(0), sizeFibers(0), theMaterials(0), matData(0), QzBar(0.0), QyBar(0.0), ABar(0.0), - yBar(0.0), zBar(0.0), e(3), eCommit(3), s(0), ks(0) + yBar(0.0), zBar(0.0), e(3), eCommit(3), s(0), ks(0), sT(0), Fiber_T(0), Fiber_TMax(0) { s = new Vector(sData, 3); ks = new Matrix(kData, 3, 3); @@ -312,6 +335,11 @@ FiberSection3dThermal::~FiberSection3dThermal() delete sT; //if (TemperatureTangent != 0) //delete [] TemperatureTangent; + + if (Fiber_T != 0) + delete [] Fiber_T; + if (Fiber_TMax != 0) + delete [] Fiber_TMax; } int diff --git a/SRC/material/section/TclModelBuilderSectionCommand.cpp b/SRC/material/section/TclModelBuilderSectionCommand.cpp index 557833c1fb..52a97d2fdf 100755 --- a/SRC/material/section/TclModelBuilderSectionCommand.cpp +++ b/SRC/material/section/TclModelBuilderSectionCommand.cpp @@ -100,13 +100,6 @@ using std::ios; #include -extern int OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain); - extern void *OPS_ElasticSection(void); extern void *OPS_ElasticWarpingShearSection2d(); extern void *OPS_ElasticTubeSection3d(void); @@ -728,7 +721,7 @@ TclModelBuilderSectionCommand (ClientData clientData, Tcl_Interp *interp, int ar } //end Yuli Huang & Xinzheng Lu LayeredShellFiberSection - //-----Thermo-mechanical shell sections added by L.Jiang [SIF] + //-----Thermo-mechanical shell sections added by L.Jiang [SIF] else if (strcmp(argv[1], "PlateFiberThermal") == 0) { if (argc < 5) { opserr << "WARNING insufficient arguments\n"; diff --git a/SRC/material/section/fiber/UniaxialFiber2d.h b/SRC/material/section/fiber/UniaxialFiber2d.h index 74b5f2df86..5c6a49f98e 100644 --- a/SRC/material/section/fiber/UniaxialFiber2d.h +++ b/SRC/material/section/fiber/UniaxialFiber2d.h @@ -40,7 +40,7 @@ #ifndef UniaxialFiber2d_h #define UniaxialFiber2d_h -#include +#include "Fiber.h" #include #include diff --git a/SRC/material/section/fiber/UniaxialFiber3d.h b/SRC/material/section/fiber/UniaxialFiber3d.h index 191f64e0fd..5075231208 100644 --- a/SRC/material/section/fiber/UniaxialFiber3d.h +++ b/SRC/material/section/fiber/UniaxialFiber3d.h @@ -42,7 +42,7 @@ #define UniaxialFiber3d_h #include -#include +#include "Fiber.h" class UniaxialMaterial; class Response; diff --git a/SRC/material/uniaxial/ASD_SMA_3K.cpp b/SRC/material/uniaxial/ASD_SMA_3K.cpp new file mode 100644 index 0000000000..c752aa64bc --- /dev/null +++ b/SRC/material/uniaxial/ASD_SMA_3K.cpp @@ -0,0 +1,625 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.0 $ +// $Date: 2020-09-01 11:29:01 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/ASD_SMA_3K.cpp,v $ + +// Written: Luca Aceto +// Created: Aug +// Revision: A +// +// Description: This file contains the class implementation for ASD_SMA_3K. + +/* +ASD_SMA_3K is written by Eng. Luca Aceto (luca.aceto@unich.it), University of Chieti-Pescara, InGeo department in collaboration with ASDEA Software Technology: https://asdeasoft.net + + +This material is a modified version of Self Centering Material written by JAE at Oct 2007 +With ASD_SMA_3K it is possible to replicate the behavior of SMA material with a different unloading stiffness (k3) + + k1 = Load stiffness + k2 = Post-Activation Stiffness (0<$k2<$k1) + k3 = Unload stiffness + sigAct = Forward Activation Stress/Force + beta= Ratio of Forward to Reverse Activation Stress/Force + + +ASD_SMA_3K matTag? k1? k2? k3? sigF? beta? + +*/ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* static class instance counter */ +static int ASD_SMA3K_counter = 0; + +void* OPS_ASD_SMA_3K() +{ + + + + int numdata = OPS_GetNumRemainingInputArgs(); + if (numdata < 5) { + opserr << "WARNING: Insufficient arguments\n"; + opserr << "Want: uniaxialMaterial ASD_SMA_3K matTag? k1? k2? k3? sigF? beta?"; + return 0; + } + + int tag; + numdata = 1; + if (OPS_GetIntInput(&numdata,&tag) < 0) { + opserr << "WARNING invalid tag\n"; + return 0; + } + + double data[5] = {0,0,0,0,0}; + numdata = OPS_GetNumRemainingInputArgs(); + if (numdata > 5) { + numdata = 5; + } + if (OPS_GetDoubleInput(&numdata,data)) { + opserr << "WARNING invalid double inputs\n"; + return 0; + } + + UniaxialMaterial* mat = new ASD_SMA_3K(tag,data[0],data[1],data[2],data[3],data[4]); + if (mat == 0) { + opserr << "WARNING: failed to create ASD_SMA_3K material\n"; + return 0; + } + + return mat; +} + +ASD_SMA_3K::ASD_SMA_3K(int tag, double K1, double K2, double K3, + double fa, double b) + : UniaxialMaterial(tag,MAT_TAG_ASD_SMA_3K), + k1(K1), k2(K2), k3(K3), ActF(fa), beta(b) +{ + // on first call + if (ASD_SMA3K_counter == 0) { + ASD_SMA3K_counter++; + opserr << + "\n*******************************************************************************************\n" + "* ASD_SMA_3K - Written by Eng. Luca Aceto, University of Chieti-Pescara, InGeo department *\n" + "* in collaboration with ASDEA Software Technology *\n" + "* Eng. Luca Aceto luca.aceto@unich.it *\n" + "* ASDEA Software Technology: https://asdeasoft.net *\n" + "* STKO (Scientific ToolKit for OpenSees): https://asdeasoft.net/stko/ *\n" + "*******************************************************************************************\n" + ; + } + // Find Equivalent Slip Force + ActDef = ActF / k1; + + + // Initialize variables + this->revertToStart(); + +} + +ASD_SMA_3K::ASD_SMA_3K() + : UniaxialMaterial(0,MAT_TAG_ASD_SMA_3K), + k1(0.0), k2(0.0), k3(0.0), ActF(0.0), beta(0.0) +{ + // Initialize variables + ActDef = 0; + + this->revertToStart(); + +} + +ASD_SMA_3K::~ASD_SMA_3K() +{ + +} + +int + +ASD_SMA_3K::setTrialStrain(double strain, double strainRate) +{ + + + diffStrain = strain - Cstrain; + + if (fabs(diffStrain) < DBL_EPSILON) + return 0; + + // Set total strain + Tstrain = strain; + // Tstrain = Tstrain - CslipStrain; + + // Middle Elastic Portion (outside any upper or lower activation) + // Entirely elastic response + if (fabs(Tstrain) <= ((1 - beta) * ActF / k1)) { + + Tstress = k1 * Tstrain; + Ttangent = k1; + + + + TupperStrainPos = ActDef; + TupperStressPos = ActF; + + TupperStrainNeg = -ActDef; + TupperStressNeg = -ActF; + + No_Y_Pos = 0; + No_Y_Neg = 0; + + } + else { + + // Positive Quadrant (Top Right) where strain >= 0 + if (Tstrain >= 0) { + + TupperStrainNeg = -ActDef; + TupperStressNeg = -ActF; + + // Linear range movement (no upper or lower activation) + if ((Tstrain >= ClowerStrainPos) && + (Tstrain <= CupperStrainPos)) { + + if (diffStrain < DBL_EPSILON) { + if (No_Y_Pos == 1) { + Tstress = Cstress + diffStrain * k3; + Ttangent = k3; + + TupperStrainPos = (k1 * Tstrain - Tstress - k2 * ActDef + ActF) / (k1 - k2); + TupperStressPos = k2 * TupperStrainPos - k2 * ActDef + ActF; + } + else { + Tstress = std::fmin(Cstress + diffStrain * k1, Tstrain * k1); + Ttangent = k1; + } + } + else if (diffStrain > DBL_EPSILON) { + + if (No_Y_Pos == 1) { + Tstress = std::fmin(Cstress + diffStrain * k1,Tstrain * k1); + Ttangent = k1; + No_k2_Pos = 0; + + TupperStrainPos = (k1 * Tstrain - Tstress - k2 * ActDef + ActF) / (k1 - k2); + TupperStressPos = k2 * TupperStrainPos - k2 * ActDef + ActF; + + } else if (No_Y_Pos == 0) { + + Tstress = std::fmin((Tstrain - CactivStrainPos) * k1,Tstrain*k1); + Ttangent = k1; + No_k2_Pos = 0; + } + + + } + + } + // Upper Activation + else if (Tstrain > CupperStrainPos) { + + No_Y_Pos = 1; + + TupperStressPos = CupperStressPos + (Tstrain - CupperStrainPos) * k2; + TupperStrainPos = Tstrain; + + X = (-k3 * TupperStrainPos + TupperStressPos) / (k1 - k3); + Y = k1 * ((-k3 * TupperStrainPos + TupperStressPos) / (k1 - k3)); + + TlowerStrainPos = (TupperStressPos - TupperStrainPos * k3 - ActF * (1 - beta) * (1 - (k2 / k1))) / (k2 - k3); + TlowerStressPos = k2 * ((TupperStressPos - TupperStrainPos * k3 - ActF * (1 - beta) * (1 - (k2 / k1))) / (k2 - k3)) + ActF * (1 - beta) * (1 - (k2 / k1)); + No_k2_Pos = 0; + + if (TlowerStrainPos < X) { + TlowerStrainPos = X; + TlowerStressPos = Y; + No_k2_Pos = 1; + } + + Tstress = TupperStressPos; + TactivStrainPos = TupperStrainPos - Tstress / k3; + + Ttangent = k2; + + + } + + else { // Tstrain < ClowerStrainPos + + if (k1 * Tstrain <= ClowerStressPos && No_k2_Pos == 1) { + Tstress = std::fmin((Tstrain - CactivStrainPos) * k1, Tstrain * k1); + Ttangent = k1; + + TupperStrainPos = ActDef; + TupperStressPos = ActF; + + TactivStrainPos = Tstrain - Tstress / k1; + + + } + else { + TlowerStressPos = ClowerStressPos + + (Tstrain - ClowerStrainPos) * k2; + TlowerStrainPos = Tstrain; + TupperStrainPos = Tstrain + beta * ActF / k1; + TupperStressPos = TlowerStressPos + beta * ActF; + Tstress = TlowerStressPos; + TactivStrainPos = TlowerStrainPos - Tstress / k1; + + Ttangent = k2; + } + } + } + + // Negative Quadrant (Bottom Left) where strain < 0 + else { // Tstrain < 0) + + TupperStrainPos = ActDef; + TupperStressPos = ActF; + + // Linear range movement (no upper or + // lower activation) + if ((Tstrain <= ClowerStrainNeg) && + (Tstrain >= CupperStrainNeg)) { + + if (diffStrain > DBL_EPSILON) { + if (No_Y_Neg == 1) { + Tstress = Cstress+ diffStrain * k3; + Ttangent = k3; + + TupperStrainNeg = (k1 * Tstrain - Tstress + k2 * ActDef - ActF) / (k1 - k2); + TupperStressNeg = k2 * TupperStrainNeg + k2 * ActDef - ActF; + } + else { + Tstress = std::fmax(Cstress + diffStrain * k1, Tstrain * k1); + Ttangent = k1; + } + } + else if (diffStrain < DBL_EPSILON) { + + if (No_Y_Neg == 1) { + Tstress = std::fmax(Cstress + diffStrain * k1, Tstrain * k1); + Ttangent = k1; + No_k2_Neg = 0; + + TupperStrainNeg = (k1 * Tstrain - Tstress + k2 * ActDef - ActF) / (k1 - k2); + TupperStressNeg = k2 * TupperStrainNeg + k2 * ActDef - ActF; + + } + else if (No_Y_Neg == 0) { + Tstress = std::fmax((Tstrain - CactivStrainNeg) * k1, Tstrain * k1); + Ttangent = k1; + No_k2_Neg = 0; + + + } + } + + } + // Upper Activation + else if (Tstrain < CupperStrainNeg) { + + No_Y_Neg = 1; + + TupperStressNeg = CupperStressNeg + (Tstrain - CupperStrainNeg) * k2; + TupperStrainNeg = Tstrain; + + X = (-k3 * TupperStrainNeg + TupperStressNeg) / (k1 - k3); + Y = k1 * ((-k3 * TupperStrainNeg + TupperStressNeg) / (k1 - k3)); + + TlowerStrainNeg = (TupperStressNeg - TupperStrainNeg * k3 + ActF * (1 - beta) * (1 - (k2 / k1))) / (k2 - k3); + TlowerStressNeg = k2 * ((TupperStressNeg - TupperStrainNeg * k3 + ActF * (1 - beta) * (1 - (k2 / k1))) / (k2 - k3)) - ActF * (1 - beta) * (1 - (k2 / k1)); + + + No_k2_Neg = 0; + + if (TlowerStrainNeg > X) { + TlowerStrainNeg = X; + TlowerStressNeg = Y; + No_k2_Neg = 1; + } + + Tstress = TupperStressNeg; + TactivStrainNeg = TupperStrainNeg - Tstress / k3; + + Ttangent = k2; + } + // Lower Activation + else { // Tstrain > ClowerStrainNeg + + + if (k1 * Tstrain >= ClowerStressNeg && No_k2_Neg == 1) { + Tstress = std::fmax((Tstrain - CactivStrainNeg) * k1, Tstrain * k1); + Ttangent = k1; + + TupperStrainNeg = -ActDef; + TupperStressNeg = -ActF; + + TactivStrainNeg = Tstrain - Tstress / k1; + + + } + else { + TlowerStressNeg = ClowerStressNeg + (Tstrain - ClowerStrainNeg) * k2; + TlowerStrainNeg = Tstrain; + TupperStrainNeg = Tstrain - beta * ActF / k1; + TupperStressNeg = TlowerStressNeg - beta * ActF; + Tstress = TlowerStressNeg; + TactivStrainNeg = TlowerStrainNeg - Tstress / k1; + + Ttangent = k2; + } + + + + } + } + + } + + + + return 0; +} + +double +ASD_SMA_3K::getStress(void) +{ + return Tstress; +} + +double +ASD_SMA_3K::getTangent(void) +{ + return Ttangent; +} + +double +ASD_SMA_3K::getStrain(void) +{ + return Tstrain; +} + +int +ASD_SMA_3K::commitState(void) +{ + + // Commit trial history variables + CactivStrainPos = TactivStrainPos; + CactivStrainNeg = TactivStrainNeg; + CupperStrainPos = TupperStrainPos; + ClowerStrainPos = TlowerStrainPos; + CupperStressPos = TupperStressPos; + ClowerStressPos = TlowerStressPos; + CupperStrainNeg = TupperStrainNeg; + ClowerStrainNeg = TlowerStrainNeg; + CupperStressNeg = TupperStressNeg; + ClowerStressNeg = TlowerStressNeg; + Cstrain = Tstrain; + Cstress = Tstress; + Ctangent = Ttangent; + + CLastStrain = TLastStrain; + + return 0; +} + +int +ASD_SMA_3K::revertToLastCommit(void) +{ + Tstrain = Cstrain; + Tstress = Cstress; + Ttangent = Ctangent; + + return 0; +} + +int +ASD_SMA_3K::revertToStart(void) +{ + // Reset committed history variables + CactivStrainPos = 0.0; + CactivStrainNeg = 0.0; + CupperStrainPos = ActDef; + ClowerStrainPos = (1-beta) * ActDef; + CupperStressPos = ActF; + ClowerStrainPos = (1 - beta) * ActDef; + CupperStrainNeg = -CupperStrainPos; + ClowerStrainNeg = -ClowerStrainPos; + CupperStressNeg = -CupperStressPos; + ClowerStressNeg = -ClowerStressPos; + + CLastStrain = 0.0; + + // Reset trial history variables + TactivStrainPos = 0.0; + TactivStrainNeg = 0.0; + TupperStrainPos = ActDef; + TlowerStrainPos = (1-beta) * ActDef; + TupperStressPos = ActF; + TlowerStressPos = (1-beta) * ActF; + TupperStrainNeg = -CupperStrainPos; + TlowerStrainNeg = -ClowerStrainPos; + TupperStressNeg = -CupperStressPos; + TlowerStressNeg = -ClowerStressPos; + + TLastStrain = 0.0; + + // Initialize state variables + Tstrain = 0.0; + Tstress = 0.0; + Ttangent = k1; + + Cstrain = 0.0; + + No_k2_Pos = 0; + No_k2_Neg = 0; + No_Y_Pos = 0; + No_Y_Neg = 0; + + return 0; +} + +UniaxialMaterial * +ASD_SMA_3K::getCopy(void) +{ + ASD_SMA_3K *theCopy = + new ASD_SMA_3K(this->getTag(), k1, k2, k3, ActF, beta); + + // Copy committed history variables + theCopy->CactivStrainPos = CactivStrainPos; + theCopy->CactivStrainNeg = CactivStrainNeg; + theCopy->CupperStrainPos = CupperStrainPos; + theCopy->ClowerStrainPos = ClowerStrainPos; + theCopy->CupperStressPos = CupperStressPos; + theCopy->ClowerStressPos = ClowerStressPos; + theCopy->CupperStrainNeg = CupperStrainNeg; + theCopy->ClowerStrainNeg = ClowerStrainNeg; + theCopy->CupperStressNeg = CupperStressNeg; + theCopy->ClowerStressNeg = ClowerStressNeg; + + theCopy->CLastStrain = CLastStrain; + + // Copy trial history variables + theCopy->TactivStrainPos = TactivStrainPos; + theCopy->TactivStrainNeg = TactivStrainNeg; + theCopy->TupperStrainPos = TupperStrainPos; + theCopy->TlowerStrainPos = TlowerStrainPos; + theCopy->TupperStressPos = TupperStressPos; + theCopy->TlowerStressPos = TlowerStressPos; + theCopy->TupperStrainNeg = TupperStrainNeg; + theCopy->TlowerStrainNeg = TlowerStrainNeg; + theCopy->TupperStressNeg = TupperStressNeg; + theCopy->TlowerStressNeg = TlowerStressNeg; + + theCopy->TLastStrain = TLastStrain; + + // Copy trial state variables + theCopy->Tstrain = Tstrain; + theCopy->Tstress = Tstress; + theCopy->Ttangent = Ttangent; + + theCopy->Cstrain = Cstrain; + + return theCopy; +} + +int +ASD_SMA_3K::sendSelf(int cTag, Channel &theChannel) +{ + int res = 0; + + static Vector data(23); + + data(0) = this->getTag(); + data(1) = k1; + data(2) = k2; + data(3) = k3; + data(4) = ActF; + data(5) = beta; + data(6) = ActDef; + data(7) = CactivStrainPos; + data(8) = CactivStrainNeg; + data(9) = CupperStrainPos; + data(10) = ClowerStrainPos; + data(11) = CupperStressPos; + data(12) = ClowerStressPos; + data(13) = CupperStrainNeg; + data(14) = ClowerStrainNeg; + data(15) = CupperStressNeg; + data(16) = ClowerStressNeg; + data(17) = Tstrain; + data(18) = Tstress; + data(19) = Ttangent; + data(20) = Cstrain; + data(21) = TLastStrain; + data(22) = CLastStrain; + + res = theChannel.sendVector(this->getDbTag(), cTag, data); + if (res < 0) + opserr << "ASD_SMA_3K::sendSelf() - failed to send data\n"; + + return res; +} + +int +ASD_SMA_3K::recvSelf(int cTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + + static Vector data(23); + res = theChannel.recvVector(this->getDbTag(), cTag, data); + + if (res < 0) { + opserr << "ASD_SMA_3K::recvSelf() - failed to receive data\n"; + this->setTag(0); + } + else { + this->setTag((int)data(0)); + k1 = data(1); + k2 = data(2); + k3 = data(3); + ActF = data(4); + beta = data(5); + ActDef = data(6); + CactivStrainPos = data(7); + CactivStrainNeg = data(8); + CupperStrainPos = data(9); + ClowerStrainPos = data(10); + CupperStressPos = data(11); + ClowerStressPos = data(12); + CupperStrainNeg = data(13); + ClowerStrainNeg = data(14); + CupperStressNeg = data(15); + ClowerStressNeg = data(16); + Tstrain = data(17); + Tstress = data(18); + Ttangent = data(19); + Cstrain = data(20); + TLastStrain = data(21) ; + CLastStrain=data(22) ; + } + + return res; +} + +void +ASD_SMA_3K::Print(OPS_Stream &s, int flag) +{ + s << "ASD_SMA_3K, tag: " << this->getTag() << endln; + s << " k1: " << k1 << endln; + s << " k2: " << k2 << endln; + s << " k3: " << k3 << endln; + s << " ActF: " << ActF << endln; + s << " beta: " << beta << endln; +} + diff --git a/SRC/material/uniaxial/ASD_SMA_3K.h b/SRC/material/uniaxial/ASD_SMA_3K.h new file mode 100644 index 0000000000..10e3e61d06 --- /dev/null +++ b/SRC/material/uniaxial/ASD_SMA_3K.h @@ -0,0 +1,148 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.0 $ +// $Date: 2020-09-01 11:29:01 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/ASD_SMA_3K.cpp,v $ + +// Written: Luca Aceto +// Created: Aug +// Revision: A +// +// Description: This file contains the class implementation for ASD_SMA_3K. + +#ifndef ASD_SMA_3K_h +#define ASD_SMA_3K_h + +/* +ASD_SMA_3K is written by Eng. Luca Aceto (luca.aceto@unich.it), University of Chieti-Pescara, InGeo department in collaboration with ASDEA Software Technology: https://asdeasoft.net + + +This material is a modified version of Self Centering Material written by JAE at Oct 2007 +With ASD_SMA_3K it is possible to replicate the behavior of SMA material with a different unloading stiffness (k3) + + k1 = Load stiffness + k2 = Post-Activation Stiffness (0<$k2<$k1) + k3 = Unload stiffness + sigAct = Forward Activation Stress/Force + beta= Ratio of Forward to Reverse Activation Stress/Force + + +ASD_SMA_3K matTag? k1? k2? k3? sigF? beta? + +*/ + +#include + +class ASD_SMA_3K : public UniaxialMaterial +{ + public: + ASD_SMA_3K(int tag, double k1, double k2, double k3, + double ActF, double beta); + ASD_SMA_3K(); + ~ASD_SMA_3K(); + + const char *getClassType(void) const {return "ASD_SMA_3K";}; + + int setTrialStrain(double strain, double strainRate = 0.0); + double getStrain(void); + double getStress(void); + double getTangent(void); + double getInitialTangent(void) {return k1;}; + + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + UniaxialMaterial *getCopy(void); + + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + + void Print(OPS_Stream &s, int flag =0); + + protected: + + private: + // Material parameters (from input) + double k1; // Precompression Stiffness + double k2; // Prestress Stiffness + double k3; // Unloading Stiffness + double ActF; // Activation Stress/Force + double beta; // Flag-Shape Parameter + + // Extra Calculated Material Parameters + double ActDef; // Actvation Strain/Deformation + + double diffStrain; // Difference of strain from last step + + // Committed history variables + double CactivStrainPos; // Committed activation strain (Pos Quad) + double CactivStrainNeg; // Committed activation strain (Neg Quad) + double CupperStrainPos; // Committed upper activation strain (Pos Quad) + double ClowerStrainPos; // Committed lower activation strain (Pos Quad) + double CupperStressPos; // Committed upper activation stress (Pos Quad) + double ClowerStressPos; // Committed lower activation stress (Pos Quad) + double CupperStrainNeg; // Committed upper activation strain (Neg Quad) + double ClowerStrainNeg; // Committed lower activation strain (Neg Quad) + double CupperStressNeg; // Committed upper activation stress (Neg Quad) + double ClowerStressNeg; // Committed lower activation stress (Neg Quad) + + double CLastStrain; + + // Trial history variables + double TactivStrainPos; // Trial activation strain (Pos Quad) + double TactivStrainNeg; // Trial activation strain (Neg Quad) + double TupperStrainPos; // Trial upper activation strain (Pos Quad) + double TlowerStrainPos; // Trial lower activation strain (Pos Quad) + double TupperStressPos; // Trial upper activation stress (Pos Quad) + double TlowerStressPos; // Trial lower activation stress (Pos Quad) + double TupperStrainNeg; // Trial upper activation strain (Neg Quad) + double TlowerStrainNeg; // Trial lower activation strain (Neg Quad) + double TupperStressNeg; // Trial upper activation stress (Neg Quad) + double TlowerStressNeg; // Trial lower activation stress (Neg Quad) + + double TLastStrain; + + // Trial state variables + double Tstrain; // Trial strain + double Tstress; // Trial stress + double Ttangent; // Trial tangent + + // Committed State Variables + double Cstrain; // Committed Strain + double Cstress; // Committed Strain + double Ctangent; // Committed Strain + + // Intermediate Value + double X; + double Y; + + int No_k2_Pos; + int No_k2_Neg; + int No_Y_Pos; + int No_Y_Neg; + +}; + + +#endif + diff --git a/SRC/material/uniaxial/FatigueMaterial.cpp b/SRC/material/uniaxial/FatigueMaterial.cpp index 8fd5ad1f17..a826179d31 100644 --- a/SRC/material/uniaxial/FatigueMaterial.cpp +++ b/SRC/material/uniaxial/FatigueMaterial.cpp @@ -705,12 +705,6 @@ FatigueMaterial::revertToStart(void) = 1 otherwise */ DL = 0; //Damage if current strain was last peak. - Dmax = 0; - E0 = 0; - m = 0; - minStrain = 0; - maxStrain = 0; - // added 6/9/2006 //values for recorder SR1 = 0; diff --git a/SRC/material/uniaxial/IMKPeakOriented.cpp b/SRC/material/uniaxial/IMKPeakOriented.cpp index f580dc4f57..fc5559ebc3 100644 --- a/SRC/material/uniaxial/IMKPeakOriented.cpp +++ b/SRC/material/uniaxial/IMKPeakOriented.cpp @@ -37,11 +37,11 @@ using namespace std; static int numIMKPeakOrientedMaterials = 0; void * -OPS_IMKPeakOriented(void) +OPS_IMKPeakOriented() { if (numIMKPeakOrientedMaterials == 0) { numIMKPeakOrientedMaterials++; - OPS_Error("\nIMK Model with Peak-Oriented Response - Code by H. ELJISR & A. ELKADY (July-2018)\n", 1); + OPS_Error("IMK Model with Peak-Oriented Response - Code by A. ELKADY & H. ELJISR (July 2020)\n", 1); } // Pointer to a uniaxial material that will be returned @@ -122,205 +122,139 @@ int IMKPeakOriented::setTrialStrain(double strain, double strainRate) fi_1 = fi; ui = U; - kappaF=1; - kappaD=1; - //cout << "***********************" << endln; - //cout << " Excurion=" << Excursion_Flag << " Failure=" << Failure_Flag << endln; - //cout << " STEP: ui_1=" << ui_1 << " ui=" << ui << " fi_1=" << fi_1 << " fi=" << fi << endln; - //cout << " +VE: Uy= " << Uy_pos_j_1 << " Umax= " << Umax_pos_j_1 << " Upeak= " << Upeak_pos_j_1 << " Ubp=" << Ubp_pos_j_1 << " Fpeak= " << Fpeak_pos_j_1 << " Fbp=" << Fbp_pos_j_1 << " KrelA=" << KrelA_pos_j_1 << " KrelB=" << KrelB_pos_j_1 << endln; - //cout << " -VE: Uy=" << Uy_neg_j_1 << " Umax=" << Umax_neg_j_1 << " Upeak=" << Upeak_neg_j_1 << " Ubp=" << Ubp_neg_j_1 << " Fpeak=" << Fpeak_neg_j_1 << " Fbp=" << Fbp_neg_j_1 << " KrelA=" << KrelA_neg_j_1 << " KrelB=" << KrelB_neg_j_1 << endln; + //cout << " +VE: Uy= " << Uy_pos_j_1 << " Umax= " << Umax_pos_j_1 << " Upeak= " << Upeak_pos_j_1 << " Fpeak= " << Fpeak_pos_j_1 << " Krel=" << Krel_j_1 << endln; + //cout << " -VE: Uy=" << Uy_neg_j_1 << " Umax=" << Umax_neg_j_1 << " Upeak=" << Upeak_neg_j_1 << " Fpeak=" << Fpeak_neg_j_1 << " Krel=" << Krel_j_1 << endln; - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //%%%%%%%%%%%%%%%%%%%%%%%%%%% MAIN CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////// MAIN CODE ////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Incremental deformation at current step du = ui - ui_1; - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + if (Failure_Flag != 1) { - //// Positive Loading - if (fi_1 >= 0) { - // Early reloading before new excursion occurs - if ((du > 0) && (du_i_1 < 0) && (fi_1 > 0)) { - //cout << " OK6**" << endln; - - // Reloading stiffness KrelA if reloading is to the left of the break point - if (ui <= Ubp_pos_j_1) { - KrelA_pos_j_1 = (Fbp_pos_j_1 - fi_1) / (Ubp_pos_j_1 - ui_1); - // Reloading stiffness KrelA if reloading is to the right of the break point - } - else { - KrelB_pos_j_1 = (Fpeak_pos_j_1 - fi_1) / (Upeak_pos_j_1 - ui_1); - } - } - // Deformation in first reloading branch KrelA - if ((ui <= Ubp_pos_j_1) && (du > 0)) { - //cout << " OK5**" << endln; - df = KrelA_pos_j_1*du; - Umaxp = ui; - // Deformation in second reloading branch KrelB - } - else if ((ui <= Upeak_pos_j_1) && (du > 0)) { - //cout << " OK4**" << endln; - df = (KrelB_pos_j_1*ui + (Fpeak_pos_j_1 - KrelB_pos_j_1*Upeak_pos_j_1)) - fi_1; - Umaxp = ui; - // Deformation in post-yield branch of the backbone - } - else if ((ui <= Umax_pos_j_1) && (du > 0)) { - //cout << " OK3**" << endln; - df = (Fy_pos_j_1 + Kp_pos_j_1*(ui - Uy_pos_j_1)) - fi_1; - Umaxp = ui; - // Deformation in the post-capping branch of the backbone + + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + ////////////////// INITIAL FLAGS CHECKS AND MAIN POINTS COORDINATES /////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + + + // CHECK FOR UNLOADING + if ((fi_1 > 0) && (du <= 0) && (du*du_i_1 <= 0)) { + Unloading_Flag = 1; + Reversal_Flag = 1; + Reloading_Flag = 0; + K_check=(FLastPeak_pos_j_1-fi_1)/(ULastPeak_pos_j_1-ui_1); + if ((K_check >=1.05*Kul_j_1) || (K_check <=0.95*Kul_j_1)) { // a tailored criteria to avoid registering last peak points during small unload/reload excursions on the unloading branch + FLastPeak_pos_j_1 = fi_1; + ULastPeak_pos_j_1 = ui_1; } - else if ((ui >= Umax_pos_j_1) && (du > 0)) { - //cout << " OK2**" << endln; - - // Deformation in residual branch of backbone - if (ui > Ures_pos_j_1) { - df = Fres_pos_j_1 - fi_1; - if (Fres_pos_j_1 == 0) { - //cout << "Res Fail" << endln; - Failure_Flag = 1; - } - // Deformation in softening branch of the backbone - } - else { - df = (Fmax_pos_j_1 + Kpc_pos_j_1*(ui - Umax_pos_j_1)) - fi_1; - } - Umaxp = ui; - // Deformation in the unloading branch - } - else { - df = Kul_j_1*du; - //cout << " OK1**" << endln; - + } + else if ((fi_1 < 0) && (du > 0) && (du*du_i_1 <= 0)) { + Unloading_Flag = 1; + Reversal_Flag = 1; + Reloading_Flag = 0; + K_check=(FLastPeak_neg_j_1-fi_1)/(ULastPeak_neg_j_1-ui_1); + if ((K_check >=1.01*Kul_j_1) || (K_check <=0.99*Kul_j_1)) { + FLastPeak_neg_j_1 = fi_1; + ULastPeak_neg_j_1 = ui_1; } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Negative Loading } else { - // Early reloading before new excursion occurs - if ((du < 0) && (du_i_1 > 0) && (fi_1 < 0)) { - // Reloading stiffness KrelA if reloading is to the right of the break point - if (ui >= Ubp_neg_j_1) { - KrelA_neg_j_1 = (Fbp_neg_j_1 - fi_1) / (Ubp_neg_j_1 - ui_1); - // Reloading stiffness KrelA if reloading is to the left of the break point - } - else { - KrelB_neg_j_1 = (Fpeak_neg_j_1 - fi_1) / (Upeak_neg_j_1 - ui_1); - } - } - // Deformation in first reloading branch KrelA - if ((ui >= Ubp_neg_j_1) && (du < 0)) { - df = KrelA_neg_j_1*du; - Umaxn = ui; - // Deformation in second reloading branch KrelB - } - else if ((ui >= Upeak_neg_j_1) && (du < 0)) { - df = (KrelB_neg_j_1*ui + (Fpeak_neg_j_1 - KrelB_neg_j_1*Upeak_neg_j_1)) - fi_1; - Umaxn = ui; - // Deformation in post-yield branch of the backbone - } - else if ((ui >= Umax_neg_j_1) && (du < 0)) { - df = (Fy_neg_j_1 + Kp_neg_j_1*(ui - Uy_neg_j_1)) - fi_1; - Umaxn = ui; - // Deformationin the post-capping branch of the backbone - } - else if ((ui <= Umax_neg_j_1) && (du < 0)) { - // Deformation in residual branch of backbone - if (ui < Ures_neg_j_1) { - df = Fres_neg_j_1 - fi_1; - if (Fres_neg_j_1 == 0) { - //cout << " Res Fail" << endln; - Failure_Flag = 1; - } - // Deformation in the softening branch of the backbone - } - else { - df = Fmax_neg_j_1 + Kpc_neg_j_1*(ui - Umax_neg_j_1) - fi_1; - } - Umaxn = ui; - } - else { - // Deformation in the unloading branch - df = Kul_j_1 *du; - } + Reversal_Flag = 0; + } + + // CHECK FOR RELOADING + if ((fi_1 > 0) && (du > 0) && (du_i_1 < 0)) { + Reloading_Flag = 1; + Unloading_Flag = 0; + } + else if ((fi_1 < 0) && (du < 0) && (du_i_1 > 0)) { + Reloading_Flag = 1; + Unloading_Flag = 0; } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Deterioration Parameters - // Internal energy increment - dEi = 0.5*(df + 2 * fi_1)*(du); - //cout << " ENERGY: dEi=" << dEi << " Kul=" << Kul_j_1 << " du=" << du << " df=" << df << endln; - // Positive excursion flag - if ((fi_1 + df >= 0) && (fi_1 < 0)) { + + // CHECK FOR NEW EXCURSION + if ((fi_1 < 0) && (fi_1 + du * Kul_j_1 >= 0)) { Excursion_Flag = 1; - // Negative excursion flag + Reloading_Flag = 0; + Unloading_Flag = 0; + u0 = ui_1 - (fi_1 / Kul_j_1); } - else if ((fi_1 + df <= 0) && (fi_1 > 0)) { + else if ((fi_1 > 0) && (fi_1 + du * Kul_j_1 <= 0)) { Excursion_Flag = 1; + Reloading_Flag = 0; + Unloading_Flag = 0; + u0 = ui_1 - (fi_1 / Kul_j_1); } else { Excursion_Flag = 0; } - // Update beta parameters at new excursion + + // UPDATE GLOBAL PEAK POINTS + if ((fi_1 >= 0) && (ui_1 >= Upeak_pos_j_1)) { + Upeak_pos_j_1 = ui_1; + Fpeak_pos_j_1 = fi_1; + } else if ((fi_1 < 0) && (ui_1 <= Upeak_neg_j_1)) { + Upeak_neg_j_1 = ui_1; + Fpeak_neg_j_1 = fi_1; + } + + // CHECK FOR YIELDING + if ((Upeak_pos_j_1 > Uy_pos_j_1) || (Upeak_neg_j_1 < Uy_neg_j_1)) { + Yield_Flag = 1; + } + + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////// UPDATE DETERIORATION PARAMETERS AND BACKBONE CURVE //////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + + // UPDATE DETERIORATION PARAMETERS AT EACH NEW EXCURSION + //cout << " ENERGY: dEi=" << dEi << " Kul=" << Kul_j_1 << " du=" << du << " df=" << df << endln; + if (Excursion_Flag == 1) { - // Total energy dissipated in all previous excursions - Epj = Energy_Acc + dEi; - // Energy dissipated in previous excursion - Ei = Epj - Energy_Diss; - betaS = pow((Ei / (EtS - Epj)), c_S); - betaC = pow((Ei / (EtC - Epj)), c_C); - betaA = pow((Ei / (EtA - Epj)), c_A); + //Epj = Energy_Acc + dEi; + Ei = fmax(0, Energy_Acc - Energy_Diss); + betaS = pow((Ei / (EtS - Energy_Acc)), c_S); + betaC = pow((Ei / (EtC - Energy_Acc)), c_C); + betaA = pow((Ei / (EtA - Energy_Acc)), c_A); + Energy_Diss = Energy_Acc; } else { - // Total energy dissipated in all previous excursions - Epj = Energy_Diss; + //Epj = Energy_Diss; betaS = 0; betaC = 0; betaA = 0; } - // Onset of unloading - Unloading_Flag = du*du_i_1 < 0 && (ui_1 >= Upeak_pos_j_1 || ui_1 <= Upeak_neg_j_1); - if (Unloading_Flag == 1) { - // Total energy dissipated until point of unloading - EpjK = dEi + Energy_Acc - 0.5*(pow((fi_1 + df), 2)) / Kul_j_1; - // Energy dissipated in current excursion until point of unloading - EiK = EpjK - Energy_Diss; + + if (Reversal_Flag == 1) { + EpjK = Energy_Acc - 0.5*(fi_1 / Kul_j_1)*fi_1; + EiK = Energy_Acc - Energy_Diss + 0.5*(fi_1 / Kul_j_1)*fi_1; betaK = pow((EiK / (EtK - EpjK)), c_K); + Kul_j_1 = Kul_j_1 * (1 - betaK); } else { betaK = 0; } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Target Peak Deformation - New_Peak_Pos_Flag = 0; - New_Peak_Neg_Flag = 0; - // Update target peak deformation for positive loading - if (Umaxp >= Upeak_pos_j_1) { - New_Peak_Pos_Flag = 1; - Upeak_pos_j_1 = Umaxp; - Fpeak_pos_j_1 = fi_1 + df; - // Plastic offset for positive loading - Plastic_Offset_pos_j_1 = Upeak_pos_j_1 - Fpeak_pos_j_1 / Kul_j_1; - } - // Update target peak deformation for negative loading - if (Umaxn <= Upeak_neg_j_1) { - New_Peak_Neg_Flag = 1; - Upeak_neg_j_1 = Umaxn; - Fpeak_neg_j_1 = fi_1 + df; - // Plastic offset for negative loading - Plastic_Offset_neg_j_1 = Upeak_neg_j_1 - Fpeak_neg_j_1 / Kul_j_1; - } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Positive Backbone and Target Peak Point + + // Update Positive Backbone and Target Peak Point if (Excursion_Flag == 1) { // Positive loading backbone - if (fi_1 < 0) { + if ((fi_1 < 0) && (Yield_Flag==1)) { // Basic strength deterioration: Yield point Uy_pos_j_1 = std::max(Uy_pos_j_1 - Fy_pos_j_1 *betaS* D_pos / Ke, Fres_pos_j_1 / Ke); Fy_pos_j_1 = std::max(Fy_pos_j_1 *(1 - betaS* D_pos), Fres_pos_j_1); @@ -341,30 +275,25 @@ int IMKPeakOriented::setTrialStrain(double strain, double strainRate) Umax_pos_j_1 = sPCpcp; // Accelerated reloading stiffness deterioration: Target peak deformation point Upeak_pos_j_1 = (1 + betaA* D_pos)*Upeak_pos_j_1; - // Target peak deformation in reloading branch of the updated backbone - if (Upeak_pos_j_1 <= Uy_pos_j_1) { + if (Upeak_pos_j_1 <= Uy_pos_j_1) { Fpeak_pos_j_1 = Ke*Upeak_pos_j_1; // Target peak deformation in post-yield branch of the updated backbone - } - else if (Upeak_pos_j_1 <= Umax_pos_j_1) { + } else if (Upeak_pos_j_1 <= Umax_pos_j_1) { Fpeak_pos_j_1 = Kp_pos_j_1 *(Upeak_pos_j_1 - Uy_pos_j_1) + Fy_pos_j_1; // Target peak deformation in post-capping branch of the updated backbone - } - else { + } else { Fpeak_pos_j_1 = max(Kpc_pos_j_1*(Upeak_pos_j_1 - Umax_pos_j_1) + Fmax_pos_j_1, Fres_pos_j_1); } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Negative Backbone and Target Peak Point - } - else { + } + else if ((fi_1 >= 0) && (Yield_Flag==1)) { + // Update Negative Backbone and Target Peak Point // Basic strength deterioration: Yield point Uy_neg_j_1 = min(Uy_neg_j_1 - Fy_neg_j_1 *betaS* D_neg / Ke, Fres_neg_j_1 / Ke); Fy_neg_j_1 = min(Fy_neg_j_1 *(1 - betaS* D_neg), Fres_neg_j_1); // Basic strength deterioration: Post-yield stiffness if (Fy_neg_j_1 != Fres_neg_j_1) { Kp_neg_j_1 = Kp_neg_j_1 *(1 - betaS* D_neg); - } - else { + } else { Kp_neg_j_1 = 0; } // Basic strength deterioration: Capping point @@ -391,97 +320,236 @@ int IMKPeakOriented::setTrialStrain(double strain, double strainRate) } } } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Krel Based on New Peak Targets at New Positive Excursion - if ((fi_1 + df >= 0) && (fi_1 < 0)) { - Fp = kappaF*Fpeak_pos_j_1; - // Deformation at reloading - u0 = ui_1 - (fi_1) / Kul_j_1; - if (u0 < 0) { - // Deformation at break point - Ubp_pos_j_1 = (1 - kappaD)*Plastic_Offset_pos_j_1; - // Force at break point - Fbp_pos_j_1 = Fp*(Ubp_pos_j_1 - u0) / (Upeak_pos_j_1 - u0); - } - // Reloading is to the left of the break point - if (u0 < Ubp_pos_j_1) { - // Reloading stiffness KrelA after new excursion - KrelA_pos_j_1 = (Fbp_pos_j_1) / (Ubp_pos_j_1 - u0); - // Reloading stiffness KrelB after new excursion - KrelB_pos_j_1 = (Fpeak_pos_j_1 - Fbp_pos_j_1) / (Upeak_pos_j_1 - Ubp_pos_j_1); - df = ((ui - u0)*KrelA_pos_j_1) - fi_1; - // Reloading is to the right of the break point + + // Update Deformation at Residual Points + Ures_pos_j_1 = (Fres_pos_j_1 - Fmax_pos_j_1 + Kpc_pos_j_1 * Umax_pos_j_1) / Kpc_pos_j_1; + Ures_neg_j_1 = (Fres_neg_j_1 - Fmax_neg_j_1 + Kpc_neg_j_1 * Umax_neg_j_1) / Kpc_neg_j_1; + + // CHECK TARGET POINT: LAST CYCLE PEAK or GLOBAL PEAK + if (Excursion_Flag == 1) { + if (du >= 0) { + Krel_LastPeak = FLastPeak_pos_j_1 / (ULastPeak_pos_j_1 - u0); + Krel_GlobalPeak = Fpeak_pos_j_1 / (Upeak_pos_j_1 - u0); } else { - // Reloading stiffness after new excursion - KrelB_pos_j_1 = (Fpeak_pos_j_1) / (Upeak_pos_j_1 - u0); - df = ((ui - u0)*KrelB_pos_j_1) - fi_1; - } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Krel Based on New Peak Targets at New Negative Excursion - } - else if ((fi_1 + df < 0) && (fi_1 > 0)) { - Fp = kappaF*Fpeak_neg_j_1; - // Deformation at reloading - u0 = ui_1 - (fi_1) / Kul_j_1; - if (u0 > 0) { - // Deformation at break point - Ubp_neg_j_1 = (1 - kappaD)*Plastic_Offset_neg_j_1; - // Force at break point - Fbp_neg_j_1 = Fp*(Ubp_neg_j_1 - u0) / (Upeak_neg_j_1 - u0); + Krel_LastPeak = FLastPeak_neg_j_1 / (ULastPeak_neg_j_1 - u0); + Krel_GlobalPeak = Fpeak_neg_j_1 / (Upeak_neg_j_1 - u0); } - // Reloading is to the right of the break point - if (u0 > Ubp_neg_j_1) { - // Reloading stiffness KrelA after new excursion - KrelA_neg_j_1 = (Fbp_neg_j_1) / (Ubp_neg_j_1 - u0); - // Reloading stiffness KrelB after new excursion - KrelB_neg_j_1 = (Fpeak_neg_j_1 - Fbp_neg_j_1) / (Upeak_neg_j_1 - Ubp_neg_j_1); - df = ((ui - u0)*KrelA_neg_j_1) - fi_1; - // Reloading is to the left of the break point + + if ((du>=0) && (FLastPeak_pos_j_1 >= Fpeak_pos_j_1)) { + TargetPeak_Flag=0; + } else if ((du<=0) && (FLastPeak_neg_j_1 <= Fpeak_neg_j_1)) { + TargetPeak_Flag=0; + } else if (abs(Krel_LastPeak) <= abs(Krel_GlobalPeak)) { + TargetPeak_Flag = 0; } else { - // Reloading stiffness after new excursion - KrelB_neg_j_1 = (Fpeak_neg_j_1) / (Upeak_neg_j_1 - u0); - df = ((ui - u0)*KrelB_neg_j_1) - fi_1; + TargetPeak_Flag = 1; } } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Unloading Stiffness - if (Unloading_Flag == 1) { - Kul_j_1 = (1 - betaK)*Kul_j_1; - df = Kul_j_1*du; - } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Deformation at Residual Points - // Deformation at residual onset for positive backbone - Ures_pos_j_1 = (Fres_pos_j_1 - Fmax_pos_j_1 + Kpc_pos_j_1 * Umax_pos_j_1) / Kpc_pos_j_1; - // Deformation at residual onset for negative backbone - Ures_neg_j_1 = (Fres_neg_j_1 - Fmax_neg_j_1 + Kpc_neg_j_1 * Umax_neg_j_1) / Kpc_neg_j_1; - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Force - fi = fi_1 + df; - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Refine Peaks - if (New_Peak_Pos_Flag == 1) { - Fpeak_pos_j_1 = fi; + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////// COMPUTE FORCE INCREMENT ///////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + + // Positive Force + if (fi_1 + du * Kul_j_1 >= 0) { + + // CASE 0: At THE ELASTIC SLOPE + if ((ui>=0) && (Upeak_pos_j_1 <= Uy_pos_j_1) && (Yield_Flag==0)) { + if (ui >= Uy_pos_j_1) { + df = Ke*(Uy_pos_j_1 - ui_1) + Kp_pos_j_1*(ui - Uy_pos_j_1); + } else { + df = du * Ke; + } + //cout << " Case = 0+" << endln; + + // CASE 1: EACH NEW EXCURSION + } else if (Excursion_Flag==1) { + if (TargetPeak_Flag==0) { + Krel_j_1 = Fpeak_pos_j_1 / (Upeak_pos_j_1 - u0); + } else { + Krel_j_1 = FLastPeak_pos_j_1 / (ULastPeak_pos_j_1 - u0); + } + df = Kul_j_1*(u0 - ui_1) + Krel_j_1*(ui - u0); + //cout << " Case = 1+" << endln; + + // CASE 2: WHEN RELOADING + } else if ((Reloading_Flag==1) && (ui <= ULastPeak_pos_j_1)) { + df = du * Kul_j_1; + //cout << " Case = 2+" << endln; + + // CASE 2: WHEN UNLOADING + } else if (Unloading_Flag==1) { + df = du * Kul_j_1; + //cout << " Case = 2+" << endln; + + // CASE 3: WHEN RELOADING BUT BETWEEN LAST CYCLE PEAK POINT AND GLOBAL PEAK POINT + } else if ((Reloading_Flag==1) && (ui >= ULastPeak_pos_j_1) && (ui <= Upeak_pos_j_1)) { + Krel_j_1 = (Fpeak_pos_j_1 - FLastPeak_pos_j_1) / (Upeak_pos_j_1 - ULastPeak_pos_j_1); + if (ui_1 <= ULastPeak_pos_j_1) { + df = Kul_j_1*(ULastPeak_pos_j_1 - ui_1) + Krel_j_1*(ui - ULastPeak_pos_j_1); + } else { + df = du * Krel_j_1; + } + //cout << " Case = 3+" << endln; + + // CASE 4: WHEN LOADING IN GENERAL TOWARDS THE TARGET PEAK + } else if ((du >= 0) && (((TargetPeak_Flag==0) && (ui <= Upeak_pos_j_1)) || ((TargetPeak_Flag==1) && (ui <= ULastPeak_pos_j_1)))) { + if (TargetPeak_Flag==0) { + Krel_j_1 = (Fpeak_pos_j_1 - fi_1) / (Upeak_pos_j_1 - ui_1); + } else { + Krel_j_1 = (FLastPeak_pos_j_1 - fi_1) / (ULastPeak_pos_j_1 - ui_1); + } + df = du * Krel_j_1; + //cout << " Case = 4+" << endln; + + // CASE 5: WHEN LOADING IN GENERAL TOWARDS THE LAST CYCLE PEAK POINT BUT BEYOND IT + } else if ((du >= 0) && (TargetPeak_Flag==1) && (ui >= ULastPeak_pos_j_1) && (ui <= Upeak_pos_j_1)) { + Krel_j_1 = (Fpeak_pos_j_1 - FLastPeak_pos_j_1) / (Upeak_pos_j_1 - ULastPeak_pos_j_1); + if (ui_1 <= ULastPeak_pos_j_1) { + df = (FLastPeak_pos_j_1 - fi_1) + Krel_j_1 * (ui - ULastPeak_pos_j_1); + } else { + df = du * Krel_j_1; + } + //cout << " Case = 5+" << endln; + + // CASE 6: WHEN LOADING BEYOND THE TARGET PEAK BUT BEFORE THE CAPPING POINT + } else if ((du >= 0) && (ui <= Umax_pos_j_1)) { + df = du * Kp_pos_j_1; + //cout << " Case = 6+" << endln; + + // CASE 7: WHEN LOADING AND BETWEEN THE CAPPING POINT AND THE RESIDUAL POINT + } else if ((du > 0) && (ui >= Umax_pos_j_1) && (ui <= Ures_pos_j_1)) { + if ((ui_1<= Umax_pos_j_1) && (ui >= Umax_pos_j_1)) { + df = Kp_pos_j_1 * (Umax_pos_j_1 - ui_1) + Kpc_pos_j_1 * (ui - Umax_pos_j_1); + } else { + df = du * Kpc_pos_j_1; + } + //cout << " Case = 7+" << endln; + + // CASE 8: WHEN LOADING AND BEYOND THE RESIDUAL POINT + } else if ((du > 0) && (ui >= Ures_pos_j_1)) { + df = 0.0; + if (Fres_pos_j_1 == 0) { + Failure_Flag = 1; + } + //cout << " Case = 8+" << endln; + } } - else if (New_Peak_Neg_Flag == 1) { - Fpeak_neg_j_1 = fi; + + // Negative Force + if (fi_1 + du * Kul_j_1 <= 0) { + + // CASE 0: At THE ELASTIC SLOPE + if ((ui<=0) && (Upeak_neg_j_1 >= Uy_neg_j_1) && (Yield_Flag==0)) { + if (ui <= Uy_neg_j_1) { + df = Ke*(Uy_neg_j_1 - ui_1) + Kp_neg_j_1 * (ui - Uy_neg_j_1); + } else { + df = du * Ke; + } + //cout << " Case = 0-" << endln; + + // CASE 1: EACH NEW EXCURSION + } else if (Excursion_Flag==1) { + if (TargetPeak_Flag==0) { + Krel_j_1 = Fpeak_neg_j_1 / (Upeak_neg_j_1 - u0); + } else { + Krel_j_1 = FLastPeak_neg_j_1 / (ULastPeak_neg_j_1 - u0); + } + df = Kul_j_1 * (u0 - ui_1) + Krel_j_1 * (ui - u0); + //cout << " Case = 1-" << endln; + + // CASE 2: WHEN RELOADING + } else if ((Reloading_Flag==1) && (ui >= ULastPeak_neg_j_1)) { + df = du * Kul_j_1; + //cout << " Case = 2-" << endln; + + // CASE 2: WHEN UNLOADING + } else if (Unloading_Flag==1) { + df = du * Kul_j_1; + //cout << " Case = 3-" << endln; + + // CASE 3: WHEN RELOADING BUT BETWEEN LAST CYCLE PEAK POINT AND GLOBAL PEAK POINT + } else if ((Reloading_Flag==1) && (ui <= ULastPeak_neg_j_1) && (ui >= Upeak_neg_j_1)) { + Krel_j_1 = (Fpeak_neg_j_1 - FLastPeak_neg_j_1) / (Upeak_neg_j_1 - ULastPeak_neg_j_1); + if (ui_1 >= ULastPeak_neg_j_1) { + df = Kul_j_1 * (ULastPeak_neg_j_1 - ui_1) + Krel_j_1 * (ui - ULastPeak_neg_j_1); + } else { + df = du * Krel_j_1; + } + //cout << " Case = 4-" << endln; + + // CASE 4: WHEN LOADING IN GENERAL TOWARDS THE TARGET PEAK + } else if ((du <= 0) && (((TargetPeak_Flag==0) && (ui >= Upeak_neg_j_1)) || ((TargetPeak_Flag==1) && (ui >= ULastPeak_neg_j_1)))) { + df = du * Krel_j_1; + //cout << " Case = 4-" << endln; + + // CASE 5: WHEN LOADING IN GENERAL TOWARDS THE LAST CYCLE PEAK POINT BUT BEYOND IT + } else if ((du <= 0) && (TargetPeak_Flag==1) && (ui <= ULastPeak_neg_j_1) && (ui >= Upeak_neg_j_1)) { + Krel_j_1 = (Fpeak_neg_j_1 - FLastPeak_neg_j_1) / (Upeak_neg_j_1 - ULastPeak_neg_j_1); + if (ui_1 >= ULastPeak_neg_j_1) { + df = (FLastPeak_neg_j_1 - fi_1) + Krel_j_1 * (ui - ULastPeak_neg_j_1); + } else { + df = du * Krel_j_1; + } + //cout << " Case = 5-" << endln; + + // CASE 6: WHEN LOADING BEYOND THE TARGET PEAK BUT BEFORE THE CAPPING POINT + } else if ((du <= 0) && (ui >= Umax_neg_j_1)) { + df = du * Kp_neg_j_1; + //cout << " Case = 6-" << endln; + + // CASE 7: WHEN LOADING AND BETWEEN THE CAPPING POINT AND THE RESIDUAL POINT + } else if ((du < 0) && (ui <= Umax_neg_j_1) && (ui >= Ures_neg_j_1)) { + if ((ui_1>=Umax_neg_j_1) && (ui<=Umax_neg_j_1)) { + df = Kp_neg_j_1 * (Umax_neg_j_1 - ui_1) + Kpc_neg_j_1 * (ui - Umax_neg_j_1); + } else { + df = du * Kpc_neg_j_1; + } + //cout << " Case = 7-" << endln; + + // CASE 8: WHEN LOADING AND BEYOND THE RESIDUAL POINT + } else if ((du < 0) && (ui <= Ures_neg_j_1)) { + df = 0.0; + if (Fres_neg_j_1 == 0) { + Failure_Flag = 1; + } + //cout << " Case = 8-" << endln; + + } } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Failure - // Failure criteria (Tolerance = 1//) + + + // Force + fi = fi_1 + df; + //cout << " Excurion=" << Excursion_Flag << " Failure=" << Failure_Flag << " Reload=" << Reloading_Flag << " Unload=" << Unloading_Flag << " Yield=" << Yield_Flag << endln; + //cout << " STEP: ui_1=" << ui_1 << " ui=" << ui << " fi_1=" << fi_1 << " fi=" << fi << endln; + + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + // CHECK FOR FAILURE + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + + // Failure criteria (Tolerance = 1//) FailS = ((betaS < -0.01) || (betaS > 1.01)); FailC = ((betaC < -0.01) || (betaC > 1.01)); FailA = ((betaA < -0.01) || (betaA > 1.01)); FailK = ((betaK < -0.01) || (betaK > 1.01)); //cout << " ENERGY: EtS=" << EtS << " EtC=" << EtC << " EtA=" << EtA << " EtK=" << EtK << endln; - //cout << " ENERGY: dEi=" << dEi << " Ei=" << Ei << " Epj=" << Epj << " Energy_Diss=" << Energy_Diss << " Energy_Acc=" << Energy_Acc << endln; + //cout << " ENERGY: dEi=" << dEi << " Ei=" << Ei << " Energy_Diss=" << Energy_Diss << " Energy_Acc=" << Energy_Acc << endln; //cout << " ENERGY: betaS=" << betaS << " betaC=" << betaC << " betaA=" << betaA << " betaK=" << betaK << endln; //cout << " FAIL: FailS=" << FailS << " FailC=" << FailC << " FailA=" << FailA << " FailK=" << FailK << endln; if (FailS || FailC || FailA || FailK) { + fi = 0; //cout << " Energy Fail" << endln; Failure_Flag = 1; } @@ -500,47 +568,47 @@ int IMKPeakOriented::setTrialStrain(double strain, double strainRate) //cout << " Strength Fail" << endln; Failure_Flag = 1; } + + dEi = 0.5*(fi + fi_1)*du; // Internal energy increment + } else { fi = 0; dEi = 0; - Epj = Energy_Acc + dEi; + //cout << " FAILURE OCCURED" << endln; } //// Energy - Energy_Acc = Energy_Acc + dEi; // Total internal energy accumulated until current increment - Energy_Diss = Epj; // Total energy dissipated in all previous excursions + Energy_Acc = Energy_Acc + dEi; //// Update Variables du_i_1 = du; - Umaxp = 0; - Umaxn = 0; // Tangent Stiffeness Calculation if (fi == fi_1) { TangentK = pow(10., -6); - ki = pow(10., -6); + ki = pow(10., -6); } - if ((ui == ui_1)) { - ki = Ke; - fi = fi_1; + if (ui == ui_1) { + ki = Ke; + fi = fi_1; TangentK = Ke; } else { - ki = (fi - fi_1) / (du); + ki = (fi - fi_1) / (du); TangentK = (fi - fi_1) / (du); } - - //cout << " fi=" << fi << endln; //cout << "***********************" << endln; - // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - // %%%%%%%%%%%%%%%%%%%%%% END OF MAIN CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%% - // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////// END OF MAIN CODE /////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// return 0; } @@ -588,48 +656,49 @@ int IMKPeakOriented::commitState(void) cUy_pos_j_1 = Uy_pos_j_1; cUmax_pos_j_1 = Umax_pos_j_1; - cUu_pos_j_1 = Uu_pos_j_1; cFy_pos_j_1 = Fy_pos_j_1; cFmax_pos_j_1 = Fmax_pos_j_1; cUpeak_pos_j_1 = Upeak_pos_j_1; cFpeak_pos_j_1 = Fpeak_pos_j_1; - cUbp_pos_j_1 = Ubp_pos_j_1; - cFbp_pos_j_1 = Fbp_pos_j_1; + cUres_pos_j_1 = Ures_pos_j_1; cFres_pos_j_1 = Fres_pos_j_1; cKp_pos_j_1 = Kp_pos_j_1; cKpc_pos_j_1 = Kpc_pos_j_1; - cKrelA_pos_j_1 = KrelA_pos_j_1; - cKrelB_pos_j_1 = KrelB_pos_j_1; - cPlastic_Offset_pos_j_1 = Plastic_Offset_pos_j_1; cUy_neg_j_1 = Uy_neg_j_1; cUmax_neg_j_1 = Umax_neg_j_1; - cUu_neg_j_1 = Uu_neg_j_1; cFy_neg_j_1 = Fy_neg_j_1; cFmax_neg_j_1 = Fmax_neg_j_1; cUpeak_neg_j_1 = Upeak_neg_j_1; cFpeak_neg_j_1 = Fpeak_neg_j_1; - cUbp_neg_j_1 = Ubp_neg_j_1; - cFbp_neg_j_1 = Fbp_neg_j_1; + cUres_neg_j_1 = Ures_neg_j_1; cFres_neg_j_1 = Fres_neg_j_1; cKp_neg_j_1 = Kp_neg_j_1; cKpc_neg_j_1 = Kpc_neg_j_1; - cKrelA_neg_j_1 = KrelA_neg_j_1; - cKrelB_neg_j_1 = KrelB_neg_j_1; - cPlastic_Offset_neg_j_1 = Plastic_Offset_neg_j_1; cKul_j_1 = Kul_j_1; - cFailure_Flag = Failure_Flag; - cExcursion_Flag = Excursion_Flag; - cEnergy_Acc = Energy_Acc; cEnergy_Diss = Energy_Diss; - cUmaxp = Umaxp; - cUmaxn = Umaxn; + cu0 = u0; + + cULastPeak_pos_j_1 = ULastPeak_pos_j_1; + cFLastPeak_pos_j_1 = FLastPeak_pos_j_1; + cULastPeak_neg_j_1 = ULastPeak_neg_j_1; + cFLastPeak_neg_j_1 = FLastPeak_neg_j_1; + + cFailure_Flag = Failure_Flag; + cExcursion_Flag = Excursion_Flag; + cReloading_Flag = Reloading_Flag; + cUnloading_Flag = Unloading_Flag; + cTargetPeak_Flag = TargetPeak_Flag; + cYield_Flag = Yield_Flag; + cReversal_Flag = Reversal_Flag; + + cKrel_j_1 = Krel_j_1; return 0; } @@ -652,93 +721,94 @@ int IMKPeakOriented::revertToLastCommit(void) Uy_pos_j_1 = cUy_pos_j_1; Umax_pos_j_1 = cUmax_pos_j_1; - Uu_pos_j_1 = cUu_pos_j_1; Fy_pos_j_1 = cFy_pos_j_1; Fmax_pos_j_1 = cFmax_pos_j_1; Upeak_pos_j_1 = cUpeak_pos_j_1; Fpeak_pos_j_1 = cFpeak_pos_j_1; - Ubp_pos_j_1 = cUbp_pos_j_1; - Fbp_pos_j_1 = cFbp_pos_j_1; + Ures_pos_j_1 = cUres_pos_j_1; Fres_pos_j_1 = cFres_pos_j_1; Kp_pos_j_1 = cKp_pos_j_1; Kpc_pos_j_1 = cKpc_pos_j_1; - KrelA_pos_j_1 = cKrelA_pos_j_1; - KrelB_pos_j_1 = cKrelB_pos_j_1; - Plastic_Offset_pos_j_1 = cPlastic_Offset_pos_j_1; + Uy_neg_j_1 = cUy_neg_j_1; Umax_neg_j_1 = cUmax_neg_j_1; - Uu_neg_j_1 = cUu_neg_j_1; Fy_neg_j_1 = cFy_neg_j_1; Fmax_neg_j_1 = cFmax_neg_j_1; Upeak_neg_j_1 = cUpeak_neg_j_1; Fpeak_neg_j_1 = cFpeak_neg_j_1; - Ubp_neg_j_1 = cUbp_neg_j_1; - Fbp_neg_j_1 = cFbp_neg_j_1; + Ures_neg_j_1 = cUres_neg_j_1; Fres_neg_j_1 = cFres_neg_j_1; Kp_neg_j_1 = cKp_neg_j_1; Kpc_neg_j_1 = cKpc_neg_j_1; - KrelA_neg_j_1 = cKrelA_neg_j_1; - KrelB_neg_j_1 = cKrelB_neg_j_1; - Plastic_Offset_neg_j_1 = cPlastic_Offset_neg_j_1; + Kul_j_1 = cKul_j_1; - Failure_Flag = cFailure_Flag; - Excursion_Flag = cExcursion_Flag; + Energy_Acc = cEnergy_Acc; Energy_Diss = cEnergy_Diss; - Umaxp = cUmaxp; - Umaxn = cUmaxn; + ULastPeak_pos_j_1 = cULastPeak_pos_j_1; + FLastPeak_pos_j_1 = cFLastPeak_pos_j_1; + ULastPeak_neg_j_1 = cULastPeak_neg_j_1; + FLastPeak_neg_j_1 = cFLastPeak_neg_j_1; + + Failure_Flag = cFailure_Flag; + Excursion_Flag = cExcursion_Flag; + Reloading_Flag = cReloading_Flag; + Unloading_Flag = cUnloading_Flag; + TargetPeak_Flag = cTargetPeak_Flag; + Yield_Flag = cYield_Flag; + Reversal_Flag = cReversal_Flag; + + u0 = cu0; + Krel_j_1 = cKrel_j_1; + return 0; } int IMKPeakOriented::revertToStart(void) { - /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\\ - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ONE TIME CALCULATIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\\ - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\\ + //////////////////////////////////////////////////////////////////// ONE TIME CALCULATIONS ////////////////////////////////////////////////////////////////////\\ + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + - Failure_Flag = 0; - Excursion_Flag = 0; - Unloading_Flag = 0; - New_Peak_Pos_Flag = 0; - New_Peak_Neg_Flag = 0; betaS = 0; betaC = 0; betaK = 0; betaA = 0; - Uy_pos = Fy_pos / Ke; + Uy_pos = Fy_pos / Ke; Umax_pos = Uy_pos + Up_pos; Fmax_pos = FmaxFy_pos*Fy_pos; - Kp_pos = (Fmax_pos - Fy_pos) / Up_pos; - Kpc_pos = Fmax_pos / Upc_pos; + Kp_pos = (Fmax_pos - Fy_pos) / Up_pos; + Kpc_pos = Fmax_pos / Upc_pos; - Uy_neg = Fy_neg / Ke; + Uy_neg = Fy_neg / Ke; Umax_neg = Uy_neg + Up_neg; Fmax_neg = FmaxFy_neg*Fy_neg; - Kp_neg = (Fmax_neg - Fy_neg) / Up_neg; - Kpc_neg = Fmax_neg / Upc_neg; + Kp_neg = (Fmax_neg - Fy_neg) / Up_neg; + Kpc_neg = Fmax_neg / Upc_neg; Upeak_pos_j_1 = Uy_pos; Fpeak_pos_j_1 = Fy_pos; Upeak_neg_j_1 = -Uy_neg; Fpeak_neg_j_1 = -Fy_neg; - - Uy_pos_j_1 = Uy_pos; - Fy_pos_j_1 = Fy_pos; - Kp_pos_j_1 = Kp_pos; + + Uy_pos_j_1 = Uy_pos; + Fy_pos_j_1 = Fy_pos; + Kp_pos_j_1 = Kp_pos; Kpc_pos_j_1 = -Kpc_pos; - Uy_neg_j_1 = -Uy_neg; - Fy_neg_j_1 = -Fy_neg; - Kp_neg_j_1 = Kp_neg; + Uy_neg_j_1 = -Uy_neg; + Fy_neg_j_1 = -Fy_neg; + Kp_neg_j_1 = Kp_neg; Kpc_neg_j_1 = -Kpc_neg; Umax_pos_j_1 = Umax_pos; @@ -748,87 +818,83 @@ int IMKPeakOriented::revertToStart(void) Fmax_neg_j_1 = -Fmax_neg; Fres_neg_j_1 = -Fy_neg*ResF_neg; - KrelA_pos_j_1 = Ke; - KrelA_neg_j_1 = Ke; - KrelB_pos_j_1 = Ke; - KrelB_neg_j_1 = Ke; - Kul_j_1 = Ke; Ures_pos_j_1 = (Fres_pos_j_1 - Fmax_pos_j_1) / Kpc_pos_j_1 + Umax_pos_j_1; Ures_neg_j_1 = (Fres_neg_j_1 - Fmax_neg_j_1) / Kpc_neg_j_1 + Umax_neg_j_1; - Ubp_pos_j_1 = 0; - Ubp_neg_j_1 = 0; - - Fbp_pos_j_1 = 0; - Fbp_neg_j_1 = 0; - - Energy_Acc = 0.0; - Energy_Diss = 0.0; + Energy_Acc = cEnergy_Acc = 0.0; + Energy_Diss = cEnergy_Diss = 0.0; - Umaxp = 0.0; - Umaxn = 0.0; + u0 = 0.0; EtS = LAMBDA_S *Fy_pos; EtC = LAMBDA_C *Fy_pos; EtA = LAMBDA_A *Fy_pos; EtK = LAMBDA_K *Fy_pos; - cPlastic_Offset_pos_j_1 = 0; - cPlastic_Offset_neg_j_1 = 0; + Failure_Flag = cFailure_Flag = 0; + Excursion_Flag = cExcursion_Flag = 0; + Unloading_Flag = cUnloading_Flag = 0; + Reloading_Flag = cReloading_Flag = 0; + TargetPeak_Flag = cTargetPeak_Flag = 0; + Yield_Flag = cYield_Flag = 0; + Reversal_Flag = cReversal_Flag = 0; + + ULastPeak_pos_j_1 = Uy_pos; + FLastPeak_pos_j_1 = Fy_pos; + ULastPeak_neg_j_1 = -Uy_neg; + FLastPeak_neg_j_1 = -Fy_neg; + + Krel_j_1 = Ke; cdu_i_1 = 0; - cUpeak_pos_j_1 = Uy_pos; - cFpeak_pos_j_1 = Fy_pos; + cUpeak_pos_j_1 = Uy_pos; + cFpeak_pos_j_1 = Fy_pos; cUpeak_neg_j_1 = -Uy_neg; cFpeak_neg_j_1 = -Fy_neg; - cUy_pos_j_1 = Uy_pos; - cFy_pos_j_1 = Fy_pos; - cKp_pos_j_1 = Kp_pos; + cUy_pos_j_1 = Uy_pos; + cFy_pos_j_1 = Fy_pos; + cKp_pos_j_1 = Kp_pos; cKpc_pos_j_1 = -Kpc_pos; - cUy_neg_j_1 = -Uy_neg; - cFy_neg_j_1 = -Fy_neg; - cKp_neg_j_1 = Kp_neg; + cUy_neg_j_1 = -Uy_neg; + cFy_neg_j_1 = -Fy_neg; + cKp_neg_j_1 = Kp_neg; cKpc_neg_j_1 = -Kpc_neg; - cUmax_pos_j_1 = Umax_pos; - cFmax_pos_j_1 = Fmax_pos; - cFres_pos_j_1 = Fy_pos*ResF_pos; + cUmax_pos_j_1 = Umax_pos; + cFmax_pos_j_1 = Fmax_pos; + cFres_pos_j_1 = Fy_pos*ResF_pos; cUmax_neg_j_1 = -Umax_neg; cFmax_neg_j_1 = -Fmax_neg; cFres_neg_j_1 = -Fy_neg*ResF_neg; - cKrelA_pos_j_1 = Ke; - cKrelA_neg_j_1 = Ke; - cKrelB_pos_j_1 = Ke; - cKrelB_neg_j_1 = Ke; - cKul_j_1 = Ke; cUres_pos_j_1 = (Fres_pos_j_1 - Fmax_pos_j_1) / Kpc_pos_j_1 + Umax_pos_j_1; cUres_neg_j_1 = (Fres_neg_j_1 - Fmax_neg_j_1) / Kpc_neg_j_1 + Umax_neg_j_1; - cUbp_pos_j_1 = 0; - cUbp_neg_j_1 = 0; - - cFbp_pos_j_1 = 0; - cFbp_neg_j_1 = 0; - + cULastPeak_pos_j_1 = Uy_pos; + cFLastPeak_pos_j_1 = Fy_pos; + cULastPeak_neg_j_1 = -Uy_neg; + cFLastPeak_neg_j_1 = -Fy_neg; + + cKrel_j_1 = Ke; + //initially I zero everything U = cU = 0; - ui = 0; - fi = 0; - ui_1 = 0; - fi_1 = 0; - cui = 0; - cfi = 0; + ui = 0; + fi = 0; + ui_1 = 0; + fi_1 = 0; + cui = 0; + cfi = 0; cui_1 = 0; cfi_1 = 0; - TangentK = Ke; + TangentK = Ke; cTangentK = Ke; //cout << " revertToStart:" << endln; //<< " U=" << U << " Ri=" << Ri << " TanK=" << TangentK << endln; @@ -845,64 +911,59 @@ IMKPeakOriented::getCopy(void) //cout << " getCopy" << endln; - - theCopy->U = U; + theCopy->U = U; theCopy->cU = cU; theCopy->TangentK = TangentK; - theCopy->ui = ui; - theCopy->fi = fi; - theCopy->ui_1 = ui_1; - theCopy->fi_1 = fi_1; + theCopy->ui = ui; + theCopy->fi = fi; + theCopy->ui_1 = ui_1; + theCopy->fi_1 = fi_1; theCopy->du_i_1 = du_i_1; - theCopy->Uy_pos_j_1 = Uy_pos_j_1; - theCopy->Umax_pos_j_1 = Umax_pos_j_1; - theCopy->Uu_pos_j_1 = Uu_pos_j_1; - theCopy->Fy_pos_j_1 = Fy_pos_j_1; - theCopy->Fmax_pos_j_1 = Fmax_pos_j_1; - theCopy->Upeak_pos_j_1 = Upeak_pos_j_1; - theCopy->Fpeak_pos_j_1 = Fpeak_pos_j_1; - theCopy->Ubp_pos_j_1 = Ubp_pos_j_1; - theCopy->Fbp_pos_j_1 = Fbp_pos_j_1; - theCopy->Ures_pos_j_1 = Ures_pos_j_1; - theCopy->Fres_pos_j_1 = Fres_pos_j_1; - theCopy->Kp_pos_j_1 = Kp_pos_j_1; - theCopy->Kpc_pos_j_1 = Kpc_pos_j_1; - theCopy->KrelA_pos_j_1 = KrelA_pos_j_1; - theCopy->KrelB_pos_j_1 = KrelB_pos_j_1; - theCopy->Plastic_Offset_pos_j_1 = Plastic_Offset_pos_j_1; - - theCopy->Uy_neg_j_1 = Uy_neg_j_1; - theCopy->Umax_neg_j_1 = Umax_neg_j_1; - theCopy->Uu_neg_j_1 = Uu_neg_j_1; - theCopy->Fy_neg_j_1 = Fy_neg_j_1; - theCopy->Fmax_neg_j_1 = Fmax_neg_j_1; - theCopy->Upeak_neg_j_1 = Upeak_neg_j_1; - theCopy->Fpeak_neg_j_1 = Fpeak_neg_j_1; - theCopy->Ubp_neg_j_1 = Ubp_neg_j_1; - theCopy->Fbp_neg_j_1 = Fbp_neg_j_1; - theCopy->Ures_neg_j_1 = Ures_neg_j_1; - theCopy->Fres_neg_j_1 = Fres_neg_j_1; - theCopy->Kp_neg_j_1 = Kp_neg_j_1; - theCopy->Kpc_neg_j_1 = Kpc_neg_j_1; - theCopy->KrelA_neg_j_1 = KrelA_neg_j_1; - theCopy->KrelB_neg_j_1 = KrelB_neg_j_1; - theCopy->Plastic_Offset_neg_j_1 = Plastic_Offset_neg_j_1; + theCopy->Uy_pos_j_1 = Uy_pos_j_1; + theCopy->Umax_pos_j_1 = Umax_pos_j_1; + theCopy->Fy_pos_j_1 = Fy_pos_j_1; + theCopy->Fmax_pos_j_1 = Fmax_pos_j_1; + theCopy->Upeak_pos_j_1 = Upeak_pos_j_1; + theCopy->Fpeak_pos_j_1 = Fpeak_pos_j_1; + theCopy->Ures_pos_j_1 = Ures_pos_j_1; + theCopy->Fres_pos_j_1 = Fres_pos_j_1; + theCopy->Kp_pos_j_1 = Kp_pos_j_1; + theCopy->Kpc_pos_j_1 = Kpc_pos_j_1; + + theCopy->Uy_neg_j_1 = Uy_neg_j_1; + theCopy->Umax_neg_j_1 = Umax_neg_j_1; + theCopy->Fy_neg_j_1 = Fy_neg_j_1; + theCopy->Fmax_neg_j_1 = Fmax_neg_j_1; + theCopy->Upeak_neg_j_1 = Upeak_neg_j_1; + theCopy->Fpeak_neg_j_1 = Fpeak_neg_j_1; + theCopy->Ures_neg_j_1 = Ures_neg_j_1; + theCopy->Fres_neg_j_1 = Fres_neg_j_1; + theCopy->Kp_neg_j_1 = Kp_neg_j_1; + theCopy->Kpc_neg_j_1 = Kpc_neg_j_1; theCopy->Kul_j_1 = Kul_j_1; - theCopy->Failure_Flag = Failure_Flag; - theCopy->Excursion_Flag = Excursion_Flag; - - theCopy->Energy_Acc = Energy_Acc; + theCopy->Energy_Acc = Energy_Acc; theCopy->Energy_Diss = Energy_Diss; - theCopy->Umaxp = Umaxp; - theCopy->Umaxn = Umaxn; + theCopy->u0 = u0; + theCopy->ULastPeak_pos_j_1 = ULastPeak_pos_j_1; + theCopy->FLastPeak_pos_j_1 = FLastPeak_pos_j_1; + theCopy->ULastPeak_neg_j_1 = ULastPeak_neg_j_1; + theCopy->FLastPeak_neg_j_1 = FLastPeak_neg_j_1; + theCopy->Failure_Flag = Failure_Flag; + theCopy->Excursion_Flag = Excursion_Flag; + theCopy->Reloading_Flag = Reloading_Flag; + theCopy->TargetPeak_Flag = TargetPeak_Flag; + theCopy->Yield_Flag = Yield_Flag; + theCopy->Reversal_Flag = Reversal_Flag; + + theCopy->Krel_j_1 = Krel_j_1; theCopy->cTangentK = cTangentK; @@ -912,51 +973,49 @@ IMKPeakOriented::getCopy(void) theCopy->cfi_1 = cfi_1; theCopy->cdu_i_1 = cdu_i_1; - theCopy->cUy_pos_j_1 = cUy_pos_j_1; - theCopy->cUmax_pos_j_1 = cUmax_pos_j_1; - theCopy->cUu_pos_j_1 = cUu_pos_j_1; - theCopy->cFy_pos_j_1 = cFy_pos_j_1; - theCopy->cFmax_pos_j_1 = cFmax_pos_j_1; + theCopy->cUy_pos_j_1 = cUy_pos_j_1; + theCopy->cUmax_pos_j_1 = cUmax_pos_j_1; + theCopy->cFy_pos_j_1 = cFy_pos_j_1; + theCopy->cFmax_pos_j_1 = cFmax_pos_j_1; theCopy->cUpeak_pos_j_1 = cUpeak_pos_j_1; theCopy->cFpeak_pos_j_1 = cFpeak_pos_j_1; - theCopy->cUbp_pos_j_1 = cUbp_pos_j_1; - theCopy->cFbp_pos_j_1 = cFbp_pos_j_1; - theCopy->cUres_pos_j_1 = cUres_pos_j_1; - theCopy->cFres_pos_j_1 = cFres_pos_j_1; - theCopy->cKp_pos_j_1 = cKp_pos_j_1; - theCopy->cKpc_pos_j_1 = cKpc_pos_j_1; - theCopy->cKrelA_pos_j_1 = cKrelA_pos_j_1; - theCopy->cKrelB_pos_j_1 = cKrelB_pos_j_1; - theCopy->cPlastic_Offset_pos_j_1 = cPlastic_Offset_pos_j_1; - - theCopy->cUy_neg_j_1 = cUy_neg_j_1; - theCopy->cUmax_neg_j_1 = cUmax_neg_j_1; - theCopy->cUu_neg_j_1 = cUu_neg_j_1; - theCopy->cFy_neg_j_1 = cFy_neg_j_1; - theCopy->cFmax_neg_j_1 = cFmax_neg_j_1; + theCopy->cUres_pos_j_1 = cUres_pos_j_1; + theCopy->cFres_pos_j_1 = cFres_pos_j_1; + theCopy->cKp_pos_j_1 = cKp_pos_j_1; + theCopy->cKpc_pos_j_1 = cKpc_pos_j_1; + + theCopy->cUy_neg_j_1 = cUy_neg_j_1; + theCopy->cUmax_neg_j_1 = cUmax_neg_j_1; + theCopy->cFy_neg_j_1 = cFy_neg_j_1; + theCopy->cFmax_neg_j_1 = cFmax_neg_j_1; theCopy->cUpeak_neg_j_1 = cUpeak_neg_j_1; theCopy->cFpeak_neg_j_1 = cFpeak_neg_j_1; - theCopy->cUbp_neg_j_1 = cUbp_neg_j_1; - theCopy->cFbp_neg_j_1 = cFbp_neg_j_1; - theCopy->cUres_neg_j_1 = cUres_neg_j_1; - theCopy->cFres_neg_j_1 = cFres_neg_j_1; - theCopy->cKp_neg_j_1 = cKp_neg_j_1; - theCopy->cKpc_neg_j_1 = cKpc_neg_j_1; - theCopy->cKrelA_neg_j_1 = cKrelA_neg_j_1; - theCopy->cKrelB_neg_j_1 = cKrelB_neg_j_1; - theCopy->cPlastic_Offset_neg_j_1 = cPlastic_Offset_neg_j_1; + theCopy->cUres_neg_j_1 = cUres_neg_j_1; + theCopy->cFres_neg_j_1 = cFres_neg_j_1; + theCopy->cKp_neg_j_1 = cKp_neg_j_1; + theCopy->cKpc_neg_j_1 = cKpc_neg_j_1; theCopy->cKul_j_1 = cKul_j_1; - theCopy->cFailure_Flag = cFailure_Flag; - theCopy->cExcursion_Flag = cExcursion_Flag; - - theCopy->cEnergy_Acc = cEnergy_Acc; + theCopy->cEnergy_Acc = cEnergy_Acc; theCopy->cEnergy_Diss = cEnergy_Diss; - theCopy->cUmaxp = cUmaxp; - theCopy->cUmaxn = cUmaxn; - + theCopy->cu0 = cu0; + + theCopy->cULastPeak_pos_j_1 = cULastPeak_pos_j_1; + theCopy->cFLastPeak_pos_j_1 = cFLastPeak_pos_j_1; + theCopy->cULastPeak_neg_j_1 = cULastPeak_neg_j_1; + theCopy->cFLastPeak_neg_j_1 = cFLastPeak_neg_j_1; + + theCopy->cFailure_Flag = cFailure_Flag; + theCopy->cExcursion_Flag = cExcursion_Flag; + theCopy->cReloading_Flag = cReloading_Flag; + theCopy->cTargetPeak_Flag = cTargetPeak_Flag; + theCopy->cYield_Flag = cYield_Flag; + theCopy->cReversal_Flag = cReversal_Flag; + + theCopy->cKrel_j_1 = cKrel_j_1; + return theCopy; } @@ -965,175 +1024,164 @@ int IMKPeakOriented::sendSelf(int cTag, Channel &theChannel) int res = 0; cout << " sendSelf" << endln; - static Vector data(149); + static Vector data(137); data(0) = this->getTag(); - data(1) = Ke; - data(2) = Uy_pos; - data(3) = Umax_pos; - data(4) = Uu_pos; - data(5) = Fy_pos; - data(6) = FmaxFy_pos; - data(7) = ResF_pos; - data(8) = Uy_neg; - data(9) = Umax_neg; - data(10) = Uu_neg; - data(11) = Fy_neg; - data(12) = FmaxFy_neg; - data(13) = ResF_neg; - data(14) = LAMBDA_S; - data(15) = LAMBDA_C; - data(16) = LAMBDA_A; - data(17) = LAMBDA_K; - data(18) = c_S; - data(19) = c_C; - data(20) = c_A; - data(21) = c_K; - data(22) = D_pos; - data(23) = D_neg; - data(24) = kappaF; - data(25) = kappaD; - - data(26) = ui; - data(27) = fi; - data(28) = ui_1; - data(29) = fi_1; - data(30) = du_i_1; - - data(31) = Uy_pos_j_1; - data(32) = Umax_pos_j_1; - data(33) = Uu_pos_j_1; - data(34) = Fy_pos_j_1; - data(35) = Fmax_pos_j_1; - data(36) = Upeak_pos_j_1; - data(37) = Fpeak_pos_j_1; - data(38) = Ubp_pos_j_1; - data(39) = Fbp_pos_j_1; - data(40) = Ures_pos_j_1; - data(41) = Fres_pos_j_1; - data(42) = Kp_pos_j_1; - data(43) = Kpc_pos_j_1; - data(44) = KrelA_pos_j_1; - data(45) = KrelB_pos_j_1; - data(46) = Plastic_Offset_pos_j_1; - - data(47) = Uy_neg_j_1; - data(48) = Umax_neg_j_1; - data(49) = Uu_neg_j_1; - data(50) = Fy_neg_j_1; - data(51) = Fmax_neg_j_1; - data(52) = Upeak_neg_j_1; - data(53) = Fpeak_neg_j_1; - data(54) = Ubp_neg_j_1; - data(55) = Fbp_neg_j_1; - data(56) = Ures_neg_j_1; - data(57) = Fres_neg_j_1; - data(58) = Kp_neg_j_1; - data(59) = Kpc_neg_j_1; - data(60) = KrelA_neg_j_1; - data(61) = KrelB_neg_j_1; - data(62) = Plastic_Offset_neg_j_1; - - data(63) = Kul_j_1; - data(64) = Failure_Flag; - data(65) = Excursion_Flag; - - data(66) = Energy_Acc; - data(67) = Energy_Diss; - data(68) = Umaxp; - data(69) = Umaxn; - - data(70) = u0; - data(71) = du; - data(72) = df; - - data(73) = Unloading_Flag; - data(74) = New_Peak_Pos_Flag; - data(75) = New_Peak_Neg_Flag; - - data(76) = Fp; - - data(77) = FailS; - data(78) = FailC; - data(79) = FailA; - data(80) = FailK; - - data(81) = Ei; - data(82) = dEi; - data(83) = Epj; - data(84) = EpjK; - data(85) = EiK; - - data(86) = c_S; - data(87) = c_C; - data(88) = c_A; - data(89) = c_K; - data(90) = EtS; - data(91) = EtC; - data(92) = EtA; - data(93) = EtK; - data(94) = betaS; - data(95) = betaC; - data(96) = betaA; - data(97) = betaK; - data(98) = sPCsp; - data(99) = sPCpcp; - - data(100) = TangentK; - - data(101) = Uy_pos; - data(102) = Umax_pos; - data(103) = Fmax_pos; - data(104) = Kp_pos; - data(105) = Kpc_pos; - - data(106) = Uy_neg; - data(107) = Umax_neg; - data(108) = Fmax_neg; - data(109) = Kp_neg; - data(110) = Kpc_neg; - - data(111) = cui; - data(112) = cfi; - data(113) = cui_1; - data(114) = cfi_1; - data(115) = cdu_i_1; - - data(116) = cUy_pos_j_1; - data(117) = cUmax_pos_j_1; - data(118) = cUu_pos_j_1; - data(119) = cFy_pos_j_1; - data(120) = cFmax_pos_j_1; - data(121) = cUpeak_pos_j_1; - data(122) = cFpeak_pos_j_1; - data(123) = cUbp_pos_j_1; - data(124) = cFbp_pos_j_1; - data(125) = cUres_pos_j_1; - data(126) = cFres_pos_j_1; - data(127) = cKp_pos_j_1; - data(128) = cKpc_pos_j_1; - data(129) = cKrelA_pos_j_1; - data(130) = cKrelB_pos_j_1; - data(131) = cPlastic_Offset_pos_j_1; - - data(132) = cUy_neg_j_1; - data(133) = cUmax_neg_j_1; - data(134) = cUu_neg_j_1; - data(135) = cFy_neg_j_1; - data(136) = cFmax_neg_j_1; - data(137) = cUpeak_neg_j_1; - data(138) = cFpeak_neg_j_1; - data(139) = cUbp_neg_j_1; - data(140) = cFbp_neg_j_1; - data(141) = cUres_neg_j_1; - data(142) = cFres_neg_j_1; - data(143) = cKp_neg_j_1; - data(144) = cKpc_neg_j_1; - data(145) = cKrelA_neg_j_1; - data(146) = cKrelB_neg_j_1; - data(147) = cPlastic_Offset_neg_j_1; - - data(148) = cKul_j_1; - + data(1) = Ke; + data(2) = Uy_pos; + data(3) = Umax_pos; + data(4) = Uu_pos; + data(5) = Fy_pos; + data(6) = FmaxFy_pos; + data(7) = ResF_pos; + data(8) = Uy_neg; + data(9) = Umax_neg; + data(10) = Uu_neg; + data(11) = Fy_neg; + data(12) = FmaxFy_neg; + data(13) = ResF_neg; + data(14) = LAMBDA_S; + data(15) = LAMBDA_C; + data(16) = LAMBDA_A; + data(17) = LAMBDA_K; + data(18) = c_S; + data(19) = c_C; + data(20) = c_A; + data(21) = c_K; + data(22) = D_pos; + data(23) = D_neg; + data(24) = ui; + data(25) = fi; + data(26) = ui_1; + data(27) = fi_1; + data(28) = du_i_1; + + data(29) = Uy_pos_j_1; + data(30) = Umax_pos_j_1; + data(31) = Fy_pos_j_1; + data(32) = Fmax_pos_j_1; + data(33) = Upeak_pos_j_1; + data(34) = Fpeak_pos_j_1; + data(35) = Ures_pos_j_1; + data(36) = Fres_pos_j_1; + data(37) = Kp_pos_j_1; + data(38) = Kpc_pos_j_1; + + data(39) = Uy_neg_j_1; + data(40) = Umax_neg_j_1; + data(41) = Fy_neg_j_1; + data(42) = Fmax_neg_j_1; + data(43) = Upeak_neg_j_1; + data(44) = Fpeak_neg_j_1; + data(45) = Ures_neg_j_1; + data(46) = Fres_neg_j_1; + data(47) = Kp_neg_j_1; + data(48) = Kpc_neg_j_1; + + data(49) = Kul_j_1; + + data(50) = Failure_Flag; + data(51) = Excursion_Flag; + data(52) = Unloading_Flag; + data(53) = Reloading_Flag; + data(54) = TargetPeak_Flag; + data(55) = Yield_Flag; + + data(56) = Energy_Acc; + data(57) = Energy_Diss; + + data(58) = u0; + data(59) = du; + data(60) = df; + + data(61) = FailS; + data(62) = FailC; + data(63) = FailA; + data(64) = FailK; + + data(65) = Ei; + data(66) = dEi; + data(67) = Epj; + data(68) = EpjK; + data(69) = EiK; + data(70) = c_S; + data(71) = c_C; + data(72) = c_A; + data(73) = c_K; + data(74) = EtS; + data(75) = EtC; + data(76) = EtA; + data(77) = EtK; + data(78) = betaS; + data(79) = betaC; + data(80) = betaA; + data(81) = betaK; + data(82) = sPCsp; + data(83) = sPCpcp; + + data(84) = TangentK; + + data(85) = Uy_pos; + data(86) = Umax_pos; + data(87) = Fmax_pos; + data(88) = Kp_pos; + data(89) = Kpc_pos; + + data(90) = Uy_neg; + data(91) = Umax_neg; + data(92) = Fmax_neg; + data(93) = Kp_neg; + data(94) = Kpc_neg; + + data(95) = cui; + data(96) = cfi; + data(97) = cui_1; + data(98) = cfi_1; + data(99) = cdu_i_1; + + data(100) = cUy_pos_j_1; + data(101) = cUmax_pos_j_1; + data(102) = cFy_pos_j_1; + data(103) = cFmax_pos_j_1; + data(104) = cUpeak_pos_j_1; + data(105) = cFpeak_pos_j_1; + data(106) = cUres_pos_j_1; + data(107) = cFres_pos_j_1; + data(108) = cKp_pos_j_1; + data(109) = cKpc_pos_j_1; + + data(110) = cUy_neg_j_1; + data(111) = cUmax_neg_j_1; + data(112) = cFy_neg_j_1; + data(113) = cFmax_neg_j_1; + data(114) = cUpeak_neg_j_1; + data(115) = cFpeak_neg_j_1; + data(116) = cUres_neg_j_1; + data(117) = cFres_neg_j_1; + data(118) = cKp_neg_j_1; + data(119) = cKpc_neg_j_1; + + data(120) = cKul_j_1; + + data(121) = cULastPeak_pos_j_1; + data(122) = cFLastPeak_pos_j_1; + data(123) = cULastPeak_neg_j_1; + data(124) = cFLastPeak_neg_j_1; + + data(125) = cFailure_Flag; + data(126) = cExcursion_Flag; + data(127) = cReloading_Flag; + data(128) = cUnloading_Flag; + data(129) = cTargetPeak_Flag; + data(130) = cYield_Flag; + + data(131) = cKrel_j_1; + + data(132) = Krel_LastPeak; + data(133) = Krel_GlobalPeak; + data(134) = K_check; + + data(135) = cReversal_Flag; + data(136) = Reversal_Flag; res = theChannel.sendVector(this->getDbTag(), cTag, data); if (res < 0) @@ -1145,7 +1193,7 @@ int IMKPeakOriented::sendSelf(int cTag, Channel &theChannel) int IMKPeakOriented::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker) { int res = 0; - static Vector data(149); + static Vector data(137); res = theChannel.recvVector(this->getDbTag(), cTag, data); if (res < 0) { @@ -1155,173 +1203,142 @@ int IMKPeakOriented::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &t else { cout << " recvSelf" << endln; this->setTag((int)data(0)); - Ke = data(1); - Up_pos = data(2); - Upc_pos = data(3); - Uu_pos = data(4); - Fy_pos = data(5); - FmaxFy_pos = data(6); - ResF_pos = data(7); - Up_neg = data(8); - Upc_neg = data(9); - Uu_neg = data(10); - Fy_neg = data(11); - FmaxFy_neg = data(12); - ResF_neg = data(13); - LAMBDA_S = data(14); - LAMBDA_C = data(15); - LAMBDA_A = data(16); - LAMBDA_K = data(17); - c_S = data(18); - c_C = data(19); - c_A = data(20); - c_K = data(21); - D_pos = data(22); - D_neg = data(23); - kappaF = data(24); - kappaD = data(25); - - ui = data(26); - fi = data(27); - ui_1 = data(28); - fi_1 = data(29); - du_i_1 = data(30); - - Uy_pos_j_1 = data(31); - Umax_pos_j_1 = data(32); - Uu_pos_j_1 = data(33); - Fy_pos_j_1 = data(34); - Fmax_pos_j_1 = data(35); - Upeak_pos_j_1 = data(36); - Fpeak_pos_j_1 = data(37); - Ubp_pos_j_1 = data(38); - Fbp_pos_j_1 = data(39); - Ures_pos_j_1 = data(40); - Fres_pos_j_1 = data(41); - Kp_pos_j_1 = data(42); - Kpc_pos_j_1 = data(43); - KrelA_pos_j_1 = data(44); - KrelB_pos_j_1 = data(45); - Plastic_Offset_pos_j_1 = data(46); - - Uy_neg_j_1 = data(47); - Umax_neg_j_1 = data(48); - Uu_neg_j_1 = data(49); - Fy_neg_j_1 = data(50); - Fmax_neg_j_1 = data(51); - Upeak_neg_j_1 = data(52); - Fpeak_neg_j_1 = data(53); - Ubp_neg_j_1 = data(54); - Fbp_neg_j_1 = data(55); - Ures_neg_j_1 = data(56); - Fres_neg_j_1 = data(57); - Kp_neg_j_1 = data(58); - Kpc_neg_j_1 = data(59); - KrelA_neg_j_1 = data(60); - KrelB_neg_j_1 = data(61); - Plastic_Offset_neg_j_1 = data(62); - - Kul_j_1 = data(63); - - Failure_Flag = data(64); - Excursion_Flag = data(65); - - Energy_Acc = data(66); - Energy_Diss = data(67); - Umaxp = data(68); - Umaxn = data(69); - - u0 = data(70); - du = data(71); - df = data(72); - - Unloading_Flag = data(73); - New_Peak_Pos_Flag = data(74); - New_Peak_Neg_Flag = data(75); - - Fp = data(76); - - FailS = data(77); - FailC = data(78); - FailA = data(79); - FailK = data(80); - - Ei = data(81); - dEi = data(82); - Epj = data(83); - EpjK = data(84); - EiK = data(85); - - c_S = data(86); - c_C = data(87); - c_A = data(88); - c_K = data(89); - EtS = data(90); - EtC = data(91); - EtA = data(92); - EtK = data(93); - betaS = data(94); - betaC = data(95); - betaA = data(96); - betaK = data(97); - sPCsp = data(98); - sPCpcp = data(99); - - TangentK = data(100); - - Uy_pos = data(101); - Umax_pos = data(102); - Fmax_pos = data(103); - Kp_pos = data(104); - Kpc_pos = data(105); - - Uy_neg = data(106); - Umax_neg = data(107); - Fmax_neg = data(108); - Kp_neg = data(109); - Kpc_neg = data(110); - - cui = data(111); - cfi = data(112); - cui_1 = data(113); - cfi_1 = data(114); - cdu_i_1 = data(115); - - cUy_pos_j_1 = data(116); - cUmax_pos_j_1 = data(117); - cUu_pos_j_1 = data(118); - cFy_pos_j_1 = data(119); - cFmax_pos_j_1 = data(120); - cUpeak_pos_j_1 = data(121); - cFpeak_pos_j_1 = data(122); - cUbp_pos_j_1 = data(123); - cFbp_pos_j_1 = data(124); - cUres_pos_j_1 = data(125); - cFres_pos_j_1 = data(126); - cKp_pos_j_1 = data(127); - cKpc_pos_j_1 = data(128); - cKrelA_pos_j_1 = data(129); - cKrelB_pos_j_1 = data(130); - cPlastic_Offset_pos_j_1 = data(131); - - cUy_neg_j_1 = data(132); - cUmax_neg_j_1 = data(133); - cUu_neg_j_1 = data(134); - cFy_neg_j_1 = data(135); - cFmax_neg_j_1 = data(136); - cUpeak_neg_j_1 = data(137); - cFpeak_neg_j_1 = data(138); - cUbp_neg_j_1 = data(139); - cFbp_neg_j_1 = data(140); - cUres_neg_j_1 = data(141); - cFres_neg_j_1 = data(142); - cKp_neg_j_1 = data(143); - cKpc_neg_j_1 = data(144); - cKrelA_neg_j_1 = data(145); - cKrelB_neg_j_1 = data(146); - cPlastic_Offset_neg_j_1 = data(147); - - cKul_j_1 = data(148); + Ke = data(1); + Up_pos = data(2); + Upc_pos = data(3); + Uu_pos = data(4); + Fy_pos = data(5); + FmaxFy_pos = data(6); + ResF_pos = data(7); + Up_neg = data(8); + Upc_neg = data(9); + Uu_neg = data(10); + Fy_neg = data(11); + FmaxFy_neg = data(12); + ResF_neg = data(13); + LAMBDA_S = data(14); + LAMBDA_C = data(15); + LAMBDA_A = data(16); + LAMBDA_K = data(17); + c_S = data(18); + c_C = data(19); + c_A = data(20); + c_K = data(21); + D_pos = data(22); + D_neg = data(23); + ui = data(24); + fi = data(25); + ui_1 = data(26); + fi_1 = data(27); + du_i_1 = data(28); + Uy_pos_j_1 = data(29); + Umax_pos_j_1 = data(30); + Fy_pos_j_1 = data(31); + Fmax_pos_j_1 = data(32); + Upeak_pos_j_1 = data(33); + Fpeak_pos_j_1 = data(34); + Ures_pos_j_1 = data(35); + Fres_pos_j_1 = data(36); + Kp_pos_j_1 = data(37); + Kpc_pos_j_1 = data(38); + Uy_neg_j_1 = data(39); + Umax_neg_j_1 = data(40); + Fy_neg_j_1 = data(41); + Fmax_neg_j_1 = data(42); + Upeak_neg_j_1 = data(43); + Fpeak_neg_j_1 = data(44); + Ures_neg_j_1 = data(45); + Fres_neg_j_1 = data(46); + Kp_neg_j_1 = data(47); + Kpc_neg_j_1 = data(48); + Failure_Flag = data(49); + Excursion_Flag = data(50); + Reloading_Flag = data(51); + Unloading_Flag = data(52); + TargetPeak_Flag = data(53); + Yield_Flag = data(54); + Kul_j_1 = data(55); + Energy_Acc = data(56); + Energy_Diss = data(57); + u0 = data(58); + du = data(59); + df = data(60); + FailS = data(61); + FailC = data(62); + FailA = data(63); + FailK = data(64); + Ei = data(65); + dEi = data(66); + Epj = data(67); + EpjK = data(68); + EiK = data(79); + c_S = data(70); + c_C = data(71); + c_A = data(72); + c_K = data(73); + EtS = data(74); + EtC = data(75); + EtA = data(76); + EtK = data(77); + betaS = data(78); + betaC = data(79); + betaA = data(80); + betaK = data(81); + sPCsp = data(82); + sPCpcp = data(83); + TangentK = data(84); + Uy_pos = data(85); + Umax_pos = data(86); + Fmax_pos = data(87); + Kp_pos = data(88); + Kpc_pos = data(89); + Uy_neg = data(90); + Umax_neg = data(91); + Fmax_neg = data(92); + Kp_neg = data(93); + Kpc_neg = data(94); + cui = data(95); + cfi = data(96); + cui_1 = data(97); + cfi_1 = data(98); + cdu_i_1 = data(99); + cUy_pos_j_1 = data(100); + cUmax_pos_j_1 = data(101); + cFy_pos_j_1 = data(102); + cFmax_pos_j_1 = data(103); + cUpeak_pos_j_1 = data(104); + cFpeak_pos_j_1 = data(105); + cUres_pos_j_1 = data(106); + cFres_pos_j_1 = data(107); + cKp_pos_j_1 = data(108); + cKpc_pos_j_1 = data(109); + cUy_neg_j_1 = data(110); + cUmax_neg_j_1 = data(111); + cFy_neg_j_1 = data(112); + cFmax_neg_j_1 = data(113); + cUpeak_neg_j_1 = data(114); + cFpeak_neg_j_1 = data(115); + cUres_neg_j_1 = data(116); + cFres_neg_j_1 = data(117); + cKp_neg_j_1 = data(118); + cKpc_neg_j_1 = data(119); + cKul_j_1 = data(120); + cULastPeak_pos_j_1 = data(121); + cFLastPeak_pos_j_1 = data(122); + cULastPeak_neg_j_1 = data(123); + cFLastPeak_neg_j_1 = data(124); + cFailure_Flag = data(125); + cExcursion_Flag = data(126); + cReloading_Flag = data(127); + cUnloading_Flag = data(128); + cTargetPeak_Flag = data(129); + cYield_Flag = data(130); + cKrel_j_1 = data(131); + Krel_LastPeak = data(132); + Krel_GlobalPeak = data(133); + K_check = data(134); + cReversal_Flag = data(135); + Reversal_Flag = data(136); } return res; @@ -1330,5 +1347,4 @@ int IMKPeakOriented::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &t void IMKPeakOriented::Print(OPS_Stream &s, int flag) { cout << "IMKPeakOriented tag: " << this->getTag() << endln; -} - +} \ No newline at end of file diff --git a/SRC/material/uniaxial/IMKPeakOriented.h b/SRC/material/uniaxial/IMKPeakOriented.h index f5f6500361..2123113599 100644 --- a/SRC/material/uniaxial/IMKPeakOriented.h +++ b/SRC/material/uniaxial/IMKPeakOriented.h @@ -22,8 +22,7 @@ //********************************************************************** // Code Developed by: Ahmed Elkady and Hammad ElJisr -// Postdoctoral Researcher, EPFL, Switzerland -// Last Updated: July 2018 +// Last Updated: July 2020 //********************************************************************** #ifndef IMKPeakOriented_h @@ -85,8 +84,6 @@ class IMKPeakOriented : public UniaxialMaterial double D_pos; double D_neg; - double kappaF; - double kappaD; //State variables double U, cU; @@ -100,62 +97,38 @@ class IMKPeakOriented : public UniaxialMaterial double Uy_pos_j_1, cUy_pos_j_1; double Umax_pos_j_1, cUmax_pos_j_1; - double Uu_pos_j_1, cUu_pos_j_1; double Fy_pos_j_1, cFy_pos_j_1; double Fmax_pos_j_1, cFmax_pos_j_1; double Upeak_pos_j_1, cUpeak_pos_j_1; double Fpeak_pos_j_1, cFpeak_pos_j_1; - double Ubp_pos_j_1, cUbp_pos_j_1; - double Fbp_pos_j_1, cFbp_pos_j_1; double Ures_pos_j_1, cUres_pos_j_1; double Fres_pos_j_1, cFres_pos_j_1; double Kp_pos_j_1, cKp_pos_j_1; double Kpc_pos_j_1, cKpc_pos_j_1; - double KrelA_pos_j_1, cKrelA_pos_j_1; - double KrelB_pos_j_1, cKrelB_pos_j_1; - double Plastic_Offset_pos_j_1, cPlastic_Offset_pos_j_1; double Uy_neg_j_1, cUy_neg_j_1; double Umax_neg_j_1, cUmax_neg_j_1; - double Uu_neg_j_1, cUu_neg_j_1; double Fy_neg_j_1, cFy_neg_j_1; double Fmax_neg_j_1, cFmax_neg_j_1; double Upeak_neg_j_1, cUpeak_neg_j_1; double Fpeak_neg_j_1, cFpeak_neg_j_1; - double Ubp_neg_j_1, cUbp_neg_j_1; - double Fbp_neg_j_1, cFbp_neg_j_1; + double Ures_neg_j_1, cUres_neg_j_1; double Fres_neg_j_1, cFres_neg_j_1; double Kp_neg_j_1, cKp_neg_j_1; double Kpc_neg_j_1, cKpc_neg_j_1; - double KrelA_neg_j_1, cKrelA_neg_j_1; - double KrelB_neg_j_1, cKrelB_neg_j_1; - double Plastic_Offset_neg_j_1, cPlastic_Offset_neg_j_1; - double Kul_j_1, cKul_j_1; - - double Failure_Flag, cFailure_Flag; - double Excursion_Flag, cExcursion_Flag; - + double Energy_Acc, cEnergy_Acc; double Energy_Diss, cEnergy_Diss; - double Umaxp, cUmaxp; - double Umaxn, cUmaxn; - - - double u0; + double u0, cu0; + double du; double df; - double Unloading_Flag; - double New_Peak_Pos_Flag; - double New_Peak_Neg_Flag; - - double Fp; - double FailS; double FailC; double FailA; @@ -187,11 +160,31 @@ class IMKPeakOriented : public UniaxialMaterial double TangentK, cTangentK, ki; - double Uy_pos, Uy_neg; - double Umax_pos, Umax_neg; - double Fmax_pos, Fmax_neg; - double Kpc_pos, Kpc_neg; - double Kp_pos, Kp_neg; + double Uy_pos, Uy_neg; + double Umax_pos, Umax_neg; + double Fmax_pos, Fmax_neg; + double Kpc_pos, Kpc_neg; + double Kp_pos, Kp_neg; + + double ULastPeak_pos_j_1, cULastPeak_pos_j_1; + double FLastPeak_pos_j_1, cFLastPeak_pos_j_1; + double ULastPeak_neg_j_1, cULastPeak_neg_j_1; + double FLastPeak_neg_j_1, cFLastPeak_neg_j_1; + + double Failure_Flag, cFailure_Flag; + double Excursion_Flag, cExcursion_Flag; + double Reloading_Flag, cReloading_Flag; + double TargetPeak_Flag, cTargetPeak_Flag; + double Unloading_Flag, cUnloading_Flag; + double Yield_Flag, cYield_Flag; + double Reversal_Flag, cReversal_Flag; + + double Krel_j_1, cKrel_j_1; + + double Krel_LastPeak; + double Krel_GlobalPeak; + double K_check; + }; diff --git a/SRC/material/uniaxial/IMKPinching.cpp b/SRC/material/uniaxial/IMKPinching.cpp index f28023795f..b75b80242f 100644 --- a/SRC/material/uniaxial/IMKPinching.cpp +++ b/SRC/material/uniaxial/IMKPinching.cpp @@ -37,11 +37,11 @@ using namespace std; static int numIMKPinchingMaterials = 0; void * -OPS_IMKPinching(void) +OPS_IMKPinching() { if (numIMKPinchingMaterials == 0) { numIMKPinchingMaterials++; - OPS_Error("\nIMK Model with Pinched Response - Code by H. ELJISR & A. ELKADY (July-2018)\n", 1); + OPS_Error("IMK Model with Pinched Response - Code by A. ELKADY & H. ELJISR (July 2020)\n", 1); } // Pointer to a uniaxial material that will be returned @@ -58,12 +58,12 @@ OPS_IMKPinching(void) numData = 25; + if (OPS_GetDoubleInput(&numData, dData) != 0) { opserr << "Invalid Args want: uniaxialMaterial IMKPinching tag? Ke? "; opserr << "Up_pos? Upc_pos? Uu_pos? Fy_pos? FmaxFy_pos? ResF_pos? "; opserr << "Up_neg? Upc_neg? Uu_neg? Fy_neg? FmaxFy_neg? ResF_neg? "; - opserr << "LamdaS? LamdaC? LamdaA? LamdaK? Cs? Cc? Ca? Ck? D_pos? D_neg? "; - opserr << "KappaF? KappaD?"; + opserr << "LamdaS? LamdaC? LamdaA? LamdaK? Cs? Cc? Ca? Ck? D_pos? D_neg? kappaF? kappaD? "; return 0; } @@ -75,7 +75,7 @@ OPS_IMKPinching(void) dData[1], dData[2], dData[3], dData[4], dData[5], dData[6], dData[7], dData[8], dData[9], dData[10], dData[11], dData[12], dData[13], dData[14], dData[15], dData[16], dData[17], dData[18], dData[19], dData[20], - dData[21], dData[22], dData[23], dData[24]); + dData[21], dData[22],dData[23], dData[24]); if (theMaterial == 0) { opserr << "WARNING could not create uniaxialMaterial of type IMKPinching Material\n"; @@ -123,201 +123,136 @@ int IMKPinching::setTrialStrain(double strain, double strainRate) ui = U; //cout << "***********************" << endln; - //cout << " Excurion=" << Excursion_Flag << " Failure=" << Failure_Flag << endln; - //cout << " STEP: ui_1=" << ui_1 << " ui=" << ui << " fi_1=" << fi_1 << " fi=" << fi << endln; - //cout << " +VE: Uy= " << Uy_pos_j_1 << " Umax= " << Umax_pos_j_1 << " Upeak= " << Upeak_pos_j_1 << " Ubp=" << Ubp_pos_j_1 << " Fpeak= " << Fpeak_pos_j_1 << " Fbp=" << Fbp_pos_j_1 << " KrelA=" << KrelA_pos_j_1 << " KrelB=" << KrelB_pos_j_1 << endln; - //cout << " -VE: Uy=" << Uy_neg_j_1 << " Umax=" << Umax_neg_j_1 << " Upeak=" << Upeak_neg_j_1 << " Ubp=" << Ubp_neg_j_1 << " Fpeak=" << Fpeak_neg_j_1 << " Fbp=" << Fbp_neg_j_1 << " KrelA=" << KrelA_neg_j_1 << " KrelB=" << KrelB_neg_j_1 << endln; + //cout << " +VE: Uy= " << Uy_pos_j_1 << " Umax= " << Umax_pos_j_1 << " Upeak= " << Upeak_pos_j_1 << " Fpeak= " << Fpeak_pos_j_1 << " Krel=" << Krel_j_1 << endln; + //cout << " -VE: Uy=" << Uy_neg_j_1 << " Umax=" << Umax_neg_j_1 << " Upeak=" << Upeak_neg_j_1 << " Fpeak=" << Fpeak_neg_j_1 << " Krel=" << Krel_j_1 << endln; - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //%%%%%%%%%%%%%%%%%%%%%%%%%%% MAIN CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////// MAIN CODE ////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Incremental deformation at current step du = ui - ui_1; - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + if (Failure_Flag != 1) { - //// Positive Loading - if (fi_1 >= 0) { - // Early reloading before new excursion occurs - if ((du > 0) && (du_i_1 < 0) && (fi_1 > 0)) { - //cout << " OK6**" << endln; - - // Reloading stiffness KrelA if reloading is to the left of the break point - if (ui <= Ubp_pos_j_1) { - KrelA_pos_j_1 = (Fbp_pos_j_1 - fi_1) / (Ubp_pos_j_1 - ui_1); - // Reloading stiffness KrelA if reloading is to the right of the break point - } - else { - KrelB_pos_j_1 = (Fpeak_pos_j_1 - fi_1) / (Upeak_pos_j_1 - ui_1); - } - } - // Deformation in first reloading branch KrelA - if ((ui <= Ubp_pos_j_1) && (du > 0)) { - //cout << " OK5**" << endln; - df = KrelA_pos_j_1*du; - Umaxp = ui; - // Deformation in second reloading branch KrelB - } - else if ((ui <= Upeak_pos_j_1) && (du > 0)) { - //cout << " OK4**" << endln; - df = (KrelB_pos_j_1*ui + (Fpeak_pos_j_1 - KrelB_pos_j_1*Upeak_pos_j_1)) - fi_1; - Umaxp = ui; - // Deformation in post-yield branch of the backbone - } - else if ((ui <= Umax_pos_j_1) && (du > 0)) { - //cout << " OK3**" << endln; - df = (Fy_pos_j_1 + Kp_pos_j_1*(ui - Uy_pos_j_1)) - fi_1; - Umaxp = ui; - // Deformation in the post-capping branch of the backbone - } - else if ((ui >= Umax_pos_j_1) && (du > 0)) { - //cout << " OK2**" << endln; - - // Deformation in residual branch of backbone - if (ui > Ures_pos_j_1) { - df = Fres_pos_j_1 - fi_1; - if (Fres_pos_j_1 == 0) { - //cout << "Res Fail" << endln; - Failure_Flag = 1; - } - // Deformation in softening branch of the backbone - } - else { - df = (Fmax_pos_j_1 + Kpc_pos_j_1*(ui - Umax_pos_j_1)) - fi_1; - } - Umaxp = ui; - // Deformation in the unloading branch + + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + ////////////////// INITIAL FLAGS CHECKS AND MAIN POINTS COORDINATES /////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + + + // CHECK FOR UNLOADING + if ((fi_1 > 0) && (du <= 0) && (du*du_i_1 <= 0)) { + Unloading_Flag = 1; + Reversal_Flag = 1; + Reloading_Flag = 0; + K_check = (FLastPeak_pos_j_1 - fi_1) / (ULastPeak_pos_j_1 - ui_1); + if ((K_check >= 1.05*Kul_j_1) || (K_check <= 0.95*Kul_j_1)) { // a tailored criteria to avoid registering last peak points during small unload/reload excursions on the unloading branch + FLastPeak_pos_j_1 = fi_1; + ULastPeak_pos_j_1 = ui_1; } - else { - df = Kul_j_1*du; - //cout << " OK1**" << endln; - + } + else if ((fi_1 < 0) && (du > 0) && (du*du_i_1 <= 0)) { + Unloading_Flag = 1; + Reversal_Flag = 1; + Reloading_Flag = 0; + K_check = (FLastPeak_neg_j_1 - fi_1) / (ULastPeak_neg_j_1 - ui_1); + if ((K_check >= 1.01*Kul_j_1) || (K_check <= 0.99*Kul_j_1)) { + FLastPeak_neg_j_1 = fi_1; + ULastPeak_neg_j_1 = ui_1; } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Negative Loading } else { - // Early reloading before new excursion occurs - if ((du < 0) && (du_i_1 > 0) && (fi_1 < 0)) { - // Reloading stiffness KrelA if reloading is to the right of the break point - if (ui >= Ubp_neg_j_1) { - KrelA_neg_j_1 = (Fbp_neg_j_1 - fi_1) / (Ubp_neg_j_1 - ui_1); - // Reloading stiffness KrelA if reloading is to the left of the break point - } - else { - KrelB_neg_j_1 = (Fpeak_neg_j_1 - fi_1) / (Upeak_neg_j_1 - ui_1); - } - } - // Deformation in first reloading branch KrelA - if ((ui >= Ubp_neg_j_1) && (du < 0)) { - df = KrelA_neg_j_1*du; - Umaxn = ui; - // Deformation in second reloading branch KrelB - } - else if ((ui >= Upeak_neg_j_1) && (du < 0)) { - df = (KrelB_neg_j_1*ui + (Fpeak_neg_j_1 - KrelB_neg_j_1*Upeak_neg_j_1)) - fi_1; - Umaxn = ui; - // Deformation in post-yield branch of the backbone - } - else if ((ui >= Umax_neg_j_1) && (du < 0)) { - df = (Fy_neg_j_1 + Kp_neg_j_1*(ui - Uy_neg_j_1)) - fi_1; - Umaxn = ui; - // Deformationin the post-capping branch of the backbone - } - else if ((ui <= Umax_neg_j_1) && (du < 0)) { - // Deformation in residual branch of backbone - if (ui < Ures_neg_j_1) { - df = Fres_neg_j_1 - fi_1; - if (Fres_neg_j_1 == 0) { - //cout << " Res Fail" << endln; - Failure_Flag = 1; - } - // Deformation in the softening branch of the backbone - } - else { - df = Fmax_neg_j_1 + Kpc_neg_j_1*(ui - Umax_neg_j_1) - fi_1; - } - Umaxn = ui; - } - else { - // Deformation in the unloading branch - df = Kul_j_1 *du; - } + Reversal_Flag = 0; + } + + // CHECK FOR RELOADING + if ((fi_1 > 0) && (du > 0) && (du_i_1 < 0)) { + Reloading_Flag = 1; + Unloading_Flag = 0; } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Deterioration Parameters - // Internal energy increment - dEi = 0.5*(df + 2 * fi_1)*(du); - //cout << " ENERGY: dEi=" << dEi << " Kul=" << Kul_j_1 << " du=" << du << " df=" << df << endln; - - // Positive excursion flag - if ((fi_1 + df >= 0) && (fi_1 < 0)) { + else if ((fi_1 < 0) && (du < 0) && (du_i_1 > 0)) { + Reloading_Flag = 1; + Unloading_Flag = 0; + } + + + // CHECK FOR NEW EXCURSION + if ((fi_1 < 0) && (fi_1 + du * Kul_j_1 >= 0)) { Excursion_Flag = 1; - // Negative excursion flag + Reloading_Flag = 0; + Unloading_Flag = 0; + u0 = ui_1 - (fi_1 / Kul_j_1); } - else if ((fi_1 + df <= 0) && (fi_1 > 0)) { + else if ((fi_1 > 0) && (fi_1 + du * Kul_j_1 <= 0)) { Excursion_Flag = 1; + Reloading_Flag = 0; + Unloading_Flag = 0; + u0 = ui_1 - (fi_1 / Kul_j_1); } else { Excursion_Flag = 0; } - // Update beta parameters at new excursion + + // UPDATE GLOBAL PEAK POINTS + if ((fi_1 >= 0) && (ui_1 >= Upeak_pos_j_1)) { + Upeak_pos_j_1 = ui_1; + Fpeak_pos_j_1 = fi_1; + } + else if ((fi_1 < 0) && (ui_1 <= Upeak_neg_j_1)) { + Upeak_neg_j_1 = ui_1; + Fpeak_neg_j_1 = fi_1; + } + + // CHECK FOR YIELDING + if ((Upeak_pos_j_1 > Uy_pos_j_1) || (Upeak_neg_j_1 < Uy_neg_j_1)) { + Yield_Flag = 1; + } + + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////// UPDATE DETERIORATION PARAMETERS AND BACKBONE CURVE //////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + + // UPDATE DETERIORATION PARAMETERS AT EACH NEW EXCURSION + if (Excursion_Flag == 1) { - // Total energy dissipated in all previous excursions - Epj = Energy_Acc + dEi; - // Energy dissipated in previous excursion - Ei = Epj - Energy_Diss; - betaS = pow((Ei / (EtS - Epj)), c_S); - betaC = pow((Ei / (EtC - Epj)), c_C); - betaA = pow((Ei / (EtA - Epj)), c_A); + Ei = fmax(0,Energy_Acc - Energy_Diss); + betaS = pow((Ei / (EtS - Energy_Acc)), c_S); + betaC = pow((Ei / (EtC - Energy_Acc)), c_C); + betaA = pow((Ei / (EtA - Energy_Acc)), c_A); + Energy_Diss = Energy_Acc; } else { - // Total energy dissipated in all previous excursions - Epj = Energy_Diss; betaS = 0; betaC = 0; betaA = 0; } - // Onset of unloading - Unloading_Flag = du*du_i_1 < 0 && (ui_1 >= Upeak_pos_j_1 || ui_1 <= Upeak_neg_j_1); - if (Unloading_Flag == 1) { - // Total energy dissipated until point of unloading - EpjK = dEi + Energy_Acc - 0.5*(pow((fi_1 + df), 2)) / Kul_j_1; - // Energy dissipated in current excursion until point of unloading - EiK = EpjK - Energy_Diss; + + if (Reversal_Flag == 1) { + EpjK = Energy_Acc - 0.5*(fi_1 / Kul_j_1)*fi_1; + EiK = Energy_Acc - Energy_Diss + 0.5*(fi_1 / Kul_j_1)*fi_1; betaK = pow((EiK / (EtK - EpjK)), c_K); + Kul_j_1 = Kul_j_1 * (1 - betaK); } else { betaK = 0; } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Target Peak Deformation - New_Peak_Pos_Flag = 0; - New_Peak_Neg_Flag = 0; - // Update target peak deformation for positive loading - if (Umaxp >= Upeak_pos_j_1) { - New_Peak_Pos_Flag = 1; - Upeak_pos_j_1 = Umaxp; - Fpeak_pos_j_1 = fi_1 + df; - // Plastic offset for positive loading - Plastic_Offset_pos_j_1 = Upeak_pos_j_1 - Fpeak_pos_j_1 / Kul_j_1; - } - // Update target peak deformation for negative loading - if (Umaxn <= Upeak_neg_j_1) { - New_Peak_Neg_Flag = 1; - Upeak_neg_j_1 = Umaxn; - Fpeak_neg_j_1 = fi_1 + df; - // Plastic offset for negative loading - Plastic_Offset_neg_j_1 = Upeak_neg_j_1 - Fpeak_neg_j_1 / Kul_j_1; - } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Positive Backbone and Target Peak Point + + // Update Positive Backbone and Target Peak Point if (Excursion_Flag == 1) { // Positive loading backbone - if (fi_1 < 0) { + if ((fi_1 < 0) && (Yield_Flag==1)) { // Basic strength deterioration: Yield point Uy_pos_j_1 = std::max(Uy_pos_j_1 - Fy_pos_j_1 *betaS* D_pos / Ke, Fres_pos_j_1 / Ke); Fy_pos_j_1 = std::max(Fy_pos_j_1 *(1 - betaS* D_pos), Fres_pos_j_1); @@ -338,30 +273,25 @@ int IMKPinching::setTrialStrain(double strain, double strainRate) Umax_pos_j_1 = sPCpcp; // Accelerated reloading stiffness deterioration: Target peak deformation point Upeak_pos_j_1 = (1 + betaA* D_pos)*Upeak_pos_j_1; - // Target peak deformation in reloading branch of the updated backbone - if (Upeak_pos_j_1 <= Uy_pos_j_1) { + if (Upeak_pos_j_1 <= Uy_pos_j_1) { Fpeak_pos_j_1 = Ke*Upeak_pos_j_1; // Target peak deformation in post-yield branch of the updated backbone - } - else if (Upeak_pos_j_1 <= Umax_pos_j_1) { + } else if (Upeak_pos_j_1 <= Umax_pos_j_1) { Fpeak_pos_j_1 = Kp_pos_j_1 *(Upeak_pos_j_1 - Uy_pos_j_1) + Fy_pos_j_1; // Target peak deformation in post-capping branch of the updated backbone - } - else { + } else { Fpeak_pos_j_1 = max(Kpc_pos_j_1*(Upeak_pos_j_1 - Umax_pos_j_1) + Fmax_pos_j_1, Fres_pos_j_1); } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Negative Backbone and Target Peak Point - } - else { + } + else if ((fi_1 >= 0) && (Yield_Flag==1)) { + // Update Negative Backbone and Target Peak Point // Basic strength deterioration: Yield point Uy_neg_j_1 = min(Uy_neg_j_1 - Fy_neg_j_1 *betaS* D_neg / Ke, Fres_neg_j_1 / Ke); Fy_neg_j_1 = min(Fy_neg_j_1 *(1 - betaS* D_neg), Fres_neg_j_1); // Basic strength deterioration: Post-yield stiffness if (Fy_neg_j_1 != Fres_neg_j_1) { Kp_neg_j_1 = Kp_neg_j_1 *(1 - betaS* D_neg); - } - else { + } else { Kp_neg_j_1 = 0; } // Basic strength deterioration: Capping point @@ -388,97 +318,308 @@ int IMKPinching::setTrialStrain(double strain, double strainRate) } } } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Krel Based on New Peak Targets at New Positive Excursion - if ((fi_1 + df >= 0) && (fi_1 < 0)) { - Fp = kappaF*Fpeak_pos_j_1; - // Deformation at reloading - u0 = ui_1 - (fi_1) / Kul_j_1; - if (u0 < 0) { - // Deformation at break point - Ubp_pos_j_1 = (1 - kappaD)*Plastic_Offset_pos_j_1; - // Force at break point - Fbp_pos_j_1 = Fp*(Ubp_pos_j_1 - u0) / (Upeak_pos_j_1 - u0); - } - // Reloading is to the left of the break point - if (u0 < Ubp_pos_j_1) { - // Reloading stiffness KrelA after new excursion - KrelA_pos_j_1 = (Fbp_pos_j_1) / (Ubp_pos_j_1 - u0); - // Reloading stiffness KrelB after new excursion - KrelB_pos_j_1 = (Fpeak_pos_j_1 - Fbp_pos_j_1) / (Upeak_pos_j_1 - Ubp_pos_j_1); - df = ((ui - u0)*KrelA_pos_j_1) - fi_1; - // Reloading is to the right of the break point + + // Update Deformation at Residual Points + Ures_pos_j_1 = (Fres_pos_j_1 - Fmax_pos_j_1 + Kpc_pos_j_1 * Umax_pos_j_1) / Kpc_pos_j_1; + Ures_neg_j_1 = (Fres_neg_j_1 - Fmax_neg_j_1 + Kpc_neg_j_1 * Umax_neg_j_1) / Kpc_neg_j_1; + + // CHECK TARGET POINT: LAST CYCLE PEAK or GLOBAL PEAK (i.e., Modified Clough rule, see Mahin & Bertero 1975) + if (Excursion_Flag == 1) { + if (du >= 0) { + Krel_LastPeak = FLastPeak_pos_j_1 / (ULastPeak_pos_j_1 - u0); + Krel_GlobalPeak = Fpeak_pos_j_1 / (Upeak_pos_j_1 - u0); } else { - // Reloading stiffness after new excursion - KrelB_pos_j_1 = (Fpeak_pos_j_1) / (Upeak_pos_j_1 - u0); - df = ((ui - u0)*KrelB_pos_j_1) - fi_1; + Krel_LastPeak = FLastPeak_neg_j_1 / (ULastPeak_neg_j_1 - u0); + Krel_GlobalPeak = Fpeak_neg_j_1 / (Upeak_neg_j_1 - u0); } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Krel Based on New Peak Targets at New Negative Excursion - } - else if ((fi_1 + df < 0) && (fi_1 > 0)) { - Fp = kappaF*Fpeak_neg_j_1; - // Deformation at reloading - u0 = ui_1 - (fi_1) / Kul_j_1; - if (u0 > 0) { - // Deformation at break point - Ubp_neg_j_1 = (1 - kappaD)*Plastic_Offset_neg_j_1; - // Force at break point - Fbp_neg_j_1 = Fp*(Ubp_neg_j_1 - u0) / (Upeak_neg_j_1 - u0); + + if ((du>=0) && (FLastPeak_pos_j_1 >= Fpeak_pos_j_1)) { + TargetPeak_Flag=0; + } else if ((du<=0) && (FLastPeak_neg_j_1 <= Fpeak_neg_j_1)) { + TargetPeak_Flag=0; } - // Reloading is to the right of the break point - if (u0 > Ubp_neg_j_1) { - // Reloading stiffness KrelA after new excursion - KrelA_neg_j_1 = (Fbp_neg_j_1) / (Ubp_neg_j_1 - u0); - // Reloading stiffness KrelB after new excursion - KrelB_neg_j_1 = (Fpeak_neg_j_1 - Fbp_neg_j_1) / (Upeak_neg_j_1 - Ubp_neg_j_1); - df = ((ui - u0)*KrelA_neg_j_1) - fi_1; - // Reloading is to the left of the break point + else if (abs(Krel_LastPeak) <= abs(Krel_GlobalPeak)) { + TargetPeak_Flag = 0; + } + else if ((du >= 0) && (abs((ULastPeak_pos_j_1 - Upeak_pos_j_1) / Upeak_pos_j_1) < 0.05) && (abs(Krel_LastPeak) <= 1.05*abs(Krel_GlobalPeak))) { + TargetPeak_Flag = 0; + } + else if ((du <= 0) && (abs((ULastPeak_neg_j_1 - Upeak_neg_j_1) / Upeak_neg_j_1) < 0.05) && (abs(Krel_LastPeak) <= 1.05*abs(Krel_GlobalPeak))) { + TargetPeak_Flag = 0; } else { - // Reloading stiffness after new excursion - KrelB_neg_j_1 = (Fpeak_neg_j_1) / (Upeak_neg_j_1 - u0); - df = ((ui - u0)*KrelB_neg_j_1) - fi_1; + TargetPeak_Flag = 1; } } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Unloading Stiffness - if (Unloading_Flag == 1) { - Kul_j_1 = (1 - betaK)*Kul_j_1; - df = Kul_j_1*du; + + // COMPUTE PINCHING POINT COORDINATES AT EACH NEW EXCURSION + if (Excursion_Flag==1) { + if (du>0) { + Upl = Upeak_pos_j_1 - (Fpeak_pos_j_1/Kul_j_1); + Ubp = (1-kappaD) * Upl ; + Fbp = kappaF * Fpeak_pos_j_1 * abs((Ubp -u0)/(Upeak_pos_j_1 -u0)); + } + else if (du<0) { + Upl = Upeak_neg_j_1 - (Fpeak_neg_j_1/Kul_j_1); + Ubp = (1-kappaD) * Upl ; + Fbp = kappaF * Fpeak_neg_j_1 * abs((Ubp -u0)/(Upeak_neg_j_1 -u0)); + } } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Update Deformation at Residual Points - // Deformation at residual onset for positive backbone - Ures_pos_j_1 = (Fres_pos_j_1 - Fmax_pos_j_1 + Kpc_pos_j_1 * Umax_pos_j_1) / Kpc_pos_j_1; - // Deformation at residual onset for negative backbone - Ures_neg_j_1 = (Fres_neg_j_1 - Fmax_neg_j_1 + Kpc_neg_j_1 * Umax_neg_j_1) / Kpc_neg_j_1; - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Force - fi = fi_1 + df; + //cout << " Upl =" << Upl << " Ubp =" << Ubp << " Fbp =" << Fbp << " kF =" << kappaF << " kD =" << kappaD << endln; + + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////// COMPUTE FORCE INCREMENT ///////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + + // Positive Force + if (fi_1 + du * Kul_j_1 >= 0) { + + // CASE 0: At THE ELASTIC SLOPE + if ((ui>=0) && (Upeak_pos_j_1 <= Uy_pos_j_1) && (Yield_Flag==0)) { + if (ui >= Uy_pos_j_1) { + df = Ke*(Uy_pos_j_1 - ui_1) + Kp_pos_j_1*(ui - Uy_pos_j_1); + } else { + df = du * Ke; + } + //cout << " Case = 0+" << endln; + + // CASE 1: EACH NEW EXCURSION + } else if (Excursion_Flag==1) { + if ((TargetPeak_Flag==0) && (u0>=Ubp)) { + Krel_j_1 = Fpeak_pos_j_1 / (Upeak_pos_j_1 - u0); + } + else if ((TargetPeak_Flag==0) && (u0<=Ubp)) { + Krel_j_1 = Fbp / (Ubp - u0); + } + else if (TargetPeak_Flag==1) { + Krel_j_1 = FLastPeak_pos_j_1 / (ULastPeak_pos_j_1 - u0); + } + + df = Kul_j_1*(u0 - ui_1) + Krel_j_1*(ui - u0); + //cout << " Case = 1+" << endln; + + // CASE 2: WHEN RELOADING + } else if ((Reloading_Flag==1) && (ui <= ULastPeak_pos_j_1)) { + df = du * Kul_j_1; + //cout << " Case = 2+" << endln; + + // CASE 2: WHEN UNLOADING + } else if (Unloading_Flag==1) { + df = du * Kul_j_1; + //cout << " Case = 2+" << endln; + + // CASE 3: WHEN RELOADING BUT BETWEEN LAST CYCLE PEAK POINT AND GLOBAL PEAK POINT + } else if ((Reloading_Flag==1) && (ui >= ULastPeak_pos_j_1) && (ui <= Upeak_pos_j_1) && (FLastPeak_pos_j_1 <= Fpeak_pos_j_1)) { + if (TargetPeak_Flag==1) { + if ((FLastPeak_pos_j_1 <= Fbp) && (ui <= Ubp)) { + Krel_j_1 = (Fbp-FLastPeak_pos_j_1)/(Ubp-ULastPeak_pos_j_1); + } else if ((FLastPeak_pos_j_1 <= Fbp) && (ui >= Ubp)) { + Krel_j_1 = (Fpeak_pos_j_1-Fbp)/(Upeak_pos_j_1-Ubp); + } else { + Krel_j_1 = (Fpeak_pos_j_1-FLastPeak_pos_j_1)/(Upeak_pos_j_1-ULastPeak_pos_j_1); + } + df = du * Krel_j_1; + } + else if (TargetPeak_Flag==0) { + Krel_j_1 = Fbp / (Ubp - u0); + if (ui_1 <= ULastPeak_pos_j_1) { + df = Kul_j_1*(ULastPeak_pos_j_1 -ui_1) + Krel_j_1 *(ui -ULastPeak_pos_j_1); + } else if (ui<= Ubp) { + df = du * Krel_j_1; + } else if (ui>= Ubp) { + Krel_j_1 = (Fpeak_pos_j_1 - Fbp) / (Upeak_pos_j_1 - Ubp); + df = du * Krel_j_1; + } + } + //cout << " Case = 3+" << endln; - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Refine Peaks - if (New_Peak_Pos_Flag == 1) { - Fpeak_pos_j_1 = fi; + // CASE 4: WHEN LOADING IN GENERAL TOWARDS THE TARGET PEAK + } else if ((du >= 0) && (ui <= Upeak_pos_j_1)) { + if ((TargetPeak_Flag==0) && (ui>=Ubp)) { + Krel_j_1 = (Fpeak_pos_j_1 - fi_1) / (Upeak_pos_j_1 - ui_1); + } + else if ((TargetPeak_Flag==0) && (ui<=Ubp)) { + Krel_j_1 = (Fbp) / (Ubp - u0); + } + else if ((TargetPeak_Flag==1) && (ui<=ULastPeak_pos_j_1)) { + Krel_j_1 = (FLastPeak_pos_j_1) / (ULastPeak_pos_j_1 - u0); + } + else if ((TargetPeak_Flag==1) && (ui>=ULastPeak_pos_j_1)) { + if ((FLastPeak_pos_j_1 <= Fbp) && (ui <= Ubp)) { + Krel_j_1 = (Fbp-FLastPeak_pos_j_1)/(Ubp-ULastPeak_pos_j_1); + } else if ((FLastPeak_pos_j_1 <= Fbp) && (ui >= Ubp)) { + Krel_j_1 = (Fpeak_pos_j_1-Fbp)/(Upeak_pos_j_1-Ubp); + } else { + Krel_j_1 = (Fpeak_pos_j_1-FLastPeak_pos_j_1)/(Upeak_pos_j_1-ULastPeak_pos_j_1); + } + } + df = du * Krel_j_1; + //cout << " Case = 4+" << endln; + + // CASE 6: WHEN LOADING BEYOND THE TARGET PEAK BUT BEFORE THE CAPPING POINT + } else if ((du >= 0) && (ui <= Umax_pos_j_1)) { + df = du * Kp_pos_j_1; + //cout << " Case = 6+" << endln; + + // CASE 7: WHEN LOADING AND BETWEEN THE CAPPING POINT AND THE RESIDUAL POINT + } else if ((du > 0) && (ui >= Umax_pos_j_1) && (ui <= Ures_pos_j_1)) { + if ((ui_1<= Umax_pos_j_1) && (ui >= Umax_pos_j_1)) { + df = Kp_pos_j_1 * (Umax_pos_j_1 - ui_1) + Kpc_pos_j_1 * (ui - Umax_pos_j_1); + } else { + df = du * Kpc_pos_j_1; + } + //cout << " Case = 7+" << endln; + + // CASE 8: WHEN LOADING AND BEYOND THE RESIDUAL POINT + } else if ((du > 0) && (ui >= Ures_pos_j_1)) { + df = 0.0; + if (Fres_pos_j_1 == 0) { + Failure_Flag = 1; + } + //cout << " Case = 8+" << endln; + } } - else if (New_Peak_Neg_Flag == 1) { - Fpeak_neg_j_1 = fi; + + // Negative Force + if (fi_1 + du * Kul_j_1 <= 0) { + + // CASE 0: At THE ELASTIC SLOPE + if ((ui<=0) && (Upeak_neg_j_1 >= Uy_neg_j_1) && (Yield_Flag==0)) { + if (ui <= Uy_neg_j_1) { + df = Ke*(Uy_neg_j_1 - ui_1) + Kp_neg_j_1 * (ui - Uy_neg_j_1); + } else { + df = du * Ke; + } + //cout << " Case = 0-" << endln; + + // CASE 1: EACH NEW EXCURSION + } else if (Excursion_Flag==1) { + if ((TargetPeak_Flag==0) && (u0<=Ubp)) { + Krel_j_1 = Fpeak_neg_j_1 / (Upeak_neg_j_1 - u0); + } + else if ((TargetPeak_Flag==0) && (u0>=Ubp)) { + Krel_j_1 = Fbp / (Ubp - u0); + } + else if (TargetPeak_Flag==1) { + Krel_j_1 = FLastPeak_neg_j_1 / (ULastPeak_neg_j_1 - u0); + } + df = Kul_j_1 * (u0 - ui_1) + Krel_j_1 * (ui - u0); + //cout << " Case = 1-" << endln; + + // CASE 2: WHEN RELOADING + } else if ((Reloading_Flag==1) && (ui >= ULastPeak_neg_j_1)) { + df = du * Kul_j_1; + //cout << " Case = 2-" << endln; + + // CASE 2: WHEN UNLOADING + } else if (Unloading_Flag==1) { + df = du * Kul_j_1; + //cout << " Case = 2-" << endln; + + // CASE 3: WHEN RELOADING BUT BETWEEN LAST CYCLE PEAK POINT AND GLOBAL PEAK POINT + } else if ((Reloading_Flag==1) && (ui <= ULastPeak_neg_j_1) && (ui >= Upeak_neg_j_1) && (FLastPeak_neg_j_1 >= Fpeak_neg_j_1)) { + if (TargetPeak_Flag==1) { + if ((FLastPeak_neg_j_1 >= Fbp) && (ui <= Ubp)) { + Krel_j_1 = (Fbp-FLastPeak_neg_j_1)/(Ubp-ULastPeak_neg_j_1); + } else if ((FLastPeak_neg_j_1 >= Fbp) && (ui <= Ubp)) { + Krel_j_1 = (Fpeak_neg_j_1-Fbp)/(Upeak_neg_j_1-Ubp); + } else { + Krel_j_1 = (Fpeak_neg_j_1-FLastPeak_neg_j_1)/(Upeak_neg_j_1-ULastPeak_neg_j_1); + } + df = du * Krel_j_1; + } + else if (TargetPeak_Flag==0) { + Krel_j_1 = Fbp / (Ubp - u0); + if (ui_1 >= ULastPeak_neg_j_1) { + df = Kul_j_1*(ULastPeak_neg_j_1 -ui_1) + Krel_j_1 *(ui -ULastPeak_neg_j_1); + } else if (ui>= Ubp) { + df = du * Krel_j_1; + } else if (ui<= Ubp) { + Krel_j_1 = (Fpeak_neg_j_1 - Fbp) / (Upeak_neg_j_1 - Ubp); + df = du * Krel_j_1; + } + } + //cout << " Case = 3-" << endln; + + // CASE 4: WHEN LOADING IN GENERAL TOWARDS THE TARGET PEAK + } else if ((du <= 0) && (ui >= Upeak_neg_j_1)) { + if ((TargetPeak_Flag==0) && (ui<=Ubp)) { + Krel_j_1 = (Fpeak_neg_j_1 - fi_1) / (Upeak_neg_j_1 - ui_1); + } + else if ((TargetPeak_Flag==0) && (ui>=Ubp)) { + Krel_j_1 = (Fbp) / (Ubp - u0); + } + else if ((TargetPeak_Flag==1) && (ui>=ULastPeak_neg_j_1)) { + Krel_j_1 = (FLastPeak_neg_j_1) / (ULastPeak_neg_j_1 - u0); + } + else if ((TargetPeak_Flag==1) && (ui<=ULastPeak_neg_j_1)) { + if ((FLastPeak_neg_j_1 >= Fbp) && (ui <= Ubp)) { + Krel_j_1 = (Fbp-FLastPeak_neg_j_1)/(Ubp-ULastPeak_neg_j_1); + } else if ((FLastPeak_neg_j_1 >= Fbp) && (ui <= Ubp)) { + Krel_j_1 = (Fpeak_neg_j_1-Fbp)/(Upeak_neg_j_1-Ubp); + } else { + Krel_j_1 = (Fpeak_neg_j_1-FLastPeak_neg_j_1)/(Upeak_neg_j_1-ULastPeak_neg_j_1); + } + } + df = du * Krel_j_1; + //cout << " Case = 4-" << endln; + + // CASE 6: WHEN LOADING BEYOND THE TARGET PEAK BUT BEFORE THE CAPPING POINT + } else if ((du <= 0) && (ui >= Umax_neg_j_1)) { + df = du * Kp_neg_j_1; + //cout << " Case = 6-" << endln; + + // CASE 7: WHEN LOADING AND BETWEEN THE CAPPING POINT AND THE RESIDUAL POINT + } else if ((du < 0) && (ui <= Umax_neg_j_1) && (ui >= Ures_neg_j_1)) { + if ((ui_1>=Umax_neg_j_1) && (ui<=Umax_neg_j_1)) { + df = Kp_neg_j_1 * (Umax_neg_j_1 - ui_1) + Kpc_neg_j_1 * (ui - Umax_neg_j_1); + } else { + df = du * Kpc_neg_j_1; + } + //cout << " Case = 7-" << endln; + + // CASE 8: WHEN LOADING AND BEYOND THE RESIDUAL POINT + } else if ((du < 0) && (ui <= Ures_neg_j_1)) { + df = 0.0; + if (Fres_neg_j_1 == 0) { + Failure_Flag = 1; + } + //cout << " Case = 8-" << endln; + + } } - // --------------------------------------------------------------------------------------------------------------------------------------------------------------------- - //// Failure - // Failure criteria (Tolerance = 1//) + + + // Force + fi = fi_1 + df; + //cout << " Excurion=" << Excursion_Flag << " Failure=" << Failure_Flag << " Reload=" << Reloading_Flag << " Unload=" << Unloading_Flag << " Yield=" << Yield_Flag << endln; + //cout << " STEP: ui_1=" << ui_1 << " ui=" << ui << " fi_1=" << fi_1 << " fi=" << fi << endln; + + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + // CHECK FOR FAILURE + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + + // Failure criteria (Tolerance = 1//) FailS = ((betaS < -0.01) || (betaS > 1.01)); FailC = ((betaC < -0.01) || (betaC > 1.01)); FailA = ((betaA < -0.01) || (betaA > 1.01)); FailK = ((betaK < -0.01) || (betaK > 1.01)); //cout << " ENERGY: EtS=" << EtS << " EtC=" << EtC << " EtA=" << EtA << " EtK=" << EtK << endln; - //cout << " ENERGY: dEi=" << dEi << " Ei=" << Ei << " Epj=" << Epj << " Energy_Diss=" << Energy_Diss << " Energy_Acc=" << Energy_Acc << endln; + //cout << " ENERGY: dEi=" << dEi << " Ei=" << Ei << " Energy_Diss=" << Energy_Diss << " Energy_Acc=" << Energy_Acc << endln; //cout << " ENERGY: betaS=" << betaS << " betaC=" << betaC << " betaA=" << betaA << " betaK=" << betaK << endln; //cout << " FAIL: FailS=" << FailS << " FailC=" << FailC << " FailA=" << FailA << " FailK=" << FailK << endln; if (FailS || FailC || FailA || FailK) { + fi = 0; //cout << " Energy Fail" << endln; Failure_Flag = 1; } @@ -497,47 +638,47 @@ int IMKPinching::setTrialStrain(double strain, double strainRate) //cout << " Strength Fail" << endln; Failure_Flag = 1; } + + dEi = 0.5*(fi + fi_1)*du; // Internal energy increment + } else { fi = 0; dEi = 0; - Epj = Energy_Acc + dEi; + //cout << " FAILURE OCCURED" << endln; } //// Energy - Energy_Acc = Energy_Acc + dEi; // Total internal energy accumulated until current increment - Energy_Diss = Epj; // Total energy dissipated in all previous excursions + Energy_Acc = Energy_Acc + dEi; //// Update Variables du_i_1 = du; - Umaxp = 0; - Umaxn = 0; // Tangent Stiffeness Calculation if (fi == fi_1) { TangentK = pow(10., -6); - ki = pow(10., -6); + ki = pow(10., -6); } - if ((ui == ui_1)) { - ki = Ke; - fi = fi_1; + if (ui == ui_1) { + ki = Ke; + fi = fi_1; TangentK = Ke; } else { - ki = (fi - fi_1) / (du); + ki = (fi - fi_1) / (du); TangentK = (fi - fi_1) / (du); } - - //cout << " fi=" << fi << endln; //cout << "***********************" << endln; - // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - // %%%%%%%%%%%%%%%%%%%%%% END OF MAIN CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%% - // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////// END OF MAIN CODE /////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// return 0; } @@ -585,48 +726,52 @@ int IMKPinching::commitState(void) cUy_pos_j_1 = Uy_pos_j_1; cUmax_pos_j_1 = Umax_pos_j_1; - cUu_pos_j_1 = Uu_pos_j_1; cFy_pos_j_1 = Fy_pos_j_1; cFmax_pos_j_1 = Fmax_pos_j_1; cUpeak_pos_j_1 = Upeak_pos_j_1; cFpeak_pos_j_1 = Fpeak_pos_j_1; - cUbp_pos_j_1 = Ubp_pos_j_1; - cFbp_pos_j_1 = Fbp_pos_j_1; + cUres_pos_j_1 = Ures_pos_j_1; cFres_pos_j_1 = Fres_pos_j_1; cKp_pos_j_1 = Kp_pos_j_1; cKpc_pos_j_1 = Kpc_pos_j_1; - cKrelA_pos_j_1 = KrelA_pos_j_1; - cKrelB_pos_j_1 = KrelB_pos_j_1; - cPlastic_Offset_pos_j_1 = Plastic_Offset_pos_j_1; cUy_neg_j_1 = Uy_neg_j_1; cUmax_neg_j_1 = Umax_neg_j_1; - cUu_neg_j_1 = Uu_neg_j_1; cFy_neg_j_1 = Fy_neg_j_1; cFmax_neg_j_1 = Fmax_neg_j_1; cUpeak_neg_j_1 = Upeak_neg_j_1; cFpeak_neg_j_1 = Fpeak_neg_j_1; - cUbp_neg_j_1 = Ubp_neg_j_1; - cFbp_neg_j_1 = Fbp_neg_j_1; + cUres_neg_j_1 = Ures_neg_j_1; cFres_neg_j_1 = Fres_neg_j_1; cKp_neg_j_1 = Kp_neg_j_1; cKpc_neg_j_1 = Kpc_neg_j_1; - cKrelA_neg_j_1 = KrelA_neg_j_1; - cKrelB_neg_j_1 = KrelB_neg_j_1; - cPlastic_Offset_neg_j_1 = Plastic_Offset_neg_j_1; cKul_j_1 = Kul_j_1; - cFailure_Flag = Failure_Flag; - cExcursion_Flag = Excursion_Flag; - cEnergy_Acc = Energy_Acc; cEnergy_Diss = Energy_Diss; - cUmaxp = Umaxp; - cUmaxn = Umaxn; + cu0 = u0; + + cULastPeak_pos_j_1 = ULastPeak_pos_j_1; + cFLastPeak_pos_j_1 = FLastPeak_pos_j_1; + cULastPeak_neg_j_1 = ULastPeak_neg_j_1; + cFLastPeak_neg_j_1 = FLastPeak_neg_j_1; + + cFailure_Flag = Failure_Flag; + cExcursion_Flag = Excursion_Flag; + cReloading_Flag = Reloading_Flag; + cUnloading_Flag = Unloading_Flag; + cTargetPeak_Flag = TargetPeak_Flag; + cYield_Flag = Yield_Flag; + cReversal_Flag = Reversal_Flag; + + cKrel_j_1 = Krel_j_1; + + cUbp = Ubp; + cFbp = Fbp; return 0; } @@ -649,93 +794,98 @@ int IMKPinching::revertToLastCommit(void) Uy_pos_j_1 = cUy_pos_j_1; Umax_pos_j_1 = cUmax_pos_j_1; - Uu_pos_j_1 = cUu_pos_j_1; Fy_pos_j_1 = cFy_pos_j_1; Fmax_pos_j_1 = cFmax_pos_j_1; Upeak_pos_j_1 = cUpeak_pos_j_1; Fpeak_pos_j_1 = cFpeak_pos_j_1; - Ubp_pos_j_1 = cUbp_pos_j_1; - Fbp_pos_j_1 = cFbp_pos_j_1; + Ures_pos_j_1 = cUres_pos_j_1; Fres_pos_j_1 = cFres_pos_j_1; Kp_pos_j_1 = cKp_pos_j_1; Kpc_pos_j_1 = cKpc_pos_j_1; - KrelA_pos_j_1 = cKrelA_pos_j_1; - KrelB_pos_j_1 = cKrelB_pos_j_1; - Plastic_Offset_pos_j_1 = cPlastic_Offset_pos_j_1; + Uy_neg_j_1 = cUy_neg_j_1; Umax_neg_j_1 = cUmax_neg_j_1; - Uu_neg_j_1 = cUu_neg_j_1; Fy_neg_j_1 = cFy_neg_j_1; Fmax_neg_j_1 = cFmax_neg_j_1; Upeak_neg_j_1 = cUpeak_neg_j_1; Fpeak_neg_j_1 = cFpeak_neg_j_1; - Ubp_neg_j_1 = cUbp_neg_j_1; - Fbp_neg_j_1 = cFbp_neg_j_1; + Ures_neg_j_1 = cUres_neg_j_1; Fres_neg_j_1 = cFres_neg_j_1; Kp_neg_j_1 = cKp_neg_j_1; Kpc_neg_j_1 = cKpc_neg_j_1; - KrelA_neg_j_1 = cKrelA_neg_j_1; - KrelB_neg_j_1 = cKrelB_neg_j_1; - Plastic_Offset_neg_j_1 = cPlastic_Offset_neg_j_1; + Kul_j_1 = cKul_j_1; - Failure_Flag = cFailure_Flag; - Excursion_Flag = cExcursion_Flag; + Energy_Acc = cEnergy_Acc; Energy_Diss = cEnergy_Diss; - Umaxp = cUmaxp; - Umaxn = cUmaxn; + ULastPeak_pos_j_1 = cULastPeak_pos_j_1; + FLastPeak_pos_j_1 = cFLastPeak_pos_j_1; + ULastPeak_neg_j_1 = cULastPeak_neg_j_1; + FLastPeak_neg_j_1 = cFLastPeak_neg_j_1; + + Failure_Flag = cFailure_Flag; + Excursion_Flag = cExcursion_Flag; + Reloading_Flag = cReloading_Flag; + Unloading_Flag = cUnloading_Flag; + TargetPeak_Flag = cTargetPeak_Flag; + Yield_Flag = cYield_Flag; + Reversal_Flag = cReversal_Flag; + + u0 = cu0; + Krel_j_1 = cKrel_j_1; + + Upl = cUpl; + Ubp = cUbp; + Fbp = cFbp; + return 0; } int IMKPinching::revertToStart(void) { - /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\\ - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ONE TIME CALCULATIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\\ - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\\ + //////////////////////////////////////////////////////////////////// ONE TIME CALCULATIONS ////////////////////////////////////////////////////////////////////\\ + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + - Failure_Flag = 0; - Excursion_Flag = 0; - Unloading_Flag = 0; - New_Peak_Pos_Flag = 0; - New_Peak_Neg_Flag = 0; betaS = 0; betaC = 0; betaK = 0; betaA = 0; - Uy_pos = Fy_pos / Ke; + Uy_pos = Fy_pos / Ke; Umax_pos = Uy_pos + Up_pos; Fmax_pos = FmaxFy_pos*Fy_pos; - Kp_pos = (Fmax_pos - Fy_pos) / Up_pos; - Kpc_pos = Fmax_pos / Upc_pos; + Kp_pos = (Fmax_pos - Fy_pos) / Up_pos; + Kpc_pos = Fmax_pos / Upc_pos; - Uy_neg = Fy_neg / Ke; + Uy_neg = Fy_neg / Ke; Umax_neg = Uy_neg + Up_neg; Fmax_neg = FmaxFy_neg*Fy_neg; - Kp_neg = (Fmax_neg - Fy_neg) / Up_neg; - Kpc_neg = Fmax_neg / Upc_neg; + Kp_neg = (Fmax_neg - Fy_neg) / Up_neg; + Kpc_neg = Fmax_neg / Upc_neg; Upeak_pos_j_1 = Uy_pos; Fpeak_pos_j_1 = Fy_pos; Upeak_neg_j_1 = -Uy_neg; Fpeak_neg_j_1 = -Fy_neg; - - Uy_pos_j_1 = Uy_pos; - Fy_pos_j_1 = Fy_pos; - Kp_pos_j_1 = Kp_pos; + + Uy_pos_j_1 = Uy_pos; + Fy_pos_j_1 = Fy_pos; + Kp_pos_j_1 = Kp_pos; Kpc_pos_j_1 = -Kpc_pos; - Uy_neg_j_1 = -Uy_neg; - Fy_neg_j_1 = -Fy_neg; - Kp_neg_j_1 = Kp_neg; + Uy_neg_j_1 = -Uy_neg; + Fy_neg_j_1 = -Fy_neg; + Kp_neg_j_1 = Kp_neg; Kpc_neg_j_1 = -Kpc_neg; Umax_pos_j_1 = Umax_pos; @@ -745,87 +895,91 @@ int IMKPinching::revertToStart(void) Fmax_neg_j_1 = -Fmax_neg; Fres_neg_j_1 = -Fy_neg*ResF_neg; - KrelA_pos_j_1 = Ke; - KrelA_neg_j_1 = Ke; - KrelB_pos_j_1 = Ke; - KrelB_neg_j_1 = Ke; - Kul_j_1 = Ke; Ures_pos_j_1 = (Fres_pos_j_1 - Fmax_pos_j_1) / Kpc_pos_j_1 + Umax_pos_j_1; Ures_neg_j_1 = (Fres_neg_j_1 - Fmax_neg_j_1) / Kpc_neg_j_1 + Umax_neg_j_1; - Ubp_pos_j_1 = 0; - Ubp_neg_j_1 = 0; - - Fbp_pos_j_1 = 0; - Fbp_neg_j_1 = 0; - - Energy_Acc = 0.0; - Energy_Diss = 0.0; + Energy_Acc = cEnergy_Acc = 0.0; + Energy_Diss = cEnergy_Diss = 0.0; - Umaxp = 0.0; - Umaxn = 0.0; + u0 = 0.0; EtS = LAMBDA_S *Fy_pos; EtC = LAMBDA_C *Fy_pos; EtA = LAMBDA_A *Fy_pos; EtK = LAMBDA_K *Fy_pos; - cPlastic_Offset_pos_j_1 = 0; - cPlastic_Offset_neg_j_1 = 0; + Failure_Flag = cFailure_Flag = 0; + Excursion_Flag = cExcursion_Flag = 0; + Unloading_Flag = cUnloading_Flag = 0; + Reloading_Flag = cReloading_Flag = 0; + TargetPeak_Flag = cTargetPeak_Flag = 0; + Yield_Flag = cYield_Flag = 0; + Reversal_Flag = cReversal_Flag = 0; + + ULastPeak_pos_j_1 = Uy_pos; + FLastPeak_pos_j_1 = Fy_pos; + ULastPeak_neg_j_1 = -Uy_neg; + FLastPeak_neg_j_1 = -Fy_neg; + + Krel_j_1 = Ke; + Upl = 0.0; + Ubp = 0.0; + Fbp = 0.0; + cdu_i_1 = 0; - cUpeak_pos_j_1 = Uy_pos; - cFpeak_pos_j_1 = Fy_pos; + cUpeak_pos_j_1 = Uy_pos; + cFpeak_pos_j_1 = Fy_pos; cUpeak_neg_j_1 = -Uy_neg; cFpeak_neg_j_1 = -Fy_neg; - cUy_pos_j_1 = Uy_pos; - cFy_pos_j_1 = Fy_pos; - cKp_pos_j_1 = Kp_pos; + cUy_pos_j_1 = Uy_pos; + cFy_pos_j_1 = Fy_pos; + cKp_pos_j_1 = Kp_pos; cKpc_pos_j_1 = -Kpc_pos; - cUy_neg_j_1 = -Uy_neg; - cFy_neg_j_1 = -Fy_neg; - cKp_neg_j_1 = Kp_neg; + cUy_neg_j_1 = -Uy_neg; + cFy_neg_j_1 = -Fy_neg; + cKp_neg_j_1 = Kp_neg; cKpc_neg_j_1 = -Kpc_neg; - cUmax_pos_j_1 = Umax_pos; - cFmax_pos_j_1 = Fmax_pos; - cFres_pos_j_1 = Fy_pos*ResF_pos; + cUmax_pos_j_1 = Umax_pos; + cFmax_pos_j_1 = Fmax_pos; + cFres_pos_j_1 = Fy_pos*ResF_pos; cUmax_neg_j_1 = -Umax_neg; cFmax_neg_j_1 = -Fmax_neg; cFres_neg_j_1 = -Fy_neg*ResF_neg; - cKrelA_pos_j_1 = Ke; - cKrelA_neg_j_1 = Ke; - cKrelB_pos_j_1 = Ke; - cKrelB_neg_j_1 = Ke; - cKul_j_1 = Ke; cUres_pos_j_1 = (Fres_pos_j_1 - Fmax_pos_j_1) / Kpc_pos_j_1 + Umax_pos_j_1; cUres_neg_j_1 = (Fres_neg_j_1 - Fmax_neg_j_1) / Kpc_neg_j_1 + Umax_neg_j_1; - cUbp_pos_j_1 = 0; - cUbp_neg_j_1 = 0; - - cFbp_pos_j_1 = 0; - cFbp_neg_j_1 = 0; - + cULastPeak_pos_j_1 = Uy_pos; + cFLastPeak_pos_j_1 = Fy_pos; + cULastPeak_neg_j_1 = -Uy_neg; + cFLastPeak_neg_j_1 = -Fy_neg; + + cKrel_j_1 = Ke; + + cUpl = 0.0; + cUbp = 0.0; + cFbp = 0.0; + //initially I zero everything U = cU = 0; - ui = 0; - fi = 0; - ui_1 = 0; - fi_1 = 0; - cui = 0; - cfi = 0; + ui = 0; + fi = 0; + ui_1 = 0; + fi_1 = 0; + cui = 0; + cfi = 0; cui_1 = 0; cfi_1 = 0; - TangentK = Ke; + TangentK = Ke; cTangentK = Ke; //cout << " revertToStart:" << endln; //<< " U=" << U << " Ri=" << Ri << " TanK=" << TangentK << endln; @@ -842,64 +996,63 @@ IMKPinching::getCopy(void) //cout << " getCopy" << endln; - - theCopy->U = U; + theCopy->U = U; theCopy->cU = cU; theCopy->TangentK = TangentK; - theCopy->ui = ui; - theCopy->fi = fi; - theCopy->ui_1 = ui_1; - theCopy->fi_1 = fi_1; + theCopy->ui = ui; + theCopy->fi = fi; + theCopy->ui_1 = ui_1; + theCopy->fi_1 = fi_1; theCopy->du_i_1 = du_i_1; - theCopy->Uy_pos_j_1 = Uy_pos_j_1; - theCopy->Umax_pos_j_1 = Umax_pos_j_1; - theCopy->Uu_pos_j_1 = Uu_pos_j_1; - theCopy->Fy_pos_j_1 = Fy_pos_j_1; - theCopy->Fmax_pos_j_1 = Fmax_pos_j_1; - theCopy->Upeak_pos_j_1 = Upeak_pos_j_1; - theCopy->Fpeak_pos_j_1 = Fpeak_pos_j_1; - theCopy->Ubp_pos_j_1 = Ubp_pos_j_1; - theCopy->Fbp_pos_j_1 = Fbp_pos_j_1; - theCopy->Ures_pos_j_1 = Ures_pos_j_1; - theCopy->Fres_pos_j_1 = Fres_pos_j_1; - theCopy->Kp_pos_j_1 = Kp_pos_j_1; - theCopy->Kpc_pos_j_1 = Kpc_pos_j_1; - theCopy->KrelA_pos_j_1 = KrelA_pos_j_1; - theCopy->KrelB_pos_j_1 = KrelB_pos_j_1; - theCopy->Plastic_Offset_pos_j_1 = Plastic_Offset_pos_j_1; - - theCopy->Uy_neg_j_1 = Uy_neg_j_1; - theCopy->Umax_neg_j_1 = Umax_neg_j_1; - theCopy->Uu_neg_j_1 = Uu_neg_j_1; - theCopy->Fy_neg_j_1 = Fy_neg_j_1; - theCopy->Fmax_neg_j_1 = Fmax_neg_j_1; - theCopy->Upeak_neg_j_1 = Upeak_neg_j_1; - theCopy->Fpeak_neg_j_1 = Fpeak_neg_j_1; - theCopy->Ubp_neg_j_1 = Ubp_neg_j_1; - theCopy->Fbp_neg_j_1 = Fbp_neg_j_1; - theCopy->Ures_neg_j_1 = Ures_neg_j_1; - theCopy->Fres_neg_j_1 = Fres_neg_j_1; - theCopy->Kp_neg_j_1 = Kp_neg_j_1; - theCopy->Kpc_neg_j_1 = Kpc_neg_j_1; - theCopy->KrelA_neg_j_1 = KrelA_neg_j_1; - theCopy->KrelB_neg_j_1 = KrelB_neg_j_1; - theCopy->Plastic_Offset_neg_j_1 = Plastic_Offset_neg_j_1; + theCopy->Uy_pos_j_1 = Uy_pos_j_1; + theCopy->Umax_pos_j_1 = Umax_pos_j_1; + theCopy->Fy_pos_j_1 = Fy_pos_j_1; + theCopy->Fmax_pos_j_1 = Fmax_pos_j_1; + theCopy->Upeak_pos_j_1 = Upeak_pos_j_1; + theCopy->Fpeak_pos_j_1 = Fpeak_pos_j_1; + theCopy->Ures_pos_j_1 = Ures_pos_j_1; + theCopy->Fres_pos_j_1 = Fres_pos_j_1; + theCopy->Kp_pos_j_1 = Kp_pos_j_1; + theCopy->Kpc_pos_j_1 = Kpc_pos_j_1; + + theCopy->Uy_neg_j_1 = Uy_neg_j_1; + theCopy->Umax_neg_j_1 = Umax_neg_j_1; + theCopy->Fy_neg_j_1 = Fy_neg_j_1; + theCopy->Fmax_neg_j_1 = Fmax_neg_j_1; + theCopy->Upeak_neg_j_1 = Upeak_neg_j_1; + theCopy->Fpeak_neg_j_1 = Fpeak_neg_j_1; + theCopy->Ures_neg_j_1 = Ures_neg_j_1; + theCopy->Fres_neg_j_1 = Fres_neg_j_1; + theCopy->Kp_neg_j_1 = Kp_neg_j_1; + theCopy->Kpc_neg_j_1 = Kpc_neg_j_1; theCopy->Kul_j_1 = Kul_j_1; - theCopy->Failure_Flag = Failure_Flag; - theCopy->Excursion_Flag = Excursion_Flag; - - theCopy->Energy_Acc = Energy_Acc; + theCopy->Energy_Acc = Energy_Acc; theCopy->Energy_Diss = Energy_Diss; - theCopy->Umaxp = Umaxp; - theCopy->Umaxn = Umaxn; + theCopy->u0 = u0; + theCopy->ULastPeak_pos_j_1 = ULastPeak_pos_j_1; + theCopy->FLastPeak_pos_j_1 = FLastPeak_pos_j_1; + theCopy->ULastPeak_neg_j_1 = ULastPeak_neg_j_1; + theCopy->FLastPeak_neg_j_1 = FLastPeak_neg_j_1; + theCopy->Failure_Flag = Failure_Flag; + theCopy->Excursion_Flag = Excursion_Flag; + theCopy->Reloading_Flag = Reloading_Flag; + theCopy->TargetPeak_Flag = TargetPeak_Flag; + theCopy->Yield_Flag = Yield_Flag; + theCopy->Reversal_Flag = Reversal_Flag; + + theCopy->Krel_j_1 = Krel_j_1; + + theCopy->Upl = Upl; + theCopy->Ubp = Ubp; + theCopy->Fbp = Fbp; theCopy->cTangentK = cTangentK; @@ -909,51 +1062,53 @@ IMKPinching::getCopy(void) theCopy->cfi_1 = cfi_1; theCopy->cdu_i_1 = cdu_i_1; - theCopy->cUy_pos_j_1 = cUy_pos_j_1; - theCopy->cUmax_pos_j_1 = cUmax_pos_j_1; - theCopy->cUu_pos_j_1 = cUu_pos_j_1; - theCopy->cFy_pos_j_1 = cFy_pos_j_1; - theCopy->cFmax_pos_j_1 = cFmax_pos_j_1; + theCopy->cUy_pos_j_1 = cUy_pos_j_1; + theCopy->cUmax_pos_j_1 = cUmax_pos_j_1; + theCopy->cFy_pos_j_1 = cFy_pos_j_1; + theCopy->cFmax_pos_j_1 = cFmax_pos_j_1; theCopy->cUpeak_pos_j_1 = cUpeak_pos_j_1; theCopy->cFpeak_pos_j_1 = cFpeak_pos_j_1; - theCopy->cUbp_pos_j_1 = cUbp_pos_j_1; - theCopy->cFbp_pos_j_1 = cFbp_pos_j_1; - theCopy->cUres_pos_j_1 = cUres_pos_j_1; - theCopy->cFres_pos_j_1 = cFres_pos_j_1; - theCopy->cKp_pos_j_1 = cKp_pos_j_1; - theCopy->cKpc_pos_j_1 = cKpc_pos_j_1; - theCopy->cKrelA_pos_j_1 = cKrelA_pos_j_1; - theCopy->cKrelB_pos_j_1 = cKrelB_pos_j_1; - theCopy->cPlastic_Offset_pos_j_1 = cPlastic_Offset_pos_j_1; - - theCopy->cUy_neg_j_1 = cUy_neg_j_1; - theCopy->cUmax_neg_j_1 = cUmax_neg_j_1; - theCopy->cUu_neg_j_1 = cUu_neg_j_1; - theCopy->cFy_neg_j_1 = cFy_neg_j_1; - theCopy->cFmax_neg_j_1 = cFmax_neg_j_1; + theCopy->cUres_pos_j_1 = cUres_pos_j_1; + theCopy->cFres_pos_j_1 = cFres_pos_j_1; + theCopy->cKp_pos_j_1 = cKp_pos_j_1; + theCopy->cKpc_pos_j_1 = cKpc_pos_j_1; + + theCopy->cUy_neg_j_1 = cUy_neg_j_1; + theCopy->cUmax_neg_j_1 = cUmax_neg_j_1; + theCopy->cFy_neg_j_1 = cFy_neg_j_1; + theCopy->cFmax_neg_j_1 = cFmax_neg_j_1; theCopy->cUpeak_neg_j_1 = cUpeak_neg_j_1; theCopy->cFpeak_neg_j_1 = cFpeak_neg_j_1; - theCopy->cUbp_neg_j_1 = cUbp_neg_j_1; - theCopy->cFbp_neg_j_1 = cFbp_neg_j_1; - theCopy->cUres_neg_j_1 = cUres_neg_j_1; - theCopy->cFres_neg_j_1 = cFres_neg_j_1; - theCopy->cKp_neg_j_1 = cKp_neg_j_1; - theCopy->cKpc_neg_j_1 = cKpc_neg_j_1; - theCopy->cKrelA_neg_j_1 = cKrelA_neg_j_1; - theCopy->cKrelB_neg_j_1 = cKrelB_neg_j_1; - theCopy->cPlastic_Offset_neg_j_1 = cPlastic_Offset_neg_j_1; + theCopy->cUres_neg_j_1 = cUres_neg_j_1; + theCopy->cFres_neg_j_1 = cFres_neg_j_1; + theCopy->cKp_neg_j_1 = cKp_neg_j_1; + theCopy->cKpc_neg_j_1 = cKpc_neg_j_1; theCopy->cKul_j_1 = cKul_j_1; - theCopy->cFailure_Flag = cFailure_Flag; - theCopy->cExcursion_Flag = cExcursion_Flag; - - theCopy->cEnergy_Acc = cEnergy_Acc; + theCopy->cEnergy_Acc = cEnergy_Acc; theCopy->cEnergy_Diss = cEnergy_Diss; - theCopy->cUmaxp = cUmaxp; - theCopy->cUmaxn = cUmaxn; - + theCopy->cu0 = cu0; + + theCopy->cULastPeak_pos_j_1 = cULastPeak_pos_j_1; + theCopy->cFLastPeak_pos_j_1 = cFLastPeak_pos_j_1; + theCopy->cULastPeak_neg_j_1 = cULastPeak_neg_j_1; + theCopy->cFLastPeak_neg_j_1 = cFLastPeak_neg_j_1; + + theCopy->cFailure_Flag = cFailure_Flag; + theCopy->cExcursion_Flag = cExcursion_Flag; + theCopy->cReloading_Flag = cReloading_Flag; + theCopy->cTargetPeak_Flag = cTargetPeak_Flag; + theCopy->cYield_Flag = cYield_Flag; + theCopy->cReversal_Flag = cReversal_Flag; + + theCopy->cKrel_j_1 = cKrel_j_1; + + theCopy->cUpl = cUpl; + theCopy->cUbp = cUbp; + theCopy->cFbp = cFbp; + return theCopy; } @@ -962,175 +1117,151 @@ int IMKPinching::sendSelf(int cTag, Channel &theChannel) int res = 0; cout << " sendSelf" << endln; - static Vector data(149); + static Vector data(144); data(0) = this->getTag(); - data(1) = Ke; - data(2) = Uy_pos; - data(3) = Umax_pos; - data(4) = Uu_pos; - data(5) = Fy_pos; - data(6) = FmaxFy_pos; - data(7) = ResF_pos; - data(8) = Uy_neg; - data(9) = Umax_neg; - data(10) = Uu_neg; - data(11) = Fy_neg; - data(12) = FmaxFy_neg; - data(13) = ResF_neg; - data(14) = LAMBDA_S; - data(15) = LAMBDA_C; - data(16) = LAMBDA_A; - data(17) = LAMBDA_K; - data(18) = c_S; - data(19) = c_C; - data(20) = c_A; - data(21) = c_K; - data(22) = D_pos; - data(23) = D_neg; + data(1) = Ke; + data(2) = Uy_pos; + data(3) = Umax_pos; + data(4) = Uu_pos; + data(5) = Fy_pos; + data(6) = FmaxFy_pos; + data(7) = ResF_pos; + data(8) = Uy_neg; + data(9) = Umax_neg; + data(10) = Uu_neg; + data(11) = Fy_neg; + data(12) = FmaxFy_neg; + data(13) = ResF_neg; + data(14) = LAMBDA_S; + data(15) = LAMBDA_C; + data(16) = LAMBDA_A; + data(17) = LAMBDA_K; + data(18) = c_S; + data(19) = c_C; + data(20) = c_A; + data(21) = c_K; + data(22) = D_pos; + data(23) = D_neg; data(24) = kappaF; data(25) = kappaD; - - data(26) = ui; - data(27) = fi; - data(28) = ui_1; - data(29) = fi_1; - data(30) = du_i_1; - - data(31) = Uy_pos_j_1; - data(32) = Umax_pos_j_1; - data(33) = Uu_pos_j_1; - data(34) = Fy_pos_j_1; - data(35) = Fmax_pos_j_1; - data(36) = Upeak_pos_j_1; - data(37) = Fpeak_pos_j_1; - data(38) = Ubp_pos_j_1; - data(39) = Fbp_pos_j_1; - data(40) = Ures_pos_j_1; - data(41) = Fres_pos_j_1; - data(42) = Kp_pos_j_1; - data(43) = Kpc_pos_j_1; - data(44) = KrelA_pos_j_1; - data(45) = KrelB_pos_j_1; - data(46) = Plastic_Offset_pos_j_1; - - data(47) = Uy_neg_j_1; - data(48) = Umax_neg_j_1; - data(49) = Uu_neg_j_1; - data(50) = Fy_neg_j_1; - data(51) = Fmax_neg_j_1; - data(52) = Upeak_neg_j_1; - data(53) = Fpeak_neg_j_1; - data(54) = Ubp_neg_j_1; - data(55) = Fbp_neg_j_1; - data(56) = Ures_neg_j_1; - data(57) = Fres_neg_j_1; - data(58) = Kp_neg_j_1; - data(59) = Kpc_neg_j_1; - data(60) = KrelA_neg_j_1; - data(61) = KrelB_neg_j_1; - data(62) = Plastic_Offset_neg_j_1; - - data(63) = Kul_j_1; - data(64) = Failure_Flag; - data(65) = Excursion_Flag; - - data(66) = Energy_Acc; - data(67) = Energy_Diss; - data(68) = Umaxp; - data(69) = Umaxn; - - data(70) = u0; - data(71) = du; - data(72) = df; - - data(73) = Unloading_Flag; - data(74) = New_Peak_Pos_Flag; - data(75) = New_Peak_Neg_Flag; - - data(76) = Fp; - - data(77) = FailS; - data(78) = FailC; - data(79) = FailA; - data(80) = FailK; - - data(81) = Ei; - data(82) = dEi; - data(83) = Epj; - data(84) = EpjK; - data(85) = EiK; - - data(86) = c_S; - data(87) = c_C; - data(88) = c_A; - data(89) = c_K; - data(90) = EtS; - data(91) = EtC; - data(92) = EtA; - data(93) = EtK; - data(94) = betaS; - data(95) = betaC; - data(96) = betaA; - data(97) = betaK; - data(98) = sPCsp; - data(99) = sPCpcp; - - data(100) = TangentK; - - data(101) = Uy_pos; - data(102) = Umax_pos; - data(103) = Fmax_pos; - data(104) = Kp_pos; - data(105) = Kpc_pos; - - data(106) = Uy_neg; - data(107) = Umax_neg; - data(108) = Fmax_neg; - data(109) = Kp_neg; - data(110) = Kpc_neg; - - data(111) = cui; - data(112) = cfi; - data(113) = cui_1; - data(114) = cfi_1; - data(115) = cdu_i_1; - - data(116) = cUy_pos_j_1; - data(117) = cUmax_pos_j_1; - data(118) = cUu_pos_j_1; - data(119) = cFy_pos_j_1; - data(120) = cFmax_pos_j_1; - data(121) = cUpeak_pos_j_1; - data(122) = cFpeak_pos_j_1; - data(123) = cUbp_pos_j_1; - data(124) = cFbp_pos_j_1; - data(125) = cUres_pos_j_1; - data(126) = cFres_pos_j_1; - data(127) = cKp_pos_j_1; - data(128) = cKpc_pos_j_1; - data(129) = cKrelA_pos_j_1; - data(130) = cKrelB_pos_j_1; - data(131) = cPlastic_Offset_pos_j_1; - - data(132) = cUy_neg_j_1; - data(133) = cUmax_neg_j_1; - data(134) = cUu_neg_j_1; - data(135) = cFy_neg_j_1; - data(136) = cFmax_neg_j_1; - data(137) = cUpeak_neg_j_1; - data(138) = cFpeak_neg_j_1; - data(139) = cUbp_neg_j_1; - data(140) = cFbp_neg_j_1; - data(141) = cUres_neg_j_1; - data(142) = cFres_neg_j_1; - data(143) = cKp_neg_j_1; - data(144) = cKpc_neg_j_1; - data(145) = cKrelA_neg_j_1; - data(146) = cKrelB_neg_j_1; - data(147) = cPlastic_Offset_neg_j_1; - - data(148) = cKul_j_1; - + data(26) = ui; + data(27) = fi; + data(28) = ui_1; + data(29) = fi_1; + data(30) = du_i_1; + data(31) = Uy_pos_j_1; + data(32) = Umax_pos_j_1; + data(33) = Fy_pos_j_1; + data(34) = Fmax_pos_j_1; + data(35) = Upeak_pos_j_1; + data(36) = Fpeak_pos_j_1; + data(37) = Ures_pos_j_1; + data(38) = Fres_pos_j_1; + data(39) = Kp_pos_j_1; + data(40) = Kpc_pos_j_1; + data(41) = Uy_neg_j_1; + data(42) = Umax_neg_j_1; + data(43) = Fy_neg_j_1; + data(44) = Fmax_neg_j_1; + data(45) = Upeak_neg_j_1; + data(46) = Fpeak_neg_j_1; + data(47) = Ures_neg_j_1; + data(48) = Fres_neg_j_1; + data(49) = Kp_neg_j_1; + data(50) = Kpc_neg_j_1; + data(51) = Kul_j_1; + data(52) = Failure_Flag; + data(53) = Excursion_Flag; + data(54) = Unloading_Flag; + data(55) = Reloading_Flag; + data(56) = TargetPeak_Flag; + data(57) = Yield_Flag; + data(58) = Energy_Acc; + data(59) = Energy_Diss; + data(60) = u0; + data(61) = du; + data(62) = df; + data(63) = FailS; + data(64) = FailC; + data(65) = FailA; + data(66) = FailK; + data(67) = Ei; + data(68) = dEi; + data(69) = Epj; + data(70) = EpjK; + data(71) = EiK; + data(72) = c_S; + data(73) = c_C; + data(74) = c_A; + data(75) = c_K; + data(76) = EtS; + data(77) = EtC; + data(78) = EtA; + data(79) = EtK; + data(80) = betaS; + data(81) = betaC; + data(82) = betaA; + data(83) = betaK; + data(84) = sPCsp; + data(85) = sPCpcp; + data(86) = TangentK; + data(87) = Uy_pos; + data(88) = Umax_pos; + data(89) = Fmax_pos; + data(90) = Kp_pos; + data(91) = Kpc_pos; + data(92) = Uy_neg; + data(93) = Umax_neg; + data(94) = Fmax_neg; + data(95) = Kp_neg; + data(96) = Kpc_neg; + data(97) = cui; + data(98) = cfi; + data(99) = cui_1; + data(100) = cfi_1; + data(101) = cdu_i_1; + data(102) = cUy_pos_j_1; + data(103) = cUmax_pos_j_1; + data(104) = cFy_pos_j_1; + data(105) = cFmax_pos_j_1; + data(106) = cUpeak_pos_j_1; + data(107) = cFpeak_pos_j_1; + data(108) = cUres_pos_j_1; + data(109) = cFres_pos_j_1; + data(110) = cKp_pos_j_1; + data(111) = cKpc_pos_j_1; + data(112) = cUy_neg_j_1; + data(113) = cUmax_neg_j_1; + data(114) = cFy_neg_j_1; + data(115) = cFmax_neg_j_1; + data(116) = cUpeak_neg_j_1; + data(117) = cFpeak_neg_j_1; + data(118) = cUres_neg_j_1; + data(119) = cFres_neg_j_1; + data(120) = cKp_neg_j_1; + data(121) = cKpc_neg_j_1; + data(122) = cKul_j_1; + data(123) = cULastPeak_pos_j_1; + data(124) = cFLastPeak_pos_j_1; + data(125) = cULastPeak_neg_j_1; + data(126) = cFLastPeak_neg_j_1; + data(127) = cFailure_Flag; + data(128) = cExcursion_Flag; + data(129) = cReloading_Flag; + data(130) = cUnloading_Flag; + data(131) = cTargetPeak_Flag; + data(132) = cYield_Flag; + data(133) = cKrel_j_1; + data(134) = Krel_LastPeak; + data(135) = Krel_GlobalPeak; + data(136) = K_check; + data(137) = Upl; + data(138) = Ubp; + data(139) = Fbp; + data(140) = cUbp; + data(141) = cFbp; + data(142) = Reversal_Flag; + data(143) = cReversal_Flag; res = theChannel.sendVector(this->getDbTag(), cTag, data); if (res < 0) @@ -1142,7 +1273,7 @@ int IMKPinching::sendSelf(int cTag, Channel &theChannel) int IMKPinching::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker) { int res = 0; - static Vector data(149); + static Vector data(144); res = theChannel.recvVector(this->getDbTag(), cTag, data); if (res < 0) { @@ -1152,173 +1283,149 @@ int IMKPinching::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBr else { cout << " recvSelf" << endln; this->setTag((int)data(0)); - Ke = data(1); - Up_pos = data(2); - Upc_pos = data(3); - Uu_pos = data(4); - Fy_pos = data(5); - FmaxFy_pos = data(6); - ResF_pos = data(7); - Up_neg = data(8); - Upc_neg = data(9); - Uu_neg = data(10); - Fy_neg = data(11); - FmaxFy_neg = data(12); - ResF_neg = data(13); - LAMBDA_S = data(14); - LAMBDA_C = data(15); - LAMBDA_A = data(16); - LAMBDA_K = data(17); - c_S = data(18); - c_C = data(19); - c_A = data(20); - c_K = data(21); - D_pos = data(22); - D_neg = data(23); - kappaF = data(24); - kappaD = data(25); - - ui = data(26); - fi = data(27); - ui_1 = data(28); - fi_1 = data(29); - du_i_1 = data(30); - - Uy_pos_j_1 = data(31); - Umax_pos_j_1 = data(32); - Uu_pos_j_1 = data(33); - Fy_pos_j_1 = data(34); - Fmax_pos_j_1 = data(35); - Upeak_pos_j_1 = data(36); - Fpeak_pos_j_1 = data(37); - Ubp_pos_j_1 = data(38); - Fbp_pos_j_1 = data(39); - Ures_pos_j_1 = data(40); - Fres_pos_j_1 = data(41); - Kp_pos_j_1 = data(42); - Kpc_pos_j_1 = data(43); - KrelA_pos_j_1 = data(44); - KrelB_pos_j_1 = data(45); - Plastic_Offset_pos_j_1 = data(46); - - Uy_neg_j_1 = data(47); - Umax_neg_j_1 = data(48); - Uu_neg_j_1 = data(49); - Fy_neg_j_1 = data(50); - Fmax_neg_j_1 = data(51); - Upeak_neg_j_1 = data(52); - Fpeak_neg_j_1 = data(53); - Ubp_neg_j_1 = data(54); - Fbp_neg_j_1 = data(55); - Ures_neg_j_1 = data(56); - Fres_neg_j_1 = data(57); - Kp_neg_j_1 = data(58); - Kpc_neg_j_1 = data(59); - KrelA_neg_j_1 = data(60); - KrelB_neg_j_1 = data(61); - Plastic_Offset_neg_j_1 = data(62); - - Kul_j_1 = data(63); - - Failure_Flag = data(64); - Excursion_Flag = data(65); - - Energy_Acc = data(66); - Energy_Diss = data(67); - Umaxp = data(68); - Umaxn = data(69); - - u0 = data(70); - du = data(71); - df = data(72); - - Unloading_Flag = data(73); - New_Peak_Pos_Flag = data(74); - New_Peak_Neg_Flag = data(75); - - Fp = data(76); - - FailS = data(77); - FailC = data(78); - FailA = data(79); - FailK = data(80); - - Ei = data(81); - dEi = data(82); - Epj = data(83); - EpjK = data(84); - EiK = data(85); - - c_S = data(86); - c_C = data(87); - c_A = data(88); - c_K = data(89); - EtS = data(90); - EtC = data(91); - EtA = data(92); - EtK = data(93); - betaS = data(94); - betaC = data(95); - betaA = data(96); - betaK = data(97); - sPCsp = data(98); - sPCpcp = data(99); - - TangentK = data(100); - - Uy_pos = data(101); - Umax_pos = data(102); - Fmax_pos = data(103); - Kp_pos = data(104); - Kpc_pos = data(105); - - Uy_neg = data(106); - Umax_neg = data(107); - Fmax_neg = data(108); - Kp_neg = data(109); - Kpc_neg = data(110); - - cui = data(111); - cfi = data(112); - cui_1 = data(113); - cfi_1 = data(114); - cdu_i_1 = data(115); - - cUy_pos_j_1 = data(116); - cUmax_pos_j_1 = data(117); - cUu_pos_j_1 = data(118); - cFy_pos_j_1 = data(119); - cFmax_pos_j_1 = data(120); - cUpeak_pos_j_1 = data(121); - cFpeak_pos_j_1 = data(122); - cUbp_pos_j_1 = data(123); - cFbp_pos_j_1 = data(124); - cUres_pos_j_1 = data(125); - cFres_pos_j_1 = data(126); - cKp_pos_j_1 = data(127); - cKpc_pos_j_1 = data(128); - cKrelA_pos_j_1 = data(129); - cKrelB_pos_j_1 = data(130); - cPlastic_Offset_pos_j_1 = data(131); - - cUy_neg_j_1 = data(132); - cUmax_neg_j_1 = data(133); - cUu_neg_j_1 = data(134); - cFy_neg_j_1 = data(135); - cFmax_neg_j_1 = data(136); - cUpeak_neg_j_1 = data(137); - cFpeak_neg_j_1 = data(138); - cUbp_neg_j_1 = data(139); - cFbp_neg_j_1 = data(140); - cUres_neg_j_1 = data(141); - cFres_neg_j_1 = data(142); - cKp_neg_j_1 = data(143); - cKpc_neg_j_1 = data(144); - cKrelA_neg_j_1 = data(145); - cKrelB_neg_j_1 = data(146); - cPlastic_Offset_neg_j_1 = data(147); - - cKul_j_1 = data(148); + Ke = data(1); + Up_pos = data(2); + Upc_pos = data(3); + Uu_pos = data(4); + Fy_pos = data(5); + FmaxFy_pos = data(6); + ResF_pos = data(7); + Up_neg = data(8); + Upc_neg = data(9); + Uu_neg = data(10); + Fy_neg = data(11); + FmaxFy_neg = data(12); + ResF_neg = data(13); + LAMBDA_S = data(14); + LAMBDA_C = data(15); + LAMBDA_A = data(16); + LAMBDA_K = data(17); + c_S = data(18); + c_C = data(19); + c_A = data(20); + c_K = data(21); + D_pos = data(22); + D_neg = data(23); + kappaF = data(24); + kappaD = data(25); + ui = data(26); + fi = data(27); + ui_1 = data(28); + fi_1 = data(29); + du_i_1 = data(30); + Uy_pos_j_1 = data(31); + Umax_pos_j_1 = data(32); + Fy_pos_j_1 = data(33); + Fmax_pos_j_1 = data(34); + Upeak_pos_j_1 = data(35); + Fpeak_pos_j_1 = data(36); + Ures_pos_j_1 = data(37); + Fres_pos_j_1 = data(38); + Kp_pos_j_1 = data(39); + Kpc_pos_j_1 = data(40); + Uy_neg_j_1 = data(41); + Umax_neg_j_1 = data(42); + Fy_neg_j_1 = data(43); + Fmax_neg_j_1 = data(44); + Upeak_neg_j_1 = data(45); + Fpeak_neg_j_1 = data(46); + Ures_neg_j_1 = data(47); + Fres_neg_j_1 = data(48); + Kp_neg_j_1 = data(49); + Kpc_neg_j_1 = data(50); + Failure_Flag = data(51); + Excursion_Flag = data(52); + Reloading_Flag = data(53); + Unloading_Flag = data(54); + TargetPeak_Flag = data(55); + Yield_Flag = data(56); + Kul_j_1 = data(57); + Energy_Acc = data(58); + Energy_Diss = data(59); + u0 = data(60); + du = data(61); + df = data(62); + FailS = data(63); + FailC = data(64); + FailA = data(65); + FailK = data(66); + Ei = data(67); + dEi = data(68); + Epj = data(79); + EpjK = data(70); + EiK = data(71); + c_S = data(72); + c_C = data(73); + c_A = data(74); + c_K = data(75); + EtS = data(76); + EtC = data(77); + EtA = data(78); + EtK = data(79); + betaS = data(80); + betaC = data(81); + betaA = data(82); + betaK = data(83); + sPCsp = data(84); + sPCpcp = data(85); + TangentK = data(86); + Uy_pos = data(87); + Umax_pos = data(88); + Fmax_pos = data(89); + Kp_pos = data(90); + Kpc_pos = data(91); + Uy_neg = data(92); + Umax_neg = data(93); + Fmax_neg = data(94); + Kp_neg = data(95); + Kpc_neg = data(96); + cui = data(97); + cfi = data(98); + cui_1 = data(99); + cfi_1 = data(100); + cdu_i_1 = data(101); + cUy_pos_j_1 = data(102); + cUmax_pos_j_1 = data(103); + cFy_pos_j_1 = data(104); + cFmax_pos_j_1 = data(105); + cUpeak_pos_j_1 = data(106); + cFpeak_pos_j_1 = data(107); + cUres_pos_j_1 = data(108); + cFres_pos_j_1 = data(109); + cKp_pos_j_1 = data(110); + cKpc_pos_j_1 = data(111); + cUy_neg_j_1 = data(112); + cUmax_neg_j_1 = data(113); + cFy_neg_j_1 = data(114); + cFmax_neg_j_1 = data(115); + cUpeak_neg_j_1 = data(116); + cFpeak_neg_j_1 = data(117); + cUres_neg_j_1 = data(118); + cFres_neg_j_1 = data(119); + cKp_neg_j_1 = data(120); + cKpc_neg_j_1 = data(121); + cKul_j_1 = data(122); + cULastPeak_pos_j_1 = data(123); + cFLastPeak_pos_j_1 = data(124); + cULastPeak_neg_j_1 = data(125); + cFLastPeak_neg_j_1 = data(126); + cFailure_Flag = data(127); + cExcursion_Flag = data(128); + cReloading_Flag = data(129); + cUnloading_Flag = data(130); + cTargetPeak_Flag = data(131); + cYield_Flag = data(132); + cKrel_j_1 = data(133); + Krel_LastPeak = data(134); + Krel_GlobalPeak = data(135); + K_check = data(136); + Upl = data(137); + Ubp = data(138); + Fbp = data(139); + cUbp = data(140); + cFbp = data(141); + cReversal_Flag = data(142); + Reversal_Flag = data(143); } return res; @@ -1327,5 +1434,4 @@ int IMKPinching::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBr void IMKPinching::Print(OPS_Stream &s, int flag) { cout << "IMKPinching tag: " << this->getTag() << endln; -} - +} \ No newline at end of file diff --git a/SRC/material/uniaxial/IMKPinching.h b/SRC/material/uniaxial/IMKPinching.h index 2c1988bb66..7d27eee4a5 100644 --- a/SRC/material/uniaxial/IMKPinching.h +++ b/SRC/material/uniaxial/IMKPinching.h @@ -18,12 +18,11 @@ ** ** ** ****************************************************************** */ -//Modified Ibarra-Medina-Krawinkler with Pinched Hysteretic Response +//Modified Ibarra-Medina-Krawinkler with Peak-Oriented Hysteretic Response //********************************************************************** // Code Developed by: Ahmed Elkady and Hammad ElJisr -// Postdoctoral Researcher, EPFL, Switzerland -// Last Updated: July 2018 +// Last Updated: July 2020 //********************************************************************** #ifndef IMKPinching_h @@ -100,68 +99,44 @@ class IMKPinching : public UniaxialMaterial double Uy_pos_j_1, cUy_pos_j_1; double Umax_pos_j_1, cUmax_pos_j_1; - double Uu_pos_j_1, cUu_pos_j_1; double Fy_pos_j_1, cFy_pos_j_1; double Fmax_pos_j_1, cFmax_pos_j_1; double Upeak_pos_j_1, cUpeak_pos_j_1; double Fpeak_pos_j_1, cFpeak_pos_j_1; - double Ubp_pos_j_1, cUbp_pos_j_1; - double Fbp_pos_j_1, cFbp_pos_j_1; double Ures_pos_j_1, cUres_pos_j_1; double Fres_pos_j_1, cFres_pos_j_1; double Kp_pos_j_1, cKp_pos_j_1; double Kpc_pos_j_1, cKpc_pos_j_1; - double KrelA_pos_j_1, cKrelA_pos_j_1; - double KrelB_pos_j_1, cKrelB_pos_j_1; - double Plastic_Offset_pos_j_1, cPlastic_Offset_pos_j_1; double Uy_neg_j_1, cUy_neg_j_1; double Umax_neg_j_1, cUmax_neg_j_1; - double Uu_neg_j_1, cUu_neg_j_1; double Fy_neg_j_1, cFy_neg_j_1; double Fmax_neg_j_1, cFmax_neg_j_1; double Upeak_neg_j_1, cUpeak_neg_j_1; double Fpeak_neg_j_1, cFpeak_neg_j_1; - double Ubp_neg_j_1, cUbp_neg_j_1; - double Fbp_neg_j_1, cFbp_neg_j_1; + double Ures_neg_j_1, cUres_neg_j_1; double Fres_neg_j_1, cFres_neg_j_1; double Kp_neg_j_1, cKp_neg_j_1; double Kpc_neg_j_1, cKpc_neg_j_1; - double KrelA_neg_j_1, cKrelA_neg_j_1; - double KrelB_neg_j_1, cKrelB_neg_j_1; - double Plastic_Offset_neg_j_1, cPlastic_Offset_neg_j_1; - double Kul_j_1, cKul_j_1; - - double Failure_Flag, cFailure_Flag; - double Excursion_Flag, cExcursion_Flag; - + double Energy_Acc, cEnergy_Acc; double Energy_Diss, cEnergy_Diss; - double Umaxp, cUmaxp; - double Umaxn, cUmaxn; - - - double u0; + double u0, cu0; + double du; double df; - double Unloading_Flag; - double New_Peak_Pos_Flag; - double New_Peak_Neg_Flag; - - double Fp; - double FailS; double FailC; double FailA; double FailK; - double Ei; + double Ei, cEi; double dEi; double Epj; double EpjK; @@ -187,11 +162,34 @@ class IMKPinching : public UniaxialMaterial double TangentK, cTangentK, ki; - double Uy_pos, Uy_neg; - double Umax_pos, Umax_neg; - double Fmax_pos, Fmax_neg; - double Kpc_pos, Kpc_neg; - double Kp_pos, Kp_neg; + double Uy_pos, Uy_neg; + double Umax_pos, Umax_neg; + double Fmax_pos, Fmax_neg; + double Kpc_pos, Kpc_neg; + double Kp_pos, Kp_neg; + + double ULastPeak_pos_j_1, cULastPeak_pos_j_1; + double FLastPeak_pos_j_1, cFLastPeak_pos_j_1; + double ULastPeak_neg_j_1, cULastPeak_neg_j_1; + double FLastPeak_neg_j_1, cFLastPeak_neg_j_1; + + double Failure_Flag, cFailure_Flag; + double Excursion_Flag, cExcursion_Flag; + double Reloading_Flag, cReloading_Flag; + double TargetPeak_Flag, cTargetPeak_Flag; + double Unloading_Flag, cUnloading_Flag; + double Yield_Flag, cYield_Flag; + double Reversal_Flag, cReversal_Flag; + + double Krel_j_1, cKrel_j_1; + + double Krel_LastPeak; + double Krel_GlobalPeak; + double K_check; + + double Upl, cUpl; + double Ubp, cUbp; + double Fbp, cFbp; }; diff --git a/SRC/material/uniaxial/Makefile b/SRC/material/uniaxial/Makefile index 1dad3831c7..ed3a22fa41 100644 --- a/SRC/material/uniaxial/Makefile +++ b/SRC/material/uniaxial/Makefile @@ -10,6 +10,7 @@ OBJS = UniaxialMaterial.o \ IMKBilin.o \ IMKPeakOriented.o \ IMKPinching.o \ + SLModel.o \ Steel2.o \ OriginCentered.o \ ConcretewBeta.o \ @@ -34,6 +35,7 @@ OBJS = UniaxialMaterial.o \ Cast.o \ HardeningMaterial.o \ HardeningMaterial2.o \ + ASD_SMA_3K.o \ Concrete01.o \ Concrete02Thermal.o \ Steel02Thermal.o \ @@ -84,6 +86,7 @@ OBJS = UniaxialMaterial.o \ TclNewUnixialMaterial.o \ ReinforcingSteel.o \ PenaltyMaterial.o \ + MultiplierMaterial.o \ ContinuumUniaxial.o \ WrappedMaterial.o \ SecantMaterial.o \ @@ -129,6 +132,7 @@ OBJS = UniaxialMaterial.o \ TDConcreteEXP.o \ TDConcreteMC10.o \ TDConcreteMC10NL.o \ + PlateBearingConnectionThermal.o \ DegradingPinchedBW.o \ TclModelBuilderUniaxialMaterialCommand.o diff --git a/SRC/material/uniaxial/MinMaxMaterial.cpp b/SRC/material/uniaxial/MinMaxMaterial.cpp index edcffd6c32..7934e546f2 100644 --- a/SRC/material/uniaxial/MinMaxMaterial.cpp +++ b/SRC/material/uniaxial/MinMaxMaterial.cpp @@ -368,7 +368,7 @@ MinMaxMaterial::setParameter(const char **argv, int argc, Parameter ¶m) { // // I suppose epsMin and epsMax could be parameters, but not for now -- MHS - // + // return theMaterial->setParameter(argv, argc, param); } @@ -377,3 +377,46 @@ MinMaxMaterial::updateParameter(int parameterID, Information &info) { return 0; } + +double +MinMaxMaterial::getStressSensitivity(int gradIndex, bool conditional) +{ + if (Cfailed) + return 0.0; + else + return theMaterial->getStressSensitivity(gradIndex, conditional); +} + +double +MinMaxMaterial::getStrainSensitivity(int gradIndex) +{ + return theMaterial->getStrainSensitivity(gradIndex); +} + +double +MinMaxMaterial::getInitialTangentSensitivity(int gradIndex) +{ + return theMaterial->getInitialTangentSensitivity(gradIndex); +} + +double +MinMaxMaterial::getDampTangentSensitivity(int gradIndex) +{ + return theMaterial->getDampTangentSensitivity(gradIndex); +} + +double +MinMaxMaterial::getRhoSensitivity(int gradIndex) +{ + return theMaterial->getRhoSensitivity(gradIndex); +} + +int +MinMaxMaterial::commitSensitivity(double strainGradient, + int gradIndex, int numGrads) +{ + if (Cfailed) + return 0; + else + return theMaterial->commitSensitivity(strainGradient, gradIndex, numGrads); +} diff --git a/SRC/material/uniaxial/MinMaxMaterial.h b/SRC/material/uniaxial/MinMaxMaterial.h index 622956e009..3d2b5d75f6 100644 --- a/SRC/material/uniaxial/MinMaxMaterial.h +++ b/SRC/material/uniaxial/MinMaxMaterial.h @@ -67,6 +67,15 @@ class MinMaxMaterial : public UniaxialMaterial int setParameter(const char **argv, int argc, Parameter ¶m); int updateParameter(int parameterID, Information &info); + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + double getStressSensitivity (int gradIndex, bool conditional); + double getStrainSensitivity (int gradIndex); + double getInitialTangentSensitivity(int gradIndex); + double getDampTangentSensitivity(int gradIndex); + double getRhoSensitivity (int gradIndex); + int commitSensitivity (double strainGradient, int gradIndex, int numGrads); + // AddingSensitivity:END /////////////////////////////////////////// protected: diff --git a/SRC/material/uniaxial/MultiLinear.cpp b/SRC/material/uniaxial/MultiLinear.cpp index 87c53724f8..31683a79f6 100644 --- a/SRC/material/uniaxial/MultiLinear.cpp +++ b/SRC/material/uniaxial/MultiLinear.cpp @@ -17,7 +17,7 @@ ** Filip C. Filippou (filippou@ce.berkeley.edu) ** ** ** ** ****************************************************************** */ - + // Written: fmk // Created: 05/12 // Revision: A @@ -38,342 +38,342 @@ #include -void * +void* OPS_MultiLinear(void) { - // Pointer to a uniaxial material that will be returned - UniaxialMaterial *theMaterial = 0; - - if (OPS_GetNumRemainingInputArgs() < 5) { - opserr << "Invalid #args, want: uniaxialMaterial MultiLinear tag? e1 s1 e2 s2 ... " << endln; - return 0; - } + // Pointer to a uniaxial material that will be returned + UniaxialMaterial* theMaterial = 0; - int iData[1]; - int numData = 1; - if (OPS_GetIntInput(&numData, iData) != 0) { - opserr << "WARNING invalid tag or soilType uniaxialMaterial MultiLinearMaterial" << endln; - return 0; - } - - numData = OPS_GetNumRemainingInputArgs(); - - int numSlope = numData/2; - double *dData = new double[numData]; - if (OPS_GetDoubleInput(&numData, dData) != 0) { - opserr << "Invalid pyData data for material uniaxial MultiLinear " << iData[0] << endln; - return 0; - } - - Vector e(numSlope); - Vector s(numSlope); - for (int i=0; i= data(0,0) && tStrain <= data(0,1)) { // elastic + if (fabs(tStrain - strain) < DBL_EPSILON) + return 0; + + tStrain = strain; tSlope = 0; - tStress = data(0,2) + (tStrain-data(0,0))*data(0,4); - tTangent = data(0,4); - } else if (tStrain < data(0,0)) { // search neg of data - tSlope = 1; - while (tSlope < numSlope && tStrain < data(tSlope,0)) - tSlope++; - if (tSlope == numSlope) - tSlope = numSlope-1; - tStress = data(tSlope,2) + (tStrain-data(tSlope,0))*data(tSlope,4); - tTangent = data(tSlope,4); - } else { // search pos side of data - tSlope = 1; - while (tSlope < numSlope && tStrain > data(tSlope,1)) - tSlope++; - if (tSlope == numSlope) - tSlope = numSlope-1; - tStress = data(tSlope,3) + (tStrain-data(tSlope,1))*data(tSlope,4); - tTangent = data(tSlope,4); - } - - return 0; -} -double + if (tStrain >= data(0, 0) && tStrain <= data(0, 1)) { // elastic + tSlope = 0; + tStress = data(0, 2) + (tStrain - data(0, 0)) * data(0, 4); + tTangent = data(0, 4); + } + else if (tStrain < data(0, 0)) { // search neg of data + tSlope = 1; + while (tSlope < numSlope && tStrain < data(tSlope, 0)) + tSlope++; + if (tSlope == numSlope) + tSlope = numSlope - 1; + tStress = data(tSlope, 2) + (tStrain - data(tSlope, 0)) * data(tSlope, 4); + tTangent = data(tSlope, 4); + } + else { // search pos side of data + tSlope = 1; + while (tSlope < numSlope && tStrain > data(tSlope, 1)) + tSlope++; + if (tSlope == numSlope) + tSlope = numSlope - 1; + tStress = data(tSlope, 3) + (tStrain - data(tSlope, 1)) * data(tSlope, 4); + tTangent = data(tSlope, 4); + } + + return 0; +} + +double MultiLinear::getStrain(void) { - return tStrain; + return tStrain; } -double +double MultiLinear::getStress(void) { - return tStress; + return tStress; } -double +double MultiLinear::getTangent(void) { - return tTangent; + return tTangent; } -int +int MultiLinear::commitState(void) { - // if yielded we need to reset the values - if (tSlope != 0) { // yielded - - - if (tStrain > data(0,1)) { // positive yield direction - - // set elastic bounds - data(0,1) = tStrain; - data(0,3) = tStress; - data(0,0) = tStrain - 2*data(0,5); - data(0,2) = tStress - 2*data(0,5)*data(0,4); - - // reset bounds for all those pts before yield - // - pos & neg affected - for (int i=1; i data(0, 1)) { // positive yield direction + + // set elastic bounds + data(0, 1) = tStrain; + data(0, 3) = tStress; + data(0, 0) = tStrain - 2 * data(0, 5); + data(0, 2) = tStress - 2 * data(0, 5) * data(0, 4); + + // reset bounds for all those pts before yield + // - pos & neg affected + for (int i = 1; i < tSlope; i++) { + data(i, 1) = tStrain; + data(i, 3) = tStress; + data(i, 0) = data(i - 1, 0) - 2 * data(i, 5); + data(i, 2) = data(i - 1, 2) - 2 * data(i, 5) * data(i, 4); + } + + // reset bounds for all those pts after + // - neg affected + data(tSlope, 0) = data(tSlope - 1, 0) - 2 * data(tSlope, 5) + + data(tSlope, 1) - data(tSlope - 1, 1); + data(tSlope, 2) = data(tSlope - 1, 2) + + (data(tSlope, 0) - data(tSlope - 1, 0)) * data(tSlope, 4); + + for (int i = tSlope + 1; i < numSlope; i++) { + data(i, 0) = data(i - 1, 0) - 2 * data(i, 5) + + data(i, 1) - data(i - 1, 1); + data(i, 2) = data(i - 1, 2) + + (data(i, 0) - data(i - 1, 0)) * data(i, 4); + } + } + else { // neg yield direction + + // set elastic bounds + data(0, 0) = tStrain; + data(0, 2) = tStress; + data(0, 1) = tStrain + 2 * data(0, 5); + data(0, 3) = tStress + 2 * data(0, 5) * data(0, 4); + + // reset bounds for all those pts before yield slope + // - pos & neg affected + for (int i = 1; i < tSlope; i++) { + data(i, 0) = tStrain; + data(i, 2) = tStress; + data(i, 1) = data(i - 1, 1) + 2 * data(i, 5); + data(i, 3) = data(i - 1, 3) + 2 * data(i, 5) * data(i, 4); + } + + // reset bounds for all those pts after + // - pos pts affected + data(tSlope, 1) = data(tSlope - 1, 1) + 2 * data(tSlope, 5) + + data(tSlope, 0) - data(tSlope - 1, 0); + data(tSlope, 3) = data(tSlope - 1, 3) + + (data(tSlope, 1) - data(tSlope - 1, 1)) * data(tSlope, 4); + + for (int i = tSlope + 1; i < numSlope; i++) { + data(i, 1) = data(i - 1, 1) + 2 * data(i, 5) + + data(i, 0) - data(i - 1, 0); + data(i, 3) = data(i - 1, 3) + + (data(i, 1) - data(i - 1, 1)) * data(i, 4); + } + } } - } - - cStress = tStress; - cStrain = tStrain; - cTangent = tTangent; - return 0; + cStress = tStress; + cStrain = tStrain; + cTangent = tTangent; + + return 0; } -int +int MultiLinear::revertToLastCommit(void) { - tStrain = cStrain; - tTangent = cTangent; - tStress = cStress; - - return 0; + tStrain = cStrain; + tTangent = cTangent; + tStress = cStress; + + return 0; } -int +int MultiLinear::revertToStart(void) { - - data(0,1) = data(0,5); - data(0,3) = data(0,5)*data(0,4); - data(0,0) = -data(0,1); - data(0,2) = -data(0,3); - - for (int i=1; idata = this->data; - theCopy->numSlope = this->numSlope; - - theCopy->tSlope = this->tSlope; - theCopy->tStress = this->tStress; - theCopy->tStrain = this->tStrain; - theCopy->tTangent = this->tTangent; - theCopy->cStress = this->cStress; - theCopy->cStrain = this->cStrain; - theCopy->cTangent = this->cTangent; - - return theCopy; + MultiLinear* theCopy = + new MultiLinear(); + theCopy->data = this->data; + theCopy->numSlope = this->numSlope; + + theCopy->tSlope = this->tSlope; + theCopy->tStress = this->tStress; + theCopy->tStrain = this->tStrain; + theCopy->tTangent = this->tTangent; + theCopy->cStress = this->cStress; + theCopy->cStrain = this->cStrain; + theCopy->cTangent = this->cTangent; + + return theCopy; } -int -MultiLinear::sendSelf(int cTag, Channel &theChannel) +int +MultiLinear::sendSelf(int cTag, Channel& theChannel) { - int res = 0; - static ID iData(2); - iData(0) = this->getTag(); - iData(1) = numSlope; - - res = theChannel.sendID(this->getDbTag(), cTag, iData); - if (res < 0) { - opserr << "ElasticMaterial::sendSelf() - failed to send data\n"; + int res = 0; + static ID iData(2); + iData(0) = this->getTag(); + iData(1) = numSlope; + + res = theChannel.sendID(this->getDbTag(), cTag, iData); + if (res < 0) { + opserr << "ElasticMaterial::sendSelf() - failed to send data\n"; + return res; + } + + res = theChannel.sendMatrix(this->getDbTag(), cTag, data); + if (res < 0) + opserr << "ElasticMaterial::sendSelf() - failed to send data\n"; + return res; - } - - res = theChannel.sendMatrix(this->getDbTag(), cTag, data); - if (res < 0) - opserr << "ElasticMaterial::sendSelf() - failed to send data\n"; - - return res; } -int -MultiLinear::recvSelf(int cTag, Channel &theChannel, - FEM_ObjectBroker &theBroker) +int +MultiLinear::recvSelf(int cTag, Channel& theChannel, + FEM_ObjectBroker& theBroker) { - int res = 0; - static ID iData(2); - res = theChannel.recvID(this->getDbTag(), cTag, iData); - if (res < 0) { - opserr << "ElasticMaterial::recvSelf() - failed to recv data\n"; + int res = 0; + static ID iData(2); + res = theChannel.recvID(this->getDbTag(), cTag, iData); + if (res < 0) { + opserr << "ElasticMaterial::recvSelf() - failed to recv data\n"; + return res; + } + + this->setTag(iData(0)); + numSlope = iData(1); + + data.resize(numSlope, 6); + + res = theChannel.recvMatrix(this->getDbTag(), cTag, data); + if (res < 0) + opserr << "ElasticMaterial::recvSelf() - failed to recv data\n"; + return res; - } - - this->setTag(iData(0)); - numSlope = iData(1); - - data.resize(numSlope,6); - - res = theChannel.recvMatrix(this->getDbTag(), cTag, data); - if (res < 0) - opserr << "ElasticMaterial::recvSelf() - failed to recv data\n"; - - return res; } -void -MultiLinear::Print(OPS_Stream &s, int flag) +void +MultiLinear::Print(OPS_Stream& s, int flag) { s << "MultiLinear tag: " << this->getTag() << endln; s << " stress: " << tStress << " tangent: " << tTangent << endln; diff --git a/SRC/material/uniaxial/MultiplierMaterial.cpp b/SRC/material/uniaxial/MultiplierMaterial.cpp new file mode 100644 index 0000000000..3af29b7c4b --- /dev/null +++ b/SRC/material/uniaxial/MultiplierMaterial.cpp @@ -0,0 +1,350 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.6 $ +// $Date: 2010-09-11 00:50:53 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/MultiplierMaterial.cpp,v $ + +// Written: MHS +// Created: Aug 2001 +// +// Description: This file contains the class definition for +// MultiplierMaterial. MultiplierMaterial wraps a UniaxialMaterial +// and multiplies the stress and tangent of the wrapped UniaxialMaterial +// object by a factor. This wrapper can be used to apply overstrength +// factors to materials and p-y multipliers for shadowing effects in +// pile groups. An example is shown below with a multiplier of 0.8. +// and imposes min and max strain limits. + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#define OPS_Export + +OPS_Export void * +OPS_MultiplierMaterial(void) +{ + // Pointer to a uniaxial material that will be returned + UniaxialMaterial *theMaterial = 0; + UniaxialMaterial *theOtherMaterial = 0; + int iData[2]; + + int argc = OPS_GetNumRemainingInputArgs(); + if (argc < 2) { + opserr << "WARNING insufficient args, uniaxialMaterial Multiplier $tag $otherTag $multiplier" << endln; + return 0; + } + + int numData = 2; + if (OPS_GetIntInput(&numData, iData) < 0) { + opserr << "WARNING invalid uniaxialMaterial Multiplier $tag $otherTag $multiplier" << endln; + return 0; + } + + theOtherMaterial = OPS_GetUniaxialMaterial(iData[1]); + if (theOtherMaterial == 0) { + opserr << "WARNING invalid otherTag uniaxialMaterial Multiplier tag: " << iData[0] << endln; + return 0; + } + + double multiplier = 1.0; + numData = 1; + if (OPS_GetDouble(&numData,&multiplier) < 0) { + opserr << "WARNING invalid input uniaxialMaterial Multiplier tag: " << iData[0] << endln; + return 0; + } + + // Parsing was successful, allocate the material + theMaterial = new MultiplierMaterial(iData[0], *theOtherMaterial, multiplier); + + if (theMaterial == 0) { + opserr << "WARNING could not create uniaxialMaterial of type MultiplierMaterial\n"; + return 0; + } + + return theMaterial; +} + +MultiplierMaterial::MultiplierMaterial(int tag, UniaxialMaterial &material, double mult) + :UniaxialMaterial(tag,MAT_TAG_Multiplier), theMaterial(0), multiplier(mult), parameterID(0) +{ + theMaterial = material.getCopy(); + + if (theMaterial == 0) { + opserr << "MultiplierMaterial::MultiplierMaterial -- failed to get copy of material\n"; + exit(-1); + } +} + +MultiplierMaterial::MultiplierMaterial() + :UniaxialMaterial(0,MAT_TAG_Multiplier), theMaterial(0), multiplier(1.0), parameterID(0) +{ + +} + +MultiplierMaterial::~MultiplierMaterial() +{ + if (theMaterial) + delete theMaterial; +} + +int +MultiplierMaterial::setTrialStrain(double strain, double strainRate) +{ + return theMaterial->setTrialStrain(strain, strainRate); +} + + +int +MultiplierMaterial::setTrialStrain(double strain, double temp, double strainRate) +{ + return theMaterial->setTrialStrain(strain, temp, strainRate); +} + + +double +MultiplierMaterial::getStress(void) +{ + return multiplier*theMaterial->getStress(); +} + +double +MultiplierMaterial::getTangent(void) +{ + return multiplier*theMaterial->getTangent(); +} + +double +MultiplierMaterial::getDampTangent(void) +{ + return multiplier*theMaterial->getDampTangent(); +} + + + +double +MultiplierMaterial::getStrain(void) +{ + return theMaterial->getStrain(); +} + +double +MultiplierMaterial::getStrainRate(void) +{ + return theMaterial->getStrainRate(); +} + +int +MultiplierMaterial::commitState(void) +{ + return theMaterial->commitState(); +} + +int +MultiplierMaterial::revertToLastCommit(void) +{ + return theMaterial->revertToLastCommit(); +} + +int +MultiplierMaterial::revertToStart(void) +{ + return theMaterial->revertToStart(); +} + +UniaxialMaterial * +MultiplierMaterial::getCopy(void) +{ + MultiplierMaterial *theCopy = + new MultiplierMaterial(this->getTag(), *theMaterial, multiplier); + + return theCopy; +} + +int +MultiplierMaterial::sendSelf(int cTag, Channel &theChannel) +{ + int dbTag = this->getDbTag(); + + static ID dataID(3); + dataID(0) = this->getTag(); + dataID(1) = theMaterial->getClassTag(); + int matDbTag = theMaterial->getDbTag(); + if ( matDbTag == 0) { + matDbTag = theChannel.getDbTag(); + theMaterial->setDbTag(matDbTag); + } + dataID(2) = matDbTag; + if (theChannel.sendID(dbTag, cTag, dataID) < 0) { + opserr << "MultiplierMaterial::sendSelf() - failed to send the ID\n"; + return -1; + } + + static Vector dataVec(1); + dataVec(0) = multiplier; + + if (theChannel.sendVector(dbTag, cTag, dataVec) < 0) { + opserr << "MultiplierMaterial::sendSelf() - failed to send the Vector\n"; + return -2; + } + + if (theMaterial->sendSelf(cTag, theChannel) < 0) { + opserr << "MultiplierMaterial::sendSelf() - failed to send the Material\n"; + return -3; + } + + return 0; +} + +int +MultiplierMaterial::recvSelf(int cTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int dbTag = this->getDbTag(); + + static ID dataID(3); + if (theChannel.recvID(dbTag, cTag, dataID) < 0) { + opserr << "MultiplierMaterial::recvSelf() - failed to get the ID\n"; + return -1; + } + this->setTag(int(dataID(0))); + + // as no way to change material, don't have to check classTag of the material + if (theMaterial == 0) { + int matClassTag = int(dataID(1)); + theMaterial = theBroker.getNewUniaxialMaterial(matClassTag); + if (theMaterial == 0) { + opserr << "MultiplierMaterial::recvSelf() - failed to create Material with classTag " + << dataID(0) << endln; + return -2; + } + } + theMaterial->setDbTag(dataID(2)); + + static Vector dataVec(1); + if (theChannel.recvVector(dbTag, cTag, dataVec) < 0) { + opserr << "MultiplierMaterial::recvSelf() - failed to get the Vector\n"; + return -3; + } + + multiplier = dataVec(0); + + if (theMaterial->recvSelf(cTag, theChannel, theBroker) < 0) { + opserr << "MultiplierMaterial::recvSelf() - failed to get the Material\n"; + return -4; + } + return 0; +} + +void +MultiplierMaterial::Print(OPS_Stream &s, int flag) +{ + s << "MultiplierMaterial tag: " << this->getTag() << endln; + s << "\tMaterial: " << theMaterial->getTag() << endln; + s << "\tMultiplier: " << multiplier << endln; +} + +int +MultiplierMaterial::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (strcmp(argv[0],"multiplier") == 0) { + param.setValue(multiplier); + return param.addObject(1,this); + } + return theMaterial->setParameter(argv, argc, param); +} + +int +MultiplierMaterial::updateParameter(int parameterID, Information &info) +{ + switch (parameterID) { + case -1: + return -1; + case 1: + this->multiplier = info.theDouble; + break; + } + + return 0; +} + +int +MultiplierMaterial::activateParameter(int paramID) +{ + parameterID = paramID; + + return 0; +} + +double +MultiplierMaterial::getStressSensitivity(int gradIndex, bool conditional) +{ + // dsig = dF*sigma + F*dsigma + if (parameterID == 1) + return theMaterial->getStress(); // dF*sigma where dF=1 + else + return multiplier*theMaterial->getStressSensitivity(gradIndex,conditional); +} + +double +MultiplierMaterial::getStrainSensitivity(int gradIndex) +{ + return theMaterial->getStrainSensitivity(gradIndex); +} + +double +MultiplierMaterial::getInitialTangentSensitivity(int gradIndex) +{ + if (parameterID == 1) + return theMaterial->getInitialTangent(); + else + return multiplier*theMaterial->getInitialTangentSensitivity(gradIndex); +} + +double +MultiplierMaterial::getDampTangentSensitivity(int gradIndex) +{ + if (parameterID == 1) + return theMaterial->getDampTangent(); + else + return multiplier*theMaterial->getDampTangentSensitivity(gradIndex); +} + +double +MultiplierMaterial::getRhoSensitivity(int gradIndex) +{ + return theMaterial->getRhoSensitivity(gradIndex); +} + +int +MultiplierMaterial::commitSensitivity(double strainGradient, int gradIndex, int numGrads) +{ + return theMaterial->commitSensitivity(strainGradient, gradIndex, numGrads); +} diff --git a/SRC/material/uniaxial/MultiplierMaterial.h b/SRC/material/uniaxial/MultiplierMaterial.h new file mode 100644 index 0000000000..f6551a12c6 --- /dev/null +++ b/SRC/material/uniaxial/MultiplierMaterial.h @@ -0,0 +1,94 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision$ +// $Date$ +// $Source$ + +// Description: This file contains the class definition for +// MultiplierMaterial. MultiplierMaterial wraps a UniaxialMaterial +// and multiplies the stress and tangent of the wrapped UniaxialMaterial +// object by a factor. This wrapper can be used to apply overstrength +// factors to materials and p-y multipliers for shadowing effects in +// pile groups. An example is shown below with a multiplier of 0.8. + +#ifndef MultiplierMaterial_h +#define MultiplierMaterial_h + +#include + +class MultiplierMaterial : public UniaxialMaterial +{ + public: + MultiplierMaterial(int tag, UniaxialMaterial &material, double mult); + MultiplierMaterial(); + ~MultiplierMaterial(); + + const char *getClassType(void) const {return "MultiplierMaterial";}; + + int setTrialStrain(double strain, double strainRate = 0.0); + int setTrialStrain(double strain, double FiberTemperature, double strainRate); + double getStrain(void); + double getStrainRate(void); + double getStress(void); + double getTangent(void); + double getDampTangent(void); + double getInitialTangent(void) {return theMaterial->getInitialTangent();} + + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + UniaxialMaterial *getCopy(void); + + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + + void Print(OPS_Stream &s, int flag =0); + + int setParameter(const char **argv, int argc, Parameter ¶m); + int updateParameter(int parameterID, Information &info); + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int activateParameter(int parameterID); + double getStressSensitivity (int gradIndex, bool conditional); + double getStrainSensitivity (int gradIndex); + double getInitialTangentSensitivity(int gradIndex); + double getDampTangentSensitivity(int gradIndex); + double getRhoSensitivity (int gradIndex); + int commitSensitivity (double strainGradient, int gradIndex, int numGrads); + // AddingSensitivity:END /////////////////////////////////////////// + + protected: + + private: + UniaxialMaterial *theMaterial; + + double multiplier; + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int parameterID; + // AddingSensitivity:END /////////////////////////////////////////// +}; + + +#endif + diff --git a/SRC/material/uniaxial/PY/PyLiq1.cpp b/SRC/material/uniaxial/PY/PyLiq1.cpp index 03d9424e4a..2005cc4b5d 100644 --- a/SRC/material/uniaxial/PY/PyLiq1.cpp +++ b/SRC/material/uniaxial/PY/PyLiq1.cpp @@ -63,6 +63,13 @@ #include #include #include +#include + +#include +#include +#include +#include +#include // Controls on internal iteration between spring components const int PYmaxIterations = 20; diff --git a/SRC/material/uniaxial/PY/PyLiq1.h b/SRC/material/uniaxial/PY/PyLiq1.h index 6b201d4755..5de64068bf 100644 --- a/SRC/material/uniaxial/PY/PyLiq1.h +++ b/SRC/material/uniaxial/PY/PyLiq1.h @@ -57,21 +57,14 @@ #include #include -#include -#include -#include //#include -#include +#include "PySimple1.h" #include #include -#include -#include -//#include -//#include -#include +class TimeSeries; - class PyLiq1 : public PySimple1 +class PyLiq1 : public PySimple1 { public: PyLiq1(int tag, int classtag, int soilType, double pult, double y50, double drag, diff --git a/SRC/material/uniaxial/PY/TzLiq1.cpp b/SRC/material/uniaxial/PY/TzLiq1.cpp index 9a63256a8c..0aaa6ac8b6 100644 --- a/SRC/material/uniaxial/PY/TzLiq1.cpp +++ b/SRC/material/uniaxial/PY/TzLiq1.cpp @@ -33,6 +33,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include // Control on internal iteration between spring components const int TZmaxIterations = 20; diff --git a/SRC/material/uniaxial/PY/TzLiq1.h b/SRC/material/uniaxial/PY/TzLiq1.h index df5e418b3e..e763606f0d 100644 --- a/SRC/material/uniaxial/PY/TzLiq1.h +++ b/SRC/material/uniaxial/PY/TzLiq1.h @@ -23,22 +23,19 @@ // Description: This file contains the class definition for TzLiq1. // +#include "TzSimple1.h" #include #include -#include -#include -//#include -#include -#include -#include -#include + +#include + +class FourNodeQuad; +class TimeSeries; + //#include //#include -#include - -class TzLiq1 : public TzSimple1 -{ +class TzLiq1 : public TzSimple1 { public: TzLiq1(int tag, int classtag, int tzType, double tult, double z50, double dashpot, int solidElem1, int solidElem2, Domain *theDomain); diff --git a/SRC/material/uniaxial/PathIndependentMaterial.cpp b/SRC/material/uniaxial/PathIndependentMaterial.cpp index d669cb305e..50c17b598f 100644 --- a/SRC/material/uniaxial/PathIndependentMaterial.cpp +++ b/SRC/material/uniaxial/PathIndependentMaterial.cpp @@ -257,6 +257,18 @@ PathIndependentMaterial::Print(OPS_Stream &s, int flag) s << "\tmaterial: " << theMaterial->getTag() << endln; } +int +PathIndependentMaterial::setParameter(const char **argv, int argc, Parameter ¶m) +{ + return theMaterial->setParameter(argv, argc, param); +} + +int +PathIndependentMaterial::updateParameter(int parameterID, Information &info) +{ + return 0; +} + double PathIndependentMaterial::getStressSensitivity(int gradIndex, bool conditional) { diff --git a/SRC/material/uniaxial/PathIndependentMaterial.h b/SRC/material/uniaxial/PathIndependentMaterial.h index 251d2e0044..d02bef4ac5 100644 --- a/SRC/material/uniaxial/PathIndependentMaterial.h +++ b/SRC/material/uniaxial/PathIndependentMaterial.h @@ -64,14 +64,17 @@ class PathIndependentMaterial : public UniaxialMaterial FEM_ObjectBroker &theBroker); void Print(OPS_Stream &s, int flag =0); + + int setParameter(const char **argv, int argc, Parameter ¶m); + int updateParameter(int parameterID, Information &info); // AddingSensitivity:BEGIN ////////////////////////////////////////// - virtual double getStressSensitivity (int gradIndex, bool conditional); - virtual double getStrainSensitivity (int gradIndex); - virtual double getInitialTangentSensitivity(int gradIndex); - virtual double getDampTangentSensitivity(int gradIndex); - virtual double getRhoSensitivity (int gradIndex); - virtual int commitSensitivity (double strainGradient, int gradIndex, int numGrads); + double getStressSensitivity (int gradIndex, bool conditional); + double getStrainSensitivity (int gradIndex); + double getInitialTangentSensitivity(int gradIndex); + double getDampTangentSensitivity(int gradIndex); + double getRhoSensitivity (int gradIndex); + int commitSensitivity (double strainGradient, int gradIndex, int numGrads); // AddingSensitivity:END /////////////////////////////////////////// protected: diff --git a/SRC/material/uniaxial/PenaltyMaterial.cpp b/SRC/material/uniaxial/PenaltyMaterial.cpp new file mode 100644 index 0000000000..3d6b2f1a1b --- /dev/null +++ b/SRC/material/uniaxial/PenaltyMaterial.cpp @@ -0,0 +1,346 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.6 $ +// $Date: 2010-09-11 00:50:53 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/PenaltyMaterial.cpp,v $ + +// Written: MHS +// Created: Aug 2001 +// +// Description: This file contains the class definition for +// PenaltyMaterial. PenaltyMaterial adds a small stiffness to +// its wrapped UniaxialMaterial object. This wrapper can help you +// avoid a singular stiffness due to perfect plasticity and is a +// downsized approach to putting the wrapped material in parallel +// with an ElasticMaterial. + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#define OPS_Export + +OPS_Export void * +OPS_PenaltyMaterial(void) +{ + // Pointer to a uniaxial material that will be returned + UniaxialMaterial *theMaterial = 0; + UniaxialMaterial *theOtherMaterial = 0; + int iData[2]; + + int argc = OPS_GetNumRemainingInputArgs(); + if (argc < 2) { + opserr << "WARNING insufficient args, uniaxialMaterial Penalty $tag $otherTag $penalty" << endln; + return 0; + } + + int numData = 2; + if (OPS_GetIntInput(&numData, iData) < 0) { + opserr << "WARNING invalid uniaxialMaterial Penalty $tag $otherTag $penalty" << endln; + return 0; + } + + theOtherMaterial = OPS_GetUniaxialMaterial(iData[1]); + if (theOtherMaterial == 0) { + opserr << "WARNING invalid otherTag uniaxialMaterial Penalty tag: " << iData[0] << endln; + return 0; + } + + double penalty = 0.0; + numData = 1; + if (OPS_GetDouble(&numData,&penalty) < 0) { + opserr << "WARNING invalid input uniaxialMaterial Penalty tag: " << iData[0] << endln; + return 0; + } + + // Parsing was successful, allocate the material + theMaterial = new PenaltyMaterial(iData[0], *theOtherMaterial, penalty); + + if (theMaterial == 0) { + opserr << "WARNING could not create uniaxialMaterial of type PenaltyMaterial\n"; + return 0; + } + + return theMaterial; +} + +PenaltyMaterial::PenaltyMaterial(int tag, UniaxialMaterial &material, double mult) + :UniaxialMaterial(tag,MAT_TAG_Penalty), theMaterial(0), penalty(mult), parameterID(0) +{ + theMaterial = material.getCopy(); + + if (theMaterial == 0) { + opserr << "PenaltyMaterial::PenaltyMaterial -- failed to get copy of material\n"; + exit(-1); + } +} + +PenaltyMaterial::PenaltyMaterial() + :UniaxialMaterial(0,MAT_TAG_Penalty), theMaterial(0), penalty(0.0), parameterID(0) +{ + +} + +PenaltyMaterial::~PenaltyMaterial() +{ + if (theMaterial) + delete theMaterial; +} + +int +PenaltyMaterial::setTrialStrain(double strain, double strainRate) +{ + return theMaterial->setTrialStrain(strain, strainRate); +} + + +int +PenaltyMaterial::setTrialStrain(double strain, double temp, double strainRate) +{ + return theMaterial->setTrialStrain(strain, temp, strainRate); +} + + +double +PenaltyMaterial::getStress(void) +{ + return theMaterial->getStress() + penalty*theMaterial->getStrain(); +} + +double +PenaltyMaterial::getTangent(void) +{ + return theMaterial->getTangent() + penalty; +} + +double +PenaltyMaterial::getDampTangent(void) +{ + return theMaterial->getDampTangent(); +} + + + +double +PenaltyMaterial::getStrain(void) +{ + return theMaterial->getStrain(); +} + +double +PenaltyMaterial::getStrainRate(void) +{ + return theMaterial->getStrainRate(); +} + +int +PenaltyMaterial::commitState(void) +{ + return theMaterial->commitState(); +} + +int +PenaltyMaterial::revertToLastCommit(void) +{ + return theMaterial->revertToLastCommit(); +} + +int +PenaltyMaterial::revertToStart(void) +{ + return theMaterial->revertToStart(); +} + +UniaxialMaterial * +PenaltyMaterial::getCopy(void) +{ + PenaltyMaterial *theCopy = + new PenaltyMaterial(this->getTag(), *theMaterial, penalty); + + return theCopy; +} + +int +PenaltyMaterial::sendSelf(int cTag, Channel &theChannel) +{ + int dbTag = this->getDbTag(); + + static ID dataID(3); + dataID(0) = this->getTag(); + dataID(1) = theMaterial->getClassTag(); + int matDbTag = theMaterial->getDbTag(); + if ( matDbTag == 0) { + matDbTag = theChannel.getDbTag(); + theMaterial->setDbTag(matDbTag); + } + dataID(2) = matDbTag; + if (theChannel.sendID(dbTag, cTag, dataID) < 0) { + opserr << "PenaltyMaterial::sendSelf() - failed to send the ID\n"; + return -1; + } + + static Vector dataVec(1); + dataVec(0) = penalty; + + if (theChannel.sendVector(dbTag, cTag, dataVec) < 0) { + opserr << "PenaltyMaterial::sendSelf() - failed to send the Vector\n"; + return -2; + } + + if (theMaterial->sendSelf(cTag, theChannel) < 0) { + opserr << "PenaltyMaterial::sendSelf() - failed to send the Material\n"; + return -3; + } + + return 0; +} + +int +PenaltyMaterial::recvSelf(int cTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int dbTag = this->getDbTag(); + + static ID dataID(3); + if (theChannel.recvID(dbTag, cTag, dataID) < 0) { + opserr << "PenaltyMaterial::recvSelf() - failed to get the ID\n"; + return -1; + } + this->setTag(int(dataID(0))); + + // as no way to change material, don't have to check classTag of the material + if (theMaterial == 0) { + int matClassTag = int(dataID(1)); + theMaterial = theBroker.getNewUniaxialMaterial(matClassTag); + if (theMaterial == 0) { + opserr << "PenaltyMaterial::recvSelf() - failed to create Material with classTag " + << dataID(0) << endln; + return -2; + } + } + theMaterial->setDbTag(dataID(2)); + + static Vector dataVec(1); + if (theChannel.recvVector(dbTag, cTag, dataVec) < 0) { + opserr << "PenaltyMaterial::recvSelf() - failed to get the Vector\n"; + return -3; + } + + penalty = dataVec(0); + + if (theMaterial->recvSelf(cTag, theChannel, theBroker) < 0) { + opserr << "PenaltyMaterial::recvSelf() - failed to get the Material\n"; + return -4; + } + return 0; +} + +void +PenaltyMaterial::Print(OPS_Stream &s, int flag) +{ + s << "PenaltyMaterial tag: " << this->getTag() << endln; + s << "\tMaterial: " << theMaterial->getTag() << endln; + s << "\tPenalty: " << penalty << endln; +} + +int +PenaltyMaterial::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (strcmp(argv[0],"penalty") == 0) { + param.setValue(penalty); + return param.addObject(1,this); + } + return theMaterial->setParameter(argv, argc, param); +} + +int +PenaltyMaterial::updateParameter(int parameterID, Information &info) +{ + switch (parameterID) { + case -1: + return -1; + case 1: + this->penalty = info.theDouble; + break; + } + + return 0; +} + +int +PenaltyMaterial::activateParameter(int paramID) +{ + parameterID = paramID; + + return 0; +} + +double +PenaltyMaterial::getStressSensitivity(int gradIndex, bool conditional) +{ + // dsig = dsigma + dalpha*strain < + alpha*dstrain> + if (parameterID == 1) + return theMaterial->getStrain(); // dalpha*strain where dalpha=1 + else + return theMaterial->getStressSensitivity(gradIndex,conditional); +} + +double +PenaltyMaterial::getStrainSensitivity(int gradIndex) +{ + return theMaterial->getStrainSensitivity(gradIndex); +} + +double +PenaltyMaterial::getInitialTangentSensitivity(int gradIndex) +{ + if (parameterID == 1) + return 1.0; + else + return theMaterial->getInitialTangentSensitivity(gradIndex); +} + +double +PenaltyMaterial::getDampTangentSensitivity(int gradIndex) +{ + theMaterial->getDampTangentSensitivity(gradIndex); +} + +double +PenaltyMaterial::getRhoSensitivity(int gradIndex) +{ + return theMaterial->getRhoSensitivity(gradIndex); +} + +int +PenaltyMaterial::commitSensitivity(double strainGradient, int gradIndex, int numGrads) +{ + return theMaterial->commitSensitivity(strainGradient, gradIndex, numGrads); +} diff --git a/SRC/material/uniaxial/PenaltyMaterial.h b/SRC/material/uniaxial/PenaltyMaterial.h new file mode 100644 index 0000000000..2641888afc --- /dev/null +++ b/SRC/material/uniaxial/PenaltyMaterial.h @@ -0,0 +1,94 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision$ +// $Date$ +// $Source$ + +// Description: This file contains the class definition for +// PenaltyMaterial. PenaltyMaterial adds a small stiffness to +// its wrapped UniaxialMaterial object. This wrapper can help you +// avoid a singular stiffness due to perfect plasticity and is a +// downsized approach to putting the wrapped material in parallel +// with an ElasticMaterial. + +#ifndef PenaltyMaterial_h +#define PenaltyMaterial_h + +#include + +class PenaltyMaterial : public UniaxialMaterial +{ + public: + PenaltyMaterial(int tag, UniaxialMaterial &material, double penalty); + PenaltyMaterial(); + ~PenaltyMaterial(); + + const char *getClassType(void) const {return "PenaltyMaterial";}; + + int setTrialStrain(double strain, double strainRate = 0.0); + int setTrialStrain(double strain, double FiberTemperature, double strainRate); + double getStrain(void); + double getStrainRate(void); + double getStress(void); + double getTangent(void); + double getDampTangent(void); + double getInitialTangent(void) {return theMaterial->getInitialTangent();} + + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + UniaxialMaterial *getCopy(void); + + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + + void Print(OPS_Stream &s, int flag =0); + + int setParameter(const char **argv, int argc, Parameter ¶m); + int updateParameter(int parameterID, Information &info); + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int activateParameter(int parameterID); + double getStressSensitivity (int gradIndex, bool conditional); + double getStrainSensitivity (int gradIndex); + double getInitialTangentSensitivity(int gradIndex); + double getDampTangentSensitivity(int gradIndex); + double getRhoSensitivity (int gradIndex); + int commitSensitivity (double strainGradient, int gradIndex, int numGrads); + // AddingSensitivity:END /////////////////////////////////////////// + + protected: + + private: + UniaxialMaterial *theMaterial; + + double penalty; + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int parameterID; + // AddingSensitivity:END /////////////////////////////////////////// +}; + + +#endif + diff --git a/SRC/material/uniaxial/ReinforcingSteel.cpp b/SRC/material/uniaxial/ReinforcingSteel.cpp index 1616b1ec2b..73856caa50 100644 --- a/SRC/material/uniaxial/ReinforcingSteel.cpp +++ b/SRC/material/uniaxial/ReinforcingSteel.cpp @@ -655,7 +655,7 @@ ReinforcingSteel::sendSelf(int cTag, Channel &theChannel) { int res = 0; int index =0; - static Vector data(75+12*LastRule_RS/2); + static Vector data(75+12*(LastRule_RS/2+1)); data(index++) = this->getTag(); data(index++) = reduction; @@ -763,7 +763,7 @@ ReinforcingSteel::recvSelf(int cTag, Channel &theChannel, { int res = 0; int index =0; - static Vector data(75+12*LastRule_RS/2); + static Vector data(75+12*(LastRule_RS/2+1)); res = theChannel.recvVector(this->getDbTag(), cTag, data); if (res < 0) { diff --git a/SRC/material/uniaxial/SLModel.cpp b/SRC/material/uniaxial/SLModel.cpp new file mode 100755 index 0000000000..2feb6ef291 --- /dev/null +++ b/SRC/material/uniaxial/SLModel.cpp @@ -0,0 +1,1987 @@ +#include +#include +#include +#include +#include +#include + + +#include "SLModel.h" + +#include + + +static int numSLModel = 0; + +void * +OPS_SLModel() +{ + // print out some KUDO's + if (numSLModel == 0) { + numSLModel++; + opserr << "SLModel version 2019.2\n"; + } + + // Pointer to a uniaxial material that will be returned + UniaxialMaterial *theMaterial = 0; + + int iData[1]; + double dData[3]; + int numData = 1; + + if (OPS_GetIntInput(&numData, iData) != 0) { + opserr << "WARNING invalid uniaxialMaterial SLModel tag" << endln; + return 0; + } + + numData = 3; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "Invalid Args want: uniaxialMaterial SLModel tag? Dt?, sgm_ini?, OP_Material?"; + return 0; + } + + // create a new material + theMaterial = new SLModel(iData[0], dData[0], dData[1], dData[2]); + + if (theMaterial == 0) { + opserr << "WARNING could not create uniaxialMaterial of type SLModel\n"; + return 0; + } + + // return the material + return theMaterial; +} + + +//MAT_TAG_SLModel or 0 +SLModel::SLModel(int tag, double Dt_temp, double sgm_ini_temp, double OP_Material_temp) +:UniaxialMaterial(tag, MAT_TAG_SLModel), Dt(Dt_temp), sgm_ini(sgm_ini_temp), OP_Material(OP_Material_temp) +{ + this->revertToStart(); +} + +SLModel::SLModel() +:UniaxialMaterial(0, MAT_TAG_SLModel), Dt(0.0), sgm_ini(0.0), OP_Material(0.0) +{ + this->revertToStart(); +} + +SLModel::~SLModel() +{ + // does nothing +} + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +int +SLModel::setTrialStrain(double strain, double strainRate)/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////TODO +{ + + //all variables to the last commit + this->revertToLastCommit(); // a = C_a + + // local variables + double True_tEpsp2, TrueEpsPrev, p_teps_d, Deltap_teps; + double TrueSgmPinch; + + // set trial strain + neps = strain; //set trial displacement + teps = log(1.0+neps); + + // ignore very small strain increment + double deltaD; + deltaD = strain - C_neps; + if (fabs(deltaD) < 1.0e-18 && strain != 0.0) { + return 0; + } + + + ///////////////////////////////////////////////////////// not used + if (iInitial <= 0) { + iInitial++; + } + ///////////////////////////////////////////////////////// + + + // pre-buckling process + if (status == 1) { + if (teps <= teps_prev) { + if (teps >= yteps_n) { + status = 1; + StrainHardeningFunc(); + + //*** check capping stress ******************************************************************************************** + if (nsgm < cSgmc) { + //deterioration slope modification + cEpsc = neps_prev+(neps-neps_prev)/(nsgm-nsgm_prev)*(cSgmc-nsgm_prev); + cEpsd1 = cEpsc-(cSgmc-cSgmd1)/cEd1; + cSgmd2 = cSgmd1-cEd2*cEpsd1; + cEpsd2 = -cSgmd2/cEd2; + + //peak point for tensile excursion + tEpsp = cEpsc; + tSgmp = sgm_ini; + + //reference point for back bone curve offset + refEps = cEpsc-cIniEpsc; + cEpsy = refEps-sgm_ini/E; + + //status + status = 4; + } + //********************************************************************************************************************** + } else if (teps < yteps_n) { + status = 3; + StrainHardeningFunc(); + YieldPointFunc(); + + //*** check capping stress ******************************************************************************************** + if (nsgm < cSgmc) { + //deterioration slope modification + cEpsc = neps_prev+(neps-neps_prev)/(nsgm-nsgm_prev)*(cSgmc-nsgm_prev); + cEpsd1 = cEpsc-(cSgmc-cSgmd1)/cEd1; + cSgmd2 = cSgmd1-cEd2*cEpsd1; + cEpsd2 = -cSgmd2/cEd2; + + //peak point for tensile excursion + tEpsp = cEpsc; + tSgmp = sgm_ini; + + //reference point for back bone curve offset + refEps = cEpsc-cIniEpsc; + cEpsy = refEps-sgm_ini/E; + + //status + status = 4; + } + //********************************************************************************************************************** + } + } else { + if (teps <= yteps_p) { + status = 1; + StrainHardeningFunc(); + } else if (teps > yteps_p) { + status = 2; + StrainHardeningFunc(); + YieldPointFunc(); + } + } + } else if (status == 2) { + if (teps >= teps_prev) { + status = 2; + StrainHardeningFunc(); + YieldPointFunc(); + } else if (teps < teps_prev && teps >= yteps_n) { + status = 1; + StrainHardeningFunc(); + } else if (teps < teps_prev && teps < yteps_n) { + status = 3; + StrainHardeningFunc(); + YieldPointFunc(); + } + } else if (status == 3) { + if (teps <= teps_prev) { + status = 3; + StrainHardeningFunc(); + YieldPointFunc(); + //*** check capping stress ******************************************************************************************** + if (nsgm < cSgmc) { + //deterioration slope modification + cEpsc = neps_prev+(neps-neps_prev)/(nsgm-nsgm_prev)*(cSgmc-nsgm_prev); + cEpsd1 = cEpsc-(cSgmc-cSgmd1)/cEd1; + cSgmd2 = cSgmd1-cEd2*cEpsd1; + cEpsd2 = -cSgmd2/cEd2; + + //peak point for tensile excursion + tEpsp = cEpsc; + tSgmp = sgm_ini; + + //reference point for back bone curve offset + refEps = cEpsc-cIniEpsc; + cEpsy = refEps-sgm_ini/E; + + //status + status = 4; + } + //********************************************************************************************************************** + } else if (teps > teps_prev && teps <= yteps_p) { + status = 1; + StrainHardeningFunc(); + } else if (teps > teps_prev && teps > yteps_p) { + status = 2; + StrainHardeningFunc(); + YieldPointFunc(); + } + } + + // post-buckling process + if (status >= 4 && status <= 999) { + + if (neps < neps_prev) { + if (cEpsy < neps) { + //unloading + status = 9; + nsgm = cSgmy-cEu*(cEpsy-neps); + //Tangent = cEu; + Tangent = (nsgm-nsgm_prev)/(neps-neps_prev); + } else if (cEpsc < neps && neps <= cEpsy) { + //post-yield + status = 10; + nsgm = cSgmy+cEsth*(neps-cEpsy); + //Tangent = cEsth; + Tangent = (nsgm-nsgm_prev)/(neps-neps_prev); + } else if (cEpsd1 < neps && neps <= cEpsc) { + //1st deterioration slope + status = 4; + nsgm = cSgmc+cEd1*(neps-cEpsc); + //Tangent = cEd1; + Tangent = (nsgm-nsgm_prev)/(neps-neps_prev); + } else if (cEpsd2 < neps && neps <= cEpsd1) { + //2nd deterioration slope + status = 5; + nsgm = cEd2*neps+cSgmd2; + //Tangent = cEd2; + Tangent = (nsgm-nsgm_prev)/(neps-neps_prev); + } else if (neps <= cEpsd2) { + //zero stress + status = 1000; + nsgm = -0.0001; + Tangent = 1.0e-10; + //std::cout << "*********************** 1111 **************************\n"; + } + + //plastic stain + p_neps = neps-nsgm/tEu; + + } else if (neps > neps_prev) { + if (neps < tEpsy) { + //unloading + status = 6; + nsgm = tSgmy-tEu*(tEpsy-neps); + //Tangent = tEu; + Tangent = (nsgm-nsgm_prev)/(neps-neps_prev); + } else if (tEpsy <= neps && neps < tEpsp2) { + //reloading + status = 7; + nsgm = tSgmy+tEr2*(neps-tEpsy); + //Tangent = tEr2; + Tangent = (nsgm-nsgm_prev)/(neps-neps_prev); + } else if (tEpsp2 <= neps) { + //strain hardening + status = 8; + + //true stress/strain at pinching point + True_tEpsp2 = log(1.0+tEpsp2); + + //true stress/strain @ previous step + TrueEpsPrev = log(1.0+neps_prev); + + //true strain @ current step + teps = log(1.0+neps); + + //cumulative plastic strain + if (TrueEpsPrev < True_tEpsp2) { + p_teps_d = teps-True_tEpsp2; + tsgm = nsgm_prev*(1.0+tEpsp2); + } else { + p_teps_d = teps-TrueEpsPrev; + tsgm = nsgm_prev*(1.0+neps_prev); + } + + //increment of plastic strain + Deltap_teps = p_teps_d/5.0; + + for (int i=1;i<=5;i++) { + //kinematic hardening + alf_d = c/sgm_0*(tsgm-alf)*(Deltap_teps)-gamma*alf*(Deltap_teps); + alf = alf+alf_d; //plus + + //isotropic hardening + cum_p_teps = cum_p_teps+fabs(Deltap_teps); + sgm_0 = sgm_ini+q*(1-exp(-1*beta*cum_p_teps)); + + //true stress + tsgm = alf+sgm_0; //plus + } + + //engineering stress + nsgm = tsgm/exp(teps); + + //Tangent + Tangent = (nsgm-nsgm_prev)/(neps-neps_prev); + + } + + // plastic stain + p_neps = neps-nsgm/cEu; + } + + } else if (status == 1000) { + status = 1000; + nsgm = -0.00001; + Tangent = 1.0e-10; + //std::cout << "*********************** 2222 **************************\n"; + } + + + //Cumulative plastic strain, Energy Dissipation + if (status == 1 || status == 2 || status == 3) { + DeltaE = 0.0; + } else if (status == 1000) { + DeltaE = 0.0; + } else { + DeltaE = fabs(p_neps-p_neps_prev)*fabs(nsgm+nsgm_prev)/2.0; + } + + + if (Et1-TotalE < 0.0) { + Beta1 = 0.0; + Alpha1 = Alpha1*(1-Beta1); + } else if (DeltaE > Et1-TotalE) { + Beta1 = 0.0; + Alpha1 = Alpha1*(1-Beta1); + } else { + Beta1 = pow(DeltaE/(Et1-TotalE),c1); + Alpha1 = Alpha1*(1-Beta1); + } + + + if (Et2-TotalE < 0.0) { + Beta2 = 0.0; + Alpha2 = Alpha2*(1-Beta2); + } else if (DeltaE > Et2-TotalE) { + Beta2 = 0.0; + Alpha2 = Alpha2*(1-Beta2); + } else { + Beta2 = pow(DeltaE/(Et2-TotalE),c2); + Alpha2 = Alpha2*(1-Beta2); + } + + if (Et3-TotalE < 0.0) { + Beta3 = 0.0; + Alpha3 = Alpha3*(1-Beta3); + } else if (DeltaE > Et3-TotalE) { + Beta3 = 0.0; + Alpha3 = Alpha3*(1-Beta3); + } else { + Beta3 = pow(DeltaE/(Et3-TotalE),c3); + Alpha3 = Alpha3*(1-Beta3); + } + + TotalE = TotalE+DeltaE; + + + + //Update back bone curve + if (status == 4 || status == 5 || status == 10) { + BackBoneTenFunc(); + + //true stress @ pinching point + TrueSgmPinch = tSgmp*(1.0+tEpsp2); + //update kinematic hardening + alf = TrueSgmPinch-sgm_0; + } else if (status == 7 || status == 8) { + BackBoneCompFunc(); + } else if (status == 9) { + BackBoneTen2Func(); + } else if (status == 6) { + BackBoneComp2Func(); + } + + //store stress and strain + teps_prev = teps; + neps_prev = neps; + tsgm_prev = tsgm; + nsgm_prev = nsgm; + + p_neps_prev = p_neps; + p_teps_prev = p_teps; + + + + return 0; +} + + + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + +double +SLModel::getStrain(void) +{ + return neps; +} + +double +SLModel::getStress(void) +{ + return nsgm; +} + +double +SLModel::getTangent(void) +{ + //std::cout << "*********" << Tangent << "****************************\n"; + return Tangent; +} + +int +SLModel::commitState(void) +{ + + C_status = status; + + C_E = E; + C_Dteq = Dteq; + + C_q = q; + C_beta = beta; + C_c = c; + C_gamma = gamma; + + C_CapYieldStressM = CapYieldStressM; + C_CapYieldStrainM = CapYieldStrainM; + C_Ed1EM = Ed1EM; + C_Ed2EM = Ed2EM; + C_DetCapStressM = DetCapStressM; + + C_p_teps = p_teps; + C_p_neps = p_neps; + + C_p_neps_prev = p_neps_prev; + C_p_teps_prev = p_teps_prev; + + C_cum_p_teps = cum_p_teps; + + C_sgm_0 = sgm_0; + C_alf_d = alf_d; + C_alf = alf; + + C_ytsgm_p = ytsgm_p; + C_ytsgm_n = ytsgm_n; + C_yteps_p = yteps_p; + C_yteps_n = yteps_n; + + C_teps = teps; + C_neps = neps; + C_tsgm = tsgm; + C_nsgm = nsgm; + + C_teps_prev = teps_prev; + C_neps_prev = neps_prev; + C_tsgm_prev = tsgm_prev; + C_nsgm_prev = nsgm_prev; + + C_cEu = cEu; + C_cSgmy = cSgmy; + C_cEpsy = cEpsy; + C_cSgmc = cSgmc; + C_cEpsc = cEpsc; + C_cSgmd1 = cSgmd1; + C_cEpsd1 = cEpsd1; + C_cSgmd2 = cSgmd2; + C_cEpsd2 = cEpsd2; + C_cSgmb = cSgmb; + C_cSgmd = cSgmd; + C_cEsth = cEsth; + C_cEd1 = cEd1; + C_cEd2 = cEd2; + + C_cIniSgmy = cIniSgmy; + C_cIniEpsy = cIniEpsy; + C_cIniSgmc = cIniSgmc; + C_cIniEpsc = cIniEpsc; + C_cIniEsth = cIniEsth; + C_cIniEd1 = cIniEd1; + C_cIniEd2 = cIniEd2; + C_cIniSgmd1 = cIniSgmd1; + C_cIniEpsd1 = cIniEpsd1; + C_cIniSgmb = cIniSgmb; + C_cIniSgmd = cIniSgmd; + C_cIniSgmd2 = cIniSgmd2; + C_cIniEpsd2 = cIniEpsd2; + + C_tEu = tEu; + C_tSgmy = tSgmy; + C_tEpsy = tEpsy; + C_tSgmp = tSgmp; + C_tEpsp = tEpsp; + C_tEpsp2 = tEpsp2; + C_tEr = tEr; + C_tEr2 = tEr2; + C_refEps = refEps; + + C_ay = ay; + C_au = au; + + C_Lambda1 = Lambda1; + C_c1 = c1; + C_Lambda2 = Lambda2; + C_c2 = c2; + C_Lambda3 = Lambda3; + C_c3 = c3; + + C_Et1 = Et1; + C_Et2 = Et2; + C_Et3 = Et3; + + C_Beta1 = Beta1; + C_Beta2 = Beta2; + C_Beta3 = Beta3; + + C_Alpha1 = Alpha1; + C_Alpha2 = Alpha2; + C_Alpha3 = Alpha3; + + C_TotalE = TotalE; + C_DeltaE = DeltaE; + + C_Tangent = Tangent; + + C_iInitial = iInitial; + + return 0; +} + + +int +SLModel::revertToLastCommit(void) +{ + //the opposite of commit trial history variables + status = C_status; + + E = C_E; + Dteq = C_Dteq; + + q = C_q; + beta = C_beta; + c = C_c; + gamma = C_gamma; + + CapYieldStressM = C_CapYieldStressM; + CapYieldStrainM = C_CapYieldStrainM; + Ed1EM = C_Ed1EM; + Ed2EM = C_Ed2EM; + DetCapStressM = C_DetCapStressM; + + p_teps = C_p_teps; + p_neps = C_p_neps; + + p_neps_prev = C_p_neps_prev; + p_teps_prev = C_p_teps_prev; + + cum_p_teps = C_cum_p_teps; + + sgm_0 = C_sgm_0; + alf_d = C_alf_d; + alf = C_alf; + + ytsgm_p = C_ytsgm_p; + ytsgm_n = C_ytsgm_n; + yteps_p = C_yteps_p; + yteps_n = C_yteps_n; + + teps = C_teps; + neps = C_neps; + tsgm = C_tsgm; + nsgm = C_nsgm; + + teps_prev = C_teps_prev; + neps_prev = C_neps_prev; + tsgm_prev = C_tsgm_prev; + nsgm_prev = C_nsgm_prev; + + cEu = C_cEu; + cSgmy = C_cSgmy; + cEpsy = C_cEpsy; + cSgmc = C_cSgmc; + cEpsc = C_cEpsc; + cSgmd1 = C_cSgmd1; + cEpsd1 = C_cEpsd1; + cSgmd2 = C_cSgmd2; + cEpsd2 = C_cEpsd2; + cSgmb = C_cSgmb; + cSgmd = C_cSgmd; + cEsth = C_cEsth; + cEd1 = C_cEd1; + cEd2 = C_cEd2; + + cIniSgmy = C_cIniSgmy; + cIniEpsy = C_cIniEpsy; + cIniSgmc = C_cIniSgmc; + cIniEpsc = C_cIniEpsc; + cIniEsth = C_cIniEsth; + cIniEd1 = C_cIniEd1; + cIniEd2 = C_cIniEd2; + cIniSgmd1 = C_cIniSgmd1; + cIniEpsd1 = C_cIniEpsd1; + cIniSgmb = C_cIniSgmb; + cIniSgmd = C_cIniSgmd; + cIniSgmd2 = C_cIniSgmd2; + cIniEpsd2 = C_cIniEpsd2; + + tEu = C_tEu; + tSgmy = C_tSgmy; + tEpsy = C_tEpsy; + tSgmp = C_tSgmp; + tEpsp = C_tEpsp; + tEpsp2 = C_tEpsp2; + tEr = C_tEr; + tEr2 = C_tEr2; + refEps = C_refEps; + + ay = C_ay; + au = C_au; + + Lambda1 = C_Lambda1; + c1 = C_c1; + Lambda2 = C_Lambda2; + c2 = C_c2; + Lambda3 = C_Lambda3; + c3 = C_c3; + + Et1 = C_Et1; + Et2 = C_Et2; + Et3 = C_Et3; + + Beta1 = C_Beta1; + Beta2 = C_Beta2; + Beta3 = C_Beta3; + + Alpha1 = C_Alpha1; + Alpha2 = C_Alpha2; + Alpha3 = C_Alpha3; + + TotalE = C_TotalE; + DeltaE = C_DeltaE; + + Tangent = C_Tangent; + + iInitial = C_iInitial; + + return 0; +} + + +int +SLModel::revertToStart(void) +{ + // Initialize state variables + status = C_status = 1; + + E = C_E = 200000.0; + + Dteq = C_Dteq = (Dt)*sqrt(sgm_ini/E); + + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + if (OP_Material == 10) { + //*** BCP *** + q = C_q = 68.0956; + beta = C_beta = 14.072; + c = C_c = 4200.0; + gamma = C_gamma = 19.0; + + CapYieldStressM = C_CapYieldStressM = 1.2345*pow(Dteq,-0.564); + CapYieldStrainM = C_CapYieldStrainM = 8.3096*pow(Dteq,-3.156); + Ed1EM = C_Ed1EM = -0.0267*pow(Dteq,1.5213)*0.8;//********************************************************************************************************************************************************** + Ed2EM = C_Ed2EM = -0.0034*pow(Dteq,0.8134)*0.8;//********************************************************************************************************************************************************** + DetCapStressM = C_DetCapStressM = 0.6225*pow(Dteq,0.0888); + + ay = C_ay = 1.6465*pow(Dteq/sqrt(sgm_ini/E),-1.136); + au = C_au = 5.5813*pow(Dteq/sqrt(sgm_ini/E),-1.732); + + Lambda1 = C_Lambda1 = 31.237*pow(Dt,-1.127); + c1 = C_c1 = 1.0; + + Lambda2 = C_Lambda2 = Lambda1*3.0; //********************************************************************************************************************************************************** + c2 = C_c2 = 1.0; + + Lambda3 = C_Lambda3 = Lambda1*3.0; //********************************************************************************************************************************************************** + //Lambda3 = C_Lambda3 = Lambda1*1000.0; //********************************************************************************************************************************************************** + c3 = C_c3 = 1.0; + + } else if (OP_Material == 11) { + //*** HYP *** + q = C_q = 68.1; + beta = C_beta = 14.1; + c = C_c = 2100.0; + gamma = C_gamma = 11.0; + + CapYieldStressM = C_CapYieldStressM = 1.157*pow(Dteq,-0.36); + CapYieldStrainM = C_CapYieldStrainM = 8.3096*pow(Dteq,-3.156); + Ed1EM = C_Ed1EM = -0.027*pow(Dteq,2.0)*0.8;//********************************************************************************************************************************************************** + Ed2EM = C_Ed2EM = -0.0034*pow(Dteq,0.8134)*0.8;//********************************************************************************************************************************************************** + DetCapStressM = C_DetCapStressM = 0.575*pow(Dteq,-0.03); + + ay = C_ay = 2.355*pow(Dteq/sqrt(sgm_ini/E),-1.204)*1.0; + au = C_au = 5.2672*pow(Dteq/sqrt(sgm_ini/E),-1.683); + + Lambda1 = C_Lambda1 = 31.237*pow(Dt,-1.127); + c1 = C_c1 = 1.0; + + Lambda2 = C_Lambda2 = Lambda1*3.0; //********************************************************************************************************************************************************** + c2 = C_c2 = 1.0; + + Lambda3 = C_Lambda3 = Lambda1*3.0; //********************************************************************************************************************************************************** + //Lambda3 = C_Lambda3 = Lambda1*1000.0; //********************************************************************************************************************************************************** + c3 = C_c3 = 1.0; + + + } else if (OP_Material == 12) { + //*** BCR *** + q = C_q = 22.4; + beta = C_beta = 7.2; + c = C_c = 2500.0; + gamma = C_gamma = 19.0; + + //CapYieldStressM = C_CapYieldStressM = 1.114*pow(Dteq,-0.314);//********************************************************************************************************************************************************** + CapYieldStressM = C_CapYieldStressM = 1.125*pow(Dteq,-0.27);//********************************************************************************************************************************************************** + CapYieldStrainM = C_CapYieldStrainM = 6.720*pow(Dteq,-3.09); + //Ed1EM = C_Ed1EM = -0.015*pow(Dteq,1.5);//********************************************************************************************************************************************************** + Ed1EM = C_Ed1EM = -0.0133*pow(Dteq,2.0)*1.0;//********************************************************************************************************************************************************** + Ed2EM = C_Ed2EM = -0.003*pow(Dteq,1.221)*0.8;//********************************************************************************************************************************************************** + DetCapStressM = C_DetCapStressM = 0.614*pow(Dteq,-0.041); + + ay = C_ay = 24.0*pow(Dteq/sqrt(sgm_ini/E),-1.8); + au = C_au = 5.4522*pow(Dteq/sqrt(sgm_ini/E),-1.653)*1.0; + + Lambda1 = C_Lambda1 = 17.72*pow(Dt,-0.989)*1.0; + c1 = C_c1 = 1.0; + + Lambda2 = C_Lambda2 = Lambda1*3.0; //********************************************************************************************************************************************************** + c2 = C_c2 = 1.0; + + Lambda3 = C_Lambda3 = Lambda1*3.0; //********************************************************************************************************************************************************** + //Lambda3 = C_Lambda3 = Lambda1*1000.0; //********************************************************************************************************************************************************** + c3 = C_c3 = 1.0; + + } else { + std::cout << "*********************** Material ID " << OP_Material << " is not prepared. **************************\n"; + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + p_teps = C_p_teps = 0.0; + p_neps = C_p_neps = 0.0; + + p_neps_prev = C_p_neps_prev = 0.0; + p_teps_prev = C_p_teps_prev = 0.0; + + cum_p_teps = C_cum_p_teps = 0.0; + + sgm_0 = C_sgm_0 = sgm_ini; + alf_d = C_alf_d = 0.0; + alf = C_alf = 0.0; + + ytsgm_p = C_ytsgm_p = sgm_ini; + ytsgm_n = C_ytsgm_n = -1*sgm_ini; + yteps_p = C_yteps_p = ytsgm_p/E;; + yteps_n = C_yteps_n = ytsgm_n/E;; + + teps = C_teps = 0.0; + neps = C_neps = 0.0; + tsgm = C_tsgm = 0.0; + nsgm = C_nsgm = 0.0; + + teps_prev = C_teps_prev = 0.0; + neps_prev = C_neps_prev = 0.0; + tsgm_prev = C_tsgm_prev = 0.0; + nsgm_prev = C_nsgm_prev = 0.0; + + cIniSgmy = C_cIniSgmy = (-1)*sgm_ini; + cIniEpsy = C_cIniEpsy = cIniSgmy/E; + cIniSgmc = C_cIniSgmc = (-1)*CapYieldStressM*sgm_ini; + + + + cIniEpsc = C_cIniEpsc = (-1)*CapYieldStrainM*(sgm_ini/E); + cIniEsth = C_cIniEsth = (cIniSgmc-cIniSgmy)/(cIniEpsc-cIniEpsy); + cIniEd1 = C_cIniEd1 = Ed1EM*E; + cIniEd2 = C_cIniEd2 = Ed2EM*E; + cIniSgmd1 = C_cIniSgmd1 = DetCapStressM*cIniSgmc; + cIniEpsd1 = C_cIniEpsd1 = cIniEpsc-(cIniSgmc-cIniSgmd1)/cIniEd1; + cIniSgmb = C_cIniSgmb = cIniSgmy-cIniEsth*cIniEpsy; + cIniSgmd = C_cIniSgmd = cIniSgmc-cIniEd1*cIniEpsc; + cIniSgmd2 = C_cIniSgmd2 = cIniSgmd1-cIniEd2*cIniEpsd1; + cIniEpsd2 = C_cIniEpsd2 = -cIniSgmd2/cIniEd2; + + cSgmb = C_cSgmb = cIniSgmb; + cSgmd = C_cSgmd = cIniSgmd; + + cEu = C_cEu = E; + cEsth = C_cEsth = cIniEsth; + cEd1 = C_cEd1 = cIniEd1; + cEd2 = C_cEd2 = cIniEd2; + + + cEpsc = C_cEpsc = -(cSgmd-cSgmb)/(cIniEd1-cIniEsth); + cSgmc = C_cSgmc = cIniEd1*cEpsc+cSgmd; + + cSgmd1 = C_cSgmd1 = cIniSgmd1; + cEpsd1 = C_cEpsd1 = cEpsc-(cSgmc-cSgmd1)/cEd1; + cSgmd2 = C_cSgmd2 = cSgmd1-cEd2*cEpsd1; + cEpsd2 = C_cEpsd2 = -cSgmd2/cEd2; + + cSgmd = C_cSgmd = cSgmc-cEd1*cEpsc; + cSgmb = C_cSgmb = cSgmc-cEsth*cEpsc; + + cSgmy = C_cSgmy = cEu*cSgmb/(cEu-cEsth); + cEpsy = C_cEpsy = cSgmb/(cEu-cEsth); + + + tEu = C_tEu = E; + tSgmy = C_tSgmy = sgm_ini; + tEpsy = C_tEpsy = sgm_ini/E; + tSgmp = C_tSgmp = sgm_ini; + tEpsp = C_tEpsp = cEpsc; + tEpsp2 = C_tEpsp2 = cEpsc; + + tEr = C_tEr = E; + tEr2 = C_tEr2 = E; + + refEps = C_refEps = 0.0; + + + Et1 = C_Et1 = Lambda1*sgm_ini; + Et2 = C_Et2 = Lambda2*sgm_ini; + Et3 = C_Et3 = Lambda3*sgm_ini; + + Beta1 = C_Beta1 = 0.0; + Beta2 = C_Beta2 = 0.0; + Beta3 = C_Beta3 = 0.0; + + Alpha1 = C_Alpha1 = 1.0; + Alpha2 = C_Alpha2 = 1.0; + Alpha3 = C_Alpha3 = 1.0; + + TotalE = C_TotalE = 0.0; + DeltaE = C_DeltaE = 0.0; + + Tangent = C_Tangent = 0.0; + + iInitial = C_iInitial = 0.0; + + return 0; +} + + +UniaxialMaterial * +SLModel::getCopy(void) +{ + SLModel *theCopy = new SLModel(this->getTag(), Dt, sgm_ini, OP_Material); + + //Fixed Model parameters: need to change according to material properties + theCopy -> status = status; + + theCopy -> E = E; + theCopy -> Dteq = Dteq; + theCopy -> q = q; + theCopy -> beta = beta; + theCopy -> c = c; + theCopy -> gamma = gamma; + theCopy -> CapYieldStressM = CapYieldStressM; + theCopy -> CapYieldStrainM = CapYieldStrainM; + theCopy -> Ed1EM = Ed1EM; + theCopy -> Ed2EM = Ed2EM; + theCopy -> DetCapStressM = DetCapStressM; + theCopy -> p_teps = p_teps; + theCopy -> p_neps = p_neps; + theCopy -> p_neps_prev = p_neps_prev; + theCopy -> p_teps_prev = p_teps_prev; + theCopy -> cum_p_teps = cum_p_teps; + theCopy -> sgm_0 = sgm_0; + theCopy -> alf_d = alf_d; + theCopy -> alf = alf; + theCopy -> ytsgm_p = ytsgm_p; + theCopy -> ytsgm_n = ytsgm_n; + theCopy -> yteps_p = yteps_p; + theCopy -> yteps_n = yteps_n; + theCopy -> teps = teps; + theCopy -> neps = neps; + theCopy -> tsgm = tsgm; + theCopy -> nsgm = nsgm; + theCopy -> teps_prev = teps_prev; + theCopy -> neps_prev = neps_prev; + theCopy -> tsgm_prev = tsgm_prev; + theCopy -> nsgm_prev = nsgm_prev; + theCopy -> cEu = cEu; + theCopy -> cSgmy = cSgmy; + theCopy -> cEpsy = cEpsy; + theCopy -> cSgmc = cSgmc; + theCopy -> cEpsc = cEpsc; + theCopy -> cSgmd1 = cSgmd1; + theCopy -> cEpsd1 = cEpsd1; + theCopy -> cSgmd2 = cSgmd2; + theCopy -> cEpsd2 = cEpsd2; + theCopy -> cSgmb = cSgmb; + theCopy -> cSgmd = cSgmd; + theCopy -> cEsth = cEsth; + theCopy -> cEd1 = cEd1; + theCopy -> cEd2 = cEd2; + theCopy -> cIniSgmy = cIniSgmy; + theCopy -> cIniEpsy = cIniEpsy; + theCopy -> cIniSgmc = cIniSgmc; + theCopy -> cIniEpsc = cIniEpsc; + theCopy -> cIniEsth = cIniEsth; + theCopy -> cIniEd1 = cIniEd1; + theCopy -> cIniEd2 = cIniEd2; + theCopy -> cIniSgmd1 = cIniSgmd1; + theCopy -> cIniEpsd1 = cIniEpsd1; + theCopy -> cIniSgmb = cIniSgmb; + theCopy -> cIniSgmd = cIniSgmd; + theCopy -> cIniSgmd2 = cIniSgmd2; + theCopy -> cIniEpsd2 = cIniEpsd2; + theCopy -> tEu = tEu; + theCopy -> tSgmy = tSgmy; + theCopy -> tEpsy = tEpsy; + theCopy -> tSgmp = tSgmp; + theCopy -> tEpsp = tEpsp; + theCopy -> tEpsp2 = tEpsp2; + theCopy -> tEr = tEr; + theCopy -> tEr2 = tEr2; + theCopy -> refEps = refEps; + theCopy -> ay = ay; + theCopy -> au = au; + theCopy -> Lambda1 = Lambda1; + theCopy -> c1 = c1; + theCopy -> Lambda2 = Lambda2; + theCopy -> c2 = c2; + theCopy -> Lambda3 = Lambda3; + theCopy -> c3 = c3; + theCopy -> Et1 = Et1; + theCopy -> Et2 = Et2; + theCopy -> Et3 = Et3; + theCopy -> Beta1 = Beta1; + theCopy -> Beta2 = Beta2; + theCopy -> Beta3 = Beta3; + theCopy -> Alpha1 = Alpha1; + theCopy -> Alpha2 = Alpha2; + theCopy -> Alpha3 = Alpha3; + theCopy -> TotalE = TotalE; + theCopy -> DeltaE = DeltaE; + theCopy -> Tangent = Tangent; + theCopy -> iInitial = iInitial; + + theCopy -> C_E = C_E; + theCopy -> C_Dteq = C_Dteq; + theCopy -> C_q = C_q; + theCopy -> C_beta = C_beta; + theCopy -> C_c = C_c; + theCopy -> C_gamma = C_gamma; + theCopy -> C_CapYieldStressM = C_CapYieldStressM; + theCopy -> C_CapYieldStrainM = C_CapYieldStrainM; + theCopy -> C_Ed1EM = C_Ed1EM; + theCopy -> C_Ed2EM = C_Ed2EM; + theCopy -> C_DetCapStressM = C_DetCapStressM; + theCopy -> C_p_teps = C_p_teps; + theCopy -> C_p_neps = C_p_neps; + theCopy -> C_p_neps_prev = C_p_neps_prev; + theCopy -> C_p_teps_prev = C_p_teps_prev; + theCopy -> C_cum_p_teps = C_cum_p_teps; + theCopy -> C_sgm_0 = C_sgm_0; + theCopy -> C_alf_d = C_alf_d; + theCopy -> C_alf = C_alf; + theCopy -> C_ytsgm_p = C_ytsgm_p; + theCopy -> C_ytsgm_n = C_ytsgm_n; + theCopy -> C_yteps_p = C_yteps_p; + theCopy -> C_yteps_n = C_yteps_n; + theCopy -> C_teps = C_teps; + theCopy -> C_neps = C_neps; + theCopy -> C_tsgm = C_tsgm; + theCopy -> C_nsgm = C_nsgm; + theCopy -> C_teps_prev = C_teps_prev; + theCopy -> C_neps_prev = C_neps_prev; + theCopy -> C_tsgm_prev = C_tsgm_prev; + theCopy -> C_nsgm_prev = C_nsgm_prev; + theCopy -> C_cEu = C_cEu; + theCopy -> C_cSgmy = C_cSgmy; + theCopy -> C_cEpsy = C_cEpsy; + theCopy -> C_cSgmc = C_cSgmc; + theCopy -> C_cEpsc = C_cEpsc; + theCopy -> C_cSgmd1 = C_cSgmd1; + theCopy -> C_cEpsd1 = C_cEpsd1; + theCopy -> C_cSgmd2 = C_cSgmd2; + theCopy -> C_cEpsd2 = C_cEpsd2; + theCopy -> C_cSgmb = C_cSgmb; + theCopy -> C_cSgmd = C_cSgmd; + theCopy -> C_cEsth = C_cEsth; + theCopy -> C_cEd1 = C_cEd1; + theCopy -> C_cEd2 = C_cEd2; + theCopy -> C_cIniSgmy = C_cIniSgmy; + theCopy -> C_cIniEpsy = C_cIniEpsy; + theCopy -> C_cIniSgmc = C_cIniSgmc; + theCopy -> C_cIniEpsc = C_cIniEpsc; + theCopy -> C_cIniEsth = C_cIniEsth; + theCopy -> C_cIniEd1 = C_cIniEd1; + theCopy -> C_cIniEd2 = C_cIniEd2; + theCopy -> C_cIniSgmd1 = C_cIniSgmd1; + theCopy -> C_cIniEpsd1 = C_cIniEpsd1; + theCopy -> C_cIniSgmb = C_cIniSgmb; + theCopy -> C_cIniSgmd = C_cIniSgmd; + theCopy -> C_cIniSgmd2 = C_cIniSgmd2; + theCopy -> C_cIniEpsd2 = C_cIniEpsd2; + theCopy -> C_tEu = C_tEu; + theCopy -> C_tSgmy = C_tSgmy; + theCopy -> C_tEpsy = C_tEpsy; + theCopy -> C_tSgmp = C_tSgmp; + theCopy -> C_tEpsp = C_tEpsp; + theCopy -> C_tEpsp2 = C_tEpsp2; + theCopy -> C_tEr = C_tEr; + theCopy -> C_tEr2 = C_tEr2; + theCopy -> C_refEps = C_refEps; + theCopy -> C_ay = C_ay; + theCopy -> C_au = C_au; + theCopy -> C_Lambda1 = C_Lambda1; + theCopy -> C_c1 = C_c1; + theCopy -> C_Lambda2 = C_Lambda2; + theCopy -> C_c2 = C_c2; + theCopy -> C_Lambda3 = C_Lambda3; + theCopy -> C_c3 = C_c3; + theCopy -> C_Et1 = C_Et1; + theCopy -> C_Et2 = C_Et2; + theCopy -> C_Et3 = C_Et3; + theCopy -> C_Beta1 = C_Beta1; + theCopy -> C_Beta2 = C_Beta2; + theCopy -> C_Beta3 = C_Beta3; + theCopy -> C_Alpha1 = C_Alpha1; + theCopy -> C_Alpha2 = C_Alpha2; + theCopy -> C_Alpha3 = C_Alpha3; + theCopy -> C_TotalE = C_TotalE; + theCopy -> C_DeltaE = C_DeltaE; + theCopy -> C_Tangent = C_Tangent; + theCopy -> C_iInitial = C_iInitial; + + return theCopy; +} + + +int +SLModel::sendSelf(int cTag, Channel &theChannel) +{ + int res = 0; + static Vector data(182); + data(0) = this->getTag(); + + // constaint variables + data(1) = Dt; + data(2) = sgm_ini; + data(3) = OP_Material; + + // constaint variables + data(4) = E; + data(5) = Dteq; + data(6) = q; + data(7) = beta; + data(8) = c; + data(9) = gamma; + data(10) = CapYieldStressM; + data(11) = CapYieldStrainM; + data(12) = Ed1EM; + data(13) = Ed2EM; + data(14) = DetCapStressM; + data(15) = ay; + data(16) = au; + data(17) = Lambda1; + data(18) = c1; + data(19) = Lambda2; + data(20) = c2; + data(21) = Lambda3; + data(22) = c3; + data(23) = Et1; + data(24) = Et2; + data(25) = Et3; + + // State variables from last converged state + data(26) = status; + data(27) = p_teps; + data(28) = p_neps; + data(29) = p_neps_prev; + data(30) = p_teps_prev; + data(31) = cum_p_teps; + data(31) = sgm_0; + data(33) = alf_d; + data(34) = alf; + data(35) = ytsgm_p; + data(36) = ytsgm_n; + data(37) = yteps_p; + data(38) = yteps_n; + data(39) = teps; + data(40) = neps; + data(41) = tsgm; + data(42) = nsgm; + data(43) = teps_prev; + data(44) = neps_prev; + data(45) = tsgm_prev; + data(46) = nsgm_prev; + data(47) = cEu; + data(48) = cSgmy; + data(49) = cEpsy; + data(50) = cSgmc; + data(51) = cEpsc; + data(52) = cSgmd1; + data(53) = cEpsd1; + data(54) = cSgmd2; + data(55) = cEpsd2; + data(56) = cSgmb; + data(57) = cSgmd; + data(58) = cEsth; + data(59) = cEd1; + data(60) = cEd2; + data(61) = cIniSgmy; + data(62) = cIniEpsy; + data(63) = cIniSgmc; + data(64) = cIniEpsc; + data(65) = cIniEsth; + data(66) = cIniEd1; + data(67) = cIniEd2; + data(68) = cIniSgmd1; + data(69) = cIniEpsd1; + data(70) = cIniSgmb; + data(71) = cIniSgmd; + data(72) = cIniSgmd2; + data(73) = cIniEpsd2; + data(74) = tEu; + data(75) = tSgmy; + data(76) = tEpsy; + data(77) = tSgmp; + data(78) = tEpsp; + data(79) = tEpsp2; + data(80) = tEr; + data(81) = tEr2; + data(82) = refEps; + data(83) = Beta1; + data(84) = Beta2; + data(85) = Beta3; + data(86) = Alpha1; + data(87) = Alpha2; + data(88) = Alpha3; + data(89) = TotalE; + data(90) = DeltaE; + data(91) = Tangent; + + // constaint variables + data(92) = C_E; + data(93) = C_Dteq; + data(94) = C_q; + data(95) = C_beta; + data(96) = C_c; + data(97) = C_gamma; + data(98) = C_CapYieldStressM; + data(99) = C_CapYieldStrainM; + data(100) = C_Ed1EM; + data(101) = C_Ed2EM; + data(102) = C_DetCapStressM; + data(103) = C_ay; + data(104) = C_au; + data(105) = C_Lambda1; + data(106) = C_c1; + data(107) = C_Lambda2; + data(108) = C_c2; + data(109) = C_Lambda3; + data(110) = C_c3; + data(111) = C_Et1; + data(112) = C_Et2; + data(113) = C_Et3; + + // State variables from last converged state + data(114) = C_status; + data(115) = C_p_teps; + data(116) = C_p_neps; + data(117) = C_p_neps_prev; + data(118) = C_p_teps_prev; + data(119) = C_cum_p_teps; + data(120) = C_sgm_0; + data(121) = C_alf_d; + data(122) = C_alf; + data(123) = C_ytsgm_p; + data(124) = C_ytsgm_n; + data(125) = C_yteps_p; + data(126) = C_yteps_n; + data(127) = C_teps; + data(128) = C_neps; + data(129) = C_tsgm; + data(130) = C_nsgm; + data(131) = C_teps_prev; + data(132) = C_neps_prev; + data(133) = C_tsgm_prev; + data(134) = C_nsgm_prev; + data(135) = C_cEu; + data(136) = C_cSgmy; + data(137) = C_cEpsy; + data(138) = C_cSgmc; + data(139) = C_cEpsc; + data(140) = C_cSgmd1; + data(141) = C_cEpsd1; + data(142) = C_cSgmd2; + data(143) = C_cEpsd2; + data(144) = C_cSgmb; + data(145) = C_cSgmd; + data(146) = C_cEsth; + data(147) = C_cEd1; + data(148) = C_cEd2; + data(149) = C_cIniSgmy; + data(150) = C_cIniEpsy; + data(151) = C_cIniSgmc; + data(152) = C_cIniEpsc; + data(153) = C_cIniEsth; + data(154) = C_cIniEd1; + data(155) = C_cIniEd2; + data(156) = C_cIniSgmd1; + data(157) = C_cIniEpsd1; + data(158) = C_cIniSgmb; + data(159) = C_cIniSgmd; + data(160) = C_cIniSgmd2; + data(161) = C_cIniEpsd2; + data(162) = C_tEu; + data(163) = C_tSgmy; + data(164) = C_tEpsy; + data(165) = C_tSgmp; + data(166) = C_tEpsp; + data(167) = C_tEpsp2; + data(168) = C_tEr; + data(169) = C_tEr2; + data(170) = C_refEps; + data(171) = C_Beta1; + data(172) = C_Beta2; + data(173) = C_Beta3; + data(174) = C_Alpha1; + data(175) = C_Alpha2; + data(176) = C_Alpha3; + data(177) = C_TotalE; + data(178) = C_DeltaE; + data(179) = C_Tangent; + + data(180) = iInitial; + data(181) = C_iInitial; + + res = theChannel.sendVector(this->getDbTag(), cTag, data); + if (res < 0) + opserr << "SLModel::sendSelf() - failed to send data\n"; + + return res; +} + +int +SLModel::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +{ + int res = 0; + static Vector data(182); + res = theChannel.recvVector(this->getDbTag(), cTag, data); + if (res < 0) + opserr << "SLModel::recvSelf() - failed to recv data\n"; + else { + + this->setTag(data(0)); + + // constaint variables + Dt= data(1);; + sgm_ini = data(2);; + OP_Material = data(3); + + // constaint variables + E = data(4); + Dteq = data(5); + q = data(6); + beta = data(7); + c = data(8); + gamma = data(9); + CapYieldStressM = data(10); + CapYieldStrainM = data(11); + Ed1EM = data(12); + Ed2EM = data(13); + DetCapStressM = data(14); + ay = data(15); + au = data(16); + Lambda1 = data(17); + c1 = data(18); + Lambda2 = data(19); + c2 = data(20); + Lambda3 = data(21); + c3 = data(22); + Et1 = data(23); + Et2 = data(24); + Et3 = data(25); + + // State variables from last converged state + status = data(26); + p_teps = data(27); + p_neps = data(28); + p_neps_prev = data(29); + p_teps_prev = data(30); + cum_p_teps = data(31); + sgm_0 = data(31); + alf_d = data(33); + alf = data(34); + ytsgm_p = data(35); + ytsgm_n = data(36); + yteps_p = data(37); + yteps_n = data(38); + teps = data(39); + neps = data(40); + tsgm = data(41); + nsgm = data(42); + teps_prev = data(43); + neps_prev = data(44); + tsgm_prev = data(45); + nsgm_prev = data(46); + cEu = data(47); + cSgmy = data(48); + cEpsy = data(49); + cSgmc = data(50); + cEpsc = data(51); + cSgmd1 = data(52); + cEpsd1 = data(53); + cSgmd2 = data(54); + cEpsd2 = data(55); + cSgmb = data(56); + cSgmd = data(57); + cEsth = data(58); + cEd1 = data(59); + cEd2 = data(60); + cIniSgmy = data(61); + cIniEpsy = data(62); + cIniSgmc = data(63); + cIniEpsc = data(64); + cIniEsth = data(65); + cIniEd1 = data(66); + cIniEd2 = data(67); + cIniSgmd1 = data(68); + cIniEpsd1 = data(69); + cIniSgmb = data(70); + cIniSgmd = data(71); + cIniSgmd2 = data(72); + cIniEpsd2= data(73); + tEu = data(74); + tSgmy = data(75); + tEpsy = data(76); + tSgmp = data(77); + tEpsp = data(78); + tEpsp2 = data(79); + tEr = data(80); + tEr2 = data(81); + refEps = data(82); + Beta1 = data(83); + Beta2 = data(84); + Beta3 = data(85); + Alpha1 = data(86); + Alpha2 = data(87); + Alpha3 = data(88); + TotalE = data(89); + DeltaE = data(90); + Tangent = data(91); + + // constaint variables + C_E = data(92); + C_Dteq = data(93); + C_q = data(94); + C_beta = data(95); + C_c = data(96); + C_gamma = data(97); + C_CapYieldStressM = data(98); + C_CapYieldStrainM = data(99); + C_Ed1EM = data(100); + C_Ed2EM = data(101); + C_DetCapStressM = data(102); + C_ay = data(103); + C_au = data(104); + C_Lambda1 = data(105); + C_c1 = data(106); + C_Lambda2 = data(107); + C_c2 = data(108); + C_Lambda3 = data(109); + C_c3 = data(110); + C_Et1 = data(111); + C_Et2 = data(112); + C_Et3 = data(113); + + // State variables from last converged state + C_status = data(114); + C_p_teps = data(115); + C_p_neps = data(116); + C_p_neps_prev = data(117); + C_p_teps_prev = data(118); + C_cum_p_teps = data(119); + C_sgm_0 = data(120); + C_alf_d = data(121); + C_alf = data(122); + C_ytsgm_p = data(123); + C_ytsgm_n = data(124); + C_yteps_p = data(125); + C_yteps_n = data(126); + C_teps = data(127); + C_neps = data(128); + C_tsgm = data(129); + C_nsgm = data(130); + C_teps_prev = data(131); + C_neps_prev = data(132); + C_tsgm_prev = data(133); + C_nsgm_prev = data(134); + C_cEu = data(135); + C_cSgmy = data(136); + C_cEpsy = data(137); + C_cSgmc = data(138); + C_cEpsc = data(139); + C_cSgmd1 = data(140); + C_cEpsd1 = data(141); + C_cSgmd2 = data(142); + C_cEpsd2 = data(143); + C_cSgmb = data(144); + C_cSgmd = data(145); + C_cEsth = data(146); + C_cEd1 = data(147); + C_cEd2 = data(148); + C_cIniSgmy = data(149); + C_cIniEpsy = data(150); + C_cIniSgmc = data(151); + C_cIniEpsc = data(152); + C_cIniEsth = data(153); + C_cIniEd1 = data(154); + C_cIniEd2 = data(155); + C_cIniSgmd1 = data(156); + C_cIniEpsd1 = data(157); + C_cIniSgmb = data(158); + C_cIniSgmd = data(159); + C_cIniSgmd2 = data(160); + C_cIniEpsd2 = data(161); + C_tEu = data(162); + C_tSgmy = data(163); + C_tEpsy = data(164); + C_tSgmp = data(165); + C_tEpsp = data(166); + C_tEpsp2 = data(167); + C_tEr = data(168); + C_tEr2 = data(169); + C_refEps = data(170); + C_Beta1 = data(171); + C_Beta2 = data(172); + C_Beta3 = data(173); + C_Alpha1 = data(174); + C_Alpha2 = data(175); + C_Alpha3 = data(176); + C_TotalE = data(177); + C_DeltaE = data(178); + C_Tangent = data(179); + + + iInitial = data(180); + C_iInitial = data(181); + + } + + return res; +} + + +void +SLModel::Print(OPS_Stream &s, int flag) +{ + s << "SLModel tag: " << this->getTag() << endln; + s << " Dt: " << Dt << endln; + s << " sgm_ini: " << sgm_ini << endln; + s << " OP_Material: " << OP_Material << endln; +} + + + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +/******************************************************************************************** + *** StrainHardeningFunc + ********************************************************************************************/ +void SLModel::StrainHardeningFunc(void) +{ + //define local variables + double Deltap_teps; + + if (status == 1) { + + //plastic strain + p_teps = p_teps_prev; + cum_p_teps = cum_p_teps; + + //true stress + tsgm = (teps-p_teps)*E; + sgm_0 = sgm_0; + alf_d = 0.0; + alf = alf+alf_d; + + //nominal stress + nsgm = tsgm/exp(teps); + + //nominal plastic strain + p_neps = p_neps_prev; + + //Tangent + Tangent = E; + //Tangent = (nsgm-nsgm_prev)/(neps-neps_prev); + + } else if (status == 2) { + + //true plastic strain + p_teps = teps-tsgm/E; + + //increment of plastic strain + Deltap_teps = (p_teps-p_teps_prev)/5.0; + + for (int jj=1;jj<=5;jj++) { + + //kinematic hardening component + alf_d = c/sgm_0*(tsgm-alf)*(Deltap_teps)-gamma*alf*(Deltap_teps); + alf = alf+alf_d; //plus + + //isotropic hardening component + cum_p_teps = cum_p_teps+fabs(Deltap_teps); + sgm_0 = sgm_ini+q*(1-exp(-1*beta*cum_p_teps)); + + //total true stress + tsgm = alf+sgm_0; //plus + + } + + //nominal stress + nsgm = tsgm/exp(teps); + + //nominal plastic strain + p_neps = neps-nsgm/E; + + //Tangent + Tangent = (nsgm-nsgm_prev)/(neps-neps_prev); + + } else if (status == 3) { + + //true plastic strain + p_teps = teps-tsgm/E; + + //increment of plastic strain + Deltap_teps = (p_teps-p_teps_prev)/5.0; + + for (int jj=1;jj<=5;jj++) { + //kinematic hardening component + alf_d = c/sgm_0*(tsgm-alf)*(Deltap_teps)-gamma*alf*(Deltap_teps); + alf = alf-alf_d; //minus + + //isotropic hardening component + cum_p_teps = cum_p_teps+fabs(Deltap_teps); + sgm_0 = sgm_ini+q*(1-exp(-1*beta*cum_p_teps)); + + //total true stress + tsgm = alf-sgm_0; //minus + } + + //nominal stress + nsgm = tsgm/exp(teps); + + //nominal plastic strain + p_neps = neps-nsgm/E; + + //Tangent + Tangent = (nsgm-nsgm_prev)/(neps-neps_prev); + + } +} + + + +/******************************************************************************************** + *** YieldPointFunc + ********************************************************************************************/ +void SLModel::YieldPointFunc(void) +{ + if (status == 2) { + ytsgm_p = tsgm; + yteps_p = teps; + ytsgm_n = tsgm-2*sgm_0; //negative + yteps_n = teps-2*sgm_0/E; //negative + } else if (status == 3) { + ytsgm_p = tsgm+2*sgm_0; //positive + yteps_p = teps+2*sgm_0/E; //positive + ytsgm_n = tsgm; + yteps_n = teps; + } +} + + +/******************************************************************************************** + *** post-buckling excursion in compression + ********************************************************************************************/ +void SLModel::BackBoneCompFunc(void) +{ + + // local variables + double cEpsOffset; + double cSgme; + double TempEps1, TempEps2, TempEps3; + int itemp; + + + // unloading slope + if (neps < tEpsp) { + cEu = E*(au/(au+tEpsp-neps)); + if (cEu > E) { + cEu = E; + } + } else { + cEu = E; + } + + + + // strength deterioration of basic and 1st deterioration strength + cSgmb = cIniSgmb*Alpha1; + cSgmd = cIniSgmd*Alpha1; + + // intersection of elasitc stiffness and strain hardening slope + cSgmy = E*cSgmb/(E-cIniEsth); + cEpsy = cSgmb/(E-cIniEsth); + + // stiffness deterioration + cEsth = cIniEsth*Alpha1; + + // modification of basic strength + cSgmb = cSgmy-cEsth*cEpsy; + + // intersection of strain hardening and 1st deterioration slope + cEpsc = -(cSgmd-cSgmb)/(cIniEd1-cEsth); + cSgmc = cIniEd1*cEpsc+cSgmd; + + // stiffness deterioration + cEd1 = cIniEd1*Alpha1; + + // modification of 1st deterioration strength + cSgmd = cSgmc-cEd1*cEpsc; + + // strength and stiffness deterioraiton of 2nd deterioration slope + cEd2 = cIniEd2*Alpha1; + cSgmd2 = cIniSgmd2*Alpha2; + cEpsd2 = -cSgmd2/cEd2; + + // intersection of 1st deterioration slope and 2nd deterioration slope + cEpsd1 = -(cSgmd2-cSgmd)/(cEd2-cEd1); + cSgmd1 = cEd1*cEpsd1+cSgmd; + + + // offset the back bone curve + if (refEps >= neps-nsgm/cEu) { + cEpsOffset = refEps; + } else { + cEpsOffset = neps-nsgm/cEu; + refEps = cEpsOffset; + } + + cEpsy = cEpsy+cEpsOffset; + cEpsc = cEpsc+cEpsOffset; + cEpsd1 = cEpsd1+cEpsOffset; + cEpsd2 = cEpsd2+cEpsOffset; + + cSgmd2 = cSgmd1-cEd2*cEpsd1; + cSgmd = cSgmd1-cEd1*cEpsd1; + cSgmb = cSgmc-cEsth*cEpsc; + + cSgme = nsgm-cEu*neps; + + // modification of yield stress when 2nd deterioration slope is higher than capping strength + + itemp = 0; + + if (cEpsc < cEpsd1) { + cEpsy = -(E*cEpsOffset-cSgmd2)/(E-cEd2); + cSgmy = E*(cEpsy-cEpsOffset); + cEpsc = cEpsy; + cSgmc = cSgmy; + cEpsd1 = cEpsy; + cSgmd1 = cSgmy; + + itemp = 1; + } + + // + TempEps1 = neps-(nsgm-cSgmc)/cEu; + TempEps2 = neps-(nsgm-cSgmd1)/cEu; + TempEps3 = neps-(nsgm)/cEu; + + double ReductionFactor; + ReductionFactor = 0.0;///////////////////////////////************************************************************************************************************************** + + if (cEpsc <= TempEps1) { + if (itemp == 0) { + cEpsy = -(cSgme-cSgmb)/(cEu-cEsth); + cSgmy = cEu*cEpsy+cSgme; + } else if (itemp == 1) { + cEpsy = -(cSgme-cSgmd2)/(cEu-cEd2); + cSgmy = cEu*cEpsy+cSgme; + + cEpsc = cEpsy; + cSgmc = cSgmy; + cEpsd1 = cEpsy; + cSgmd1 = cSgmy; + + + cEpsy = cEpsy-cSgmy/cEu*ReductionFactor; + cSgmy = cEu*cEpsy+cSgme; + + cSgmb = cSgmy-cEsth*cEpsy; + + cEpsc = -(cSgmb-cSgmd2)/(cEsth-cEd2); + cSgmc = cEsth*cEpsc+cSgmb; + + cEpsd1 = cEpsc; + } + } else if (TempEps1 < cEpsc && cEpsd1 <= TempEps2) { + + cEpsy = -(cSgme-cSgmd)/(cEu-cEd1); + cSgmy = cEu*cEpsy+cSgme; + cEpsy = cEpsy-cSgmy/cEu*ReductionFactor; + cSgmy = cEu*cEpsy+cSgme; + + cSgmb = cSgmy-cEsth*cEpsy; + + double TempcEpsc1, TempcEpsc2; + TempcEpsc1 = -(cSgmb-cSgmd)/(cEsth-cEd1); + TempcEpsc2 = -(cSgmb-cSgmd2)/(cEsth-cEd2); + + if (TempcEpsc1 < TempcEpsc2) { + cEpsc = TempcEpsc1; + } else { + cEpsc = TempcEpsc2; + } + cSgmc = cEsth*cEpsc+cSgmb; + + } else if (TempEps2 < cEpsd1 && cEpsd2 <= TempEps3) { + + cEpsy = -(cSgme-cSgmd2)/(cEu-cEd2); + cSgmy = cEu*cEpsy+cSgme; + cEpsy = cEpsy-cSgmy/cEu*ReductionFactor; + cSgmy = cEu*cEpsy+cSgme; + + cSgmb = cSgmy-cEsth*cEpsy; + + cEpsc = -(cSgmb-cSgmd2)/(cEsth-cEd2); + cSgmc = cEsth*cEpsc+cSgmb; + + cEpsd1 = cEpsc; + } + + + if (nsgm > tSgmp) { + tEpsp = neps; + tSgmp = nsgm; + } + + +} + + +/******************************************************************************************** + *** post-buckling excursion in tension + ********************************************************************************************/ +void SLModel::BackBoneTenFunc(void) +{ + // local variables + double TempSgm, TempEps, TempSgm2, TempEps2, Err; + + //unloading slope + if (neps < tEpsp) { + tEu = E*(au/(au+tEpsp-neps)); + if (tEu > E) { + tEu = E; + } + } else { + tEu = E; + } + + //yield stress + + if (neps < tEpsp) { + TempSgm = sgm_ini*(ay/(ay+tEpsp-neps)); + if (TempSgm > sgm_ini*0.999999) { + TempSgm = sgm_ini*0.999999; + } + } else { + TempSgm = sgm_ini*0.999999; + } + + TempEps = neps+(TempSgm-nsgm)/tEu; + + for (int i=1;i<=20;i++) { + TempSgm2 = TempSgm; + TempEps2 = TempEps; + + if (TempEps2 < tEpsp) { + TempSgm = sgm_ini*(ay/(ay+tEpsp-neps)); + if (TempSgm > sgm_ini*0.999999) { + TempSgm = sgm_ini*0.999999; + } + } else { + TempSgm = sgm_ini*0.999999; + } + + TempEps = TempEps2+(TempSgm-TempSgm2)/tEu; + + tSgmy = TempSgm; + tEpsy = TempEps; + + Err = fabs(TempSgm-TempSgm2); + if (Err < 1.0e-5) { + break; + } + }; + + + //reloading slope + tEr = (tSgmp-tSgmy)/(tEpsp-tEpsy); + tEr2 = tEr*Alpha3; + tEpsp2 = tEpsy+(tSgmp-tSgmy)/tEr2; + + +} + +/******************************************************************************************** + *** Unloading in compression + ********************************************************************************************/ +void SLModel::BackBoneComp2Func(void) +{ + + // local variables + double cSgme; + double TempEps1, TempEps2, TempEps3; + int itemp; + double cEpsOffset; + + cEu = tEu; + + + + + // modification of yield stress when 2nd deterioration slope is higher than capping strength + + itemp = 0; + cEpsOffset = refEps; + + if (cEpsc < cEpsd1) { + cEpsy = -(E*cEpsOffset-cSgmd2)/(E-cEd2); + cSgmy = E*(cEpsy-cEpsOffset); + cEpsc = cEpsy; + cSgmc = cSgmy; + cEpsd1 = cEpsy; + cSgmd1 = cSgmy; + + itemp = 1; + } + + cSgme = nsgm-cEu*neps; + + // + TempEps1 = neps-(nsgm-cSgmc)/cEu; + TempEps2 = neps-(nsgm-cSgmd1)/cEu; + TempEps3 = neps-(nsgm)/cEu; + + double ReductionFactor; + ReductionFactor = 0.0;///////////////////////////////************************************************************************************************************************** + + if (cEpsc <= TempEps1) { + if (itemp == 0) { + cEpsy = -(cSgme-cSgmb)/(cEu-cEsth); + cSgmy = cEu*cEpsy+cSgme; + } else if (itemp == 1) { + cEpsy = -(cSgme-cSgmd2)/(cEu-cEd2); + cSgmy = cEu*cEpsy+cSgme; + + cEpsc = cEpsy; + cSgmc = cSgmy; + cEpsd1 = cEpsy; + cSgmd1 = cSgmy; + + + cEpsy = cEpsy-cSgmy/cEu*ReductionFactor; + cSgmy = cEu*cEpsy+cSgme; + + cSgmb = cSgmy-cEsth*cEpsy; + + cEpsc = -(cSgmb-cSgmd2)/(cEsth-cEd2); + cSgmc = cEsth*cEpsc+cSgmb; + + cEpsd1 = cEpsc; + } + } else if (TempEps1 < cEpsc && cEpsd1 <= TempEps2) { + + cEpsy = -(cSgme-cSgmd)/(cEu-cEd1); + cSgmy = cEu*cEpsy+cSgme; + cEpsy = cEpsy-cSgmy/cEu*ReductionFactor; + cSgmy = cEu*cEpsy+cSgme; + + cSgmb = cSgmy-cEsth*cEpsy; + + double TempcEpsc1, TempcEpsc2; + TempcEpsc1 = -(cSgmb-cSgmd)/(cEsth-cEd1); + TempcEpsc2 = -(cSgmb-cSgmd2)/(cEsth-cEd2); + + if (TempcEpsc1 < TempcEpsc2) { + cEpsc = TempcEpsc1; + } else { + cEpsc = TempcEpsc2; + } + cSgmc = cEsth*cEpsc+cSgmb; + + + } else if (TempEps2 < cEpsd1 && cEpsd2 <= TempEps3) { + + cEpsy = -(cSgme-cSgmd2)/(cEu-cEd2); + cSgmy = cEu*cEpsy+cSgme; + cEpsy = cEpsy-cSgmy/cEu*ReductionFactor; + cSgmy = cEu*cEpsy+cSgme; + + cSgmb = cSgmy-cEsth*cEpsy; + + cEpsc = -(cSgmb-cSgmd2)/(cEsth-cEd2); + cSgmc = cEsth*cEpsc+cSgmb; + + cEpsd1 = cEpsc; + } + + + if (nsgm > tSgmp) { + tEpsp = neps; + tSgmp = nsgm; + } + + +} + + + +/******************************************************************************************** + *** Unloading in tension + ********************************************************************************************/ +void SLModel::BackBoneTen2Func(void) +{ + // local variables + double tSgme, TemptSgmp; + + //unloading slope + tEu = cEu; + tSgme = nsgm-tEu*neps; + + //yield stress + + TemptSgmp = tSgmp-tEpsp2*tEr2; + tEpsy = -(tSgme-TemptSgmp)/(tEu-tEr2); + tSgmy = tEu*tEpsy+tSgme; + + +} + + + diff --git a/SRC/material/uniaxial/SLModel.h b/SRC/material/uniaxial/SLModel.h new file mode 100755 index 0000000000..4efa27b6cd --- /dev/null +++ b/SRC/material/uniaxial/SLModel.h @@ -0,0 +1,189 @@ +#ifndef SLModel_h +#define SLModel_h + +#include + +class SLModel : public UniaxialMaterial +{ +public: + SLModel(int tag, double Dt, double sgm_ini, double OP_Material); + SLModel(); + ~SLModel(); + + + const char *getClassType(void) const {return "SLModel";}; + + int setTrialStrain(double strain, double strainRate = 0.0); + double getStrain(void); + double getStress(void); + double getTangent(void); + + double getInitialTangent(void) {return E;}; + + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + UniaxialMaterial *getCopy(void); + + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + + void Print(OPS_Stream &s, int flag =0); + + // functions + void StrainHardeningFunc(void); + void YieldPointFunc(void); + void BackBoneCompFunc(void); + void BackBoneTenFunc(void); + void BackBoneComp2Func(void); + void BackBoneTen2Func(void); + + + +protected: + +private: + + + //////////////////////////////////////////////////////// + double Dt, sgm_ini; + double OP_Material; + double E, Dteq; + double c, gamma, q, beta; + double CapYieldStressM, CapYieldStrainM, Ed1EM, Ed2EM, DetCapStressM; + + double status; + + double p_teps, p_neps, p_teps_prev, p_neps_prev; + double cum_p_teps; + double sgm_0, alf_d, alf; + double ytsgm_p, ytsgm_n, yteps_p, yteps_n; + + double teps, neps, tsgm, nsgm; + double teps_prev, neps_prev, tsgm_prev, nsgm_prev; + + double cEu, cSgmy, cEpsy, cSgmc, cEpsc, cSgmd1, cEpsd1, cSgmd2, cEpsd2, cSgmb, cSgmd, cEsth, cEd1, cEd2; + double cIniSgmy, cIniEpsy, cIniSgmc, cIniEpsc, cIniEsth, cIniEd1, cIniEd2, cIniSgmd1, cIniEpsd1, cIniSgmb, cIniSgmd, cIniSgmd2, cIniEpsd2; + double tEu, tSgmy, tEpsy, tSgmp, tEpsp, tEpsp2, tEr, tEr2, refEps; + + double ay, au; + double Lambda1, c1, Lambda2, c2, Lambda3, c3; + double Et1, Et2, Et3; + double Beta1, Beta2, Beta3; + double Alpha1, Alpha2, Alpha3; + double TotalE, DeltaE; + + double Tangent; + double iInitial; + + + + //////////////////////////////////////////////////////// + double C_Dt, C_sgm_ini; + double C_OP_Material; + double C_E, C_Dteq; + double C_c, C_gamma, C_q, C_beta; + double C_CapYieldStressM, C_CapYieldStrainM, C_Ed1EM, C_Ed2EM, C_DetCapStressM; + + double C_status; + + double C_p_teps, C_p_neps, C_p_teps_prev, C_p_neps_prev; + double C_cum_p_teps; + double C_sgm_0, C_alf_d, C_alf; + double C_ytsgm_p, C_ytsgm_n, C_yteps_p, C_yteps_n; + + double C_teps, C_neps, C_tsgm, C_nsgm; + double C_teps_prev, C_neps_prev, C_tsgm_prev, C_nsgm_prev; + + double C_cEu, C_cSgmy, C_cEpsy, C_cSgmc, C_cEpsc, C_cSgmd1, C_cEpsd1, C_cSgmd2, C_cEpsd2, C_cSgmb, C_cSgmd, C_cEsth, C_cEd1, C_cEd2; + double C_cIniSgmy, C_cIniEpsy, C_cIniSgmc, C_cIniEpsc, C_cIniEsth, C_cIniEd1, C_cIniEd2, C_cIniSgmd1, C_cIniEpsd1, C_cIniSgmb, C_cIniSgmd, C_cIniSgmd2, C_cIniEpsd2; + double C_tEu, C_tSgmy, C_tEpsy, C_tSgmp, C_tEpsp, C_tEpsp2, C_tEr, C_tEr2, C_refEps; + + double C_ay, C_au; + double C_Lambda1, C_c1, C_Lambda2, C_c2, C_Lambda3, C_c3; + double C_Et1, C_Et2, C_Et3; + double C_Beta1, C_Beta2, C_Beta3; + double C_Alpha1, C_Alpha2, C_Alpha3; + double C_TotalE, C_DeltaE; + + double C_Tangent; + double C_iInitial; + +}; + + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp b/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp index e1efa0a65a..8ac79414cc 100644 --- a/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp +++ b/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp @@ -62,6 +62,7 @@ #include //Quan & Michele #include //Quan & Michele #include //JAE +#include //LA #include #include @@ -136,7 +137,8 @@ extern void *OPS_StainlessECThermal(void); // L.Jiang [SIF] extern void *OPS_SteelECThermal(void); // L.Jiang [SIF] extern void *OPS_ConcreteECThermal(void);// L.Jiang [SIF] extern void *OPS_ElasticMaterialThermal(void); //L.Jiang[SIF] - +//extern void *OPS_PlateBearingConnectionThermal(void); +extern void* OPS_ASD_SMA_3K(void); // Luca Aceto extern void *OPS_BWBN(void); extern void *OPS_IMKPeakOriented(void); extern void *OPS_IMKBilin(void); @@ -167,6 +169,7 @@ extern void *OPS_OOHystereticMaterial(void); extern void *OPS_ElasticPowerFunc(void); extern void *OPS_UVCuniaxial(void); extern void *OPS_DegradingPinchedBW(void); +extern void *OPS_SLModel(void); //extern int TclCommand_ConfinedConcrete02(ClientData clientData, Tcl_Interp *interp, int argc, // TCL_Char **argv, TclModelBuilder *theTclBuilder); @@ -179,14 +182,6 @@ extern UniaxialMaterial *Tcl_addWrapperUniaxialMaterial(matObj *, ClientData cli #include -extern int OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain); - - typedef struct uniaxialPackageCommand { char *funcName; void * (*funcPtr)(); @@ -513,6 +508,13 @@ TclModelBuilderUniaxialMaterialCommand (ClientData clientData, Tcl_Interp *inter else return TCL_ERROR; } + else if (strcmp(argv[1], "SLModel") == 0) { + void *theMat = OPS_SLModel(); + if (theMat != 0) + theMaterial = (UniaxialMaterial *)theMat; + else + return TCL_ERROR; + } else if ((strcmp(argv[1],"RambergOsgood") == 0) || (strcmp(argv[1],"RambergOsgoodSteel") == 0)) { void *theMat = OPS_RambergOsgoodSteel(); if (theMat != 0) @@ -678,12 +680,20 @@ TclModelBuilderUniaxialMaterialCommand (ClientData clientData, Tcl_Interp *inter else return TCL_ERROR; + } else if (strcmp(argv[1],"PlateBearingConnectionThermal") == 0) { + //void *theMat = OPS_PlateBearingConnectionThermal(); + void *theMat = 0; + if (theMat != 0) + theMaterial = (UniaxialMaterial *)theMat; + else + return TCL_ERROR; + } else if (strcmp(argv[1],"Steel01Thermal") == 0) { void *theMat = OPS_Steel01Thermal(); if (theMat != 0) theMaterial = (UniaxialMaterial *)theMat; else - return TCL_ERROR; + return TCL_ERROR; } else if (strcmp(argv[1],"Steel02Thermal") == 0) { void *theMat = OPS_Steel02Thermal(); @@ -2588,6 +2598,15 @@ TclModelBuilderUniaxialMaterialCommand (ClientData clientData, Tcl_Interp *inter } + else if (strcmp(argv[1], "ASD_SMA_3K") == 0) { + void *theMat = OPS_ASD_SMA_3K(); + if (theMat != 0) + theMaterial = (UniaxialMaterial *)theMat; + else + return TCL_ERROR; + } + + else if (strcmp(argv[1],"SelfCentering") == 0) { if (argc < 7) { opserr << "WARNING insufficient arguments\n"; diff --git a/SRC/material/uniaxial/TensionOnlyMaterial.cpp b/SRC/material/uniaxial/TensionOnlyMaterial.cpp index 386b01d91d..d1f12abaf3 100644 --- a/SRC/material/uniaxial/TensionOnlyMaterial.cpp +++ b/SRC/material/uniaxial/TensionOnlyMaterial.cpp @@ -193,8 +193,12 @@ TensionOnlyMaterial::getStrainRate(void) int TensionOnlyMaterial::commitState(void) -{ - return theMaterial->commitState(); +{ + double f = theMaterial->getStress(); + if (f >= 0.0) + return theMaterial->commitState(); + else + return 0; } int @@ -337,3 +341,52 @@ TensionOnlyMaterial::updateParameter(int parameterID, Information &info) { return 0; } + +double +TensionOnlyMaterial::getStressSensitivity(int gradIndex, bool conditional) +{ + double f = theMaterial->getStress(); + if (f < 0.0) + return 0.0; + else + return theMaterial->getStressSensitivity(gradIndex, conditional); +} + +double +TensionOnlyMaterial::getStrainSensitivity(int gradIndex) +{ + return theMaterial->getStrainSensitivity(gradIndex); +} + +double +TensionOnlyMaterial::getInitialTangentSensitivity(int gradIndex) +{ + return theMaterial->getInitialTangentSensitivity(gradIndex); +} + +double +TensionOnlyMaterial::getDampTangentSensitivity(int gradIndex) +{ + double f = theMaterial->getStress(); + if (f < 0.0) + return 0.0; + else + return theMaterial->getDampTangentSensitivity(gradIndex); +} + +double +TensionOnlyMaterial::getRhoSensitivity(int gradIndex) +{ + return theMaterial->getRhoSensitivity(gradIndex); +} + +int +TensionOnlyMaterial::commitSensitivity(double strainGradient, + int gradIndex, int numGrads) +{ + double f = theMaterial->getStress(); + if (f >= 0.0) + return theMaterial->commitSensitivity(strainGradient, gradIndex, numGrads); + else + return 0; +} diff --git a/SRC/material/uniaxial/TensionOnlyMaterial.h b/SRC/material/uniaxial/TensionOnlyMaterial.h index 13f2758d41..f9c771895a 100644 --- a/SRC/material/uniaxial/TensionOnlyMaterial.h +++ b/SRC/material/uniaxial/TensionOnlyMaterial.h @@ -66,6 +66,15 @@ class TensionOnlyMaterial : public UniaxialMaterial int setParameter(const char **argv, int argc, Parameter ¶m); int updateParameter(int parameterID, Information &info); + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + double getStressSensitivity (int gradIndex, bool conditional); + double getStrainSensitivity (int gradIndex); + double getInitialTangentSensitivity(int gradIndex); + double getDampTangentSensitivity(int gradIndex); + double getRhoSensitivity (int gradIndex); + int commitSensitivity (double strainGradient, int gradIndex, int numGrads); + // AddingSensitivity:END /////////////////////////////////////////// protected: diff --git a/SRC/material/uniaxial/backbone/TclModelBuilderBackboneCommand.cpp b/SRC/material/uniaxial/backbone/TclModelBuilderBackboneCommand.cpp index 25fadd525f..1f3f639772 100644 --- a/SRC/material/uniaxial/backbone/TclModelBuilderBackboneCommand.cpp +++ b/SRC/material/uniaxial/backbone/TclModelBuilderBackboneCommand.cpp @@ -56,13 +56,6 @@ extern void *OPS_MultilinearBackbone(void); #include -extern int OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain); - static void printCommand(int argc, TCL_Char **argv) { opserr << "Input command: "; diff --git a/SRC/material/uniaxial/limitState/LimitStateMaterial.cpp b/SRC/material/uniaxial/limitState/LimitStateMaterial.cpp index 2c61ecce96..17eb4c8bd7 100644 --- a/SRC/material/uniaxial/limitState/LimitStateMaterial.cpp +++ b/SRC/material/uniaxial/limitState/LimitStateMaterial.cpp @@ -43,6 +43,7 @@ // All code specific to LimitStateMaterial separated by //////////////// #include +#include "LimitCurve.h" #include #include diff --git a/SRC/material/uniaxial/limitState/LimitStateMaterial.h b/SRC/material/uniaxial/limitState/LimitStateMaterial.h index ec9e21ae31..e12ab0ec81 100644 --- a/SRC/material/uniaxial/limitState/LimitStateMaterial.h +++ b/SRC/material/uniaxial/limitState/LimitStateMaterial.h @@ -42,7 +42,7 @@ #define LimitStateMaterial_h #include -#include +class LimitCurve; class LimitStateMaterial : public UniaxialMaterial diff --git a/SRC/material/uniaxial/limitState/TclLimitState.cpp b/SRC/material/uniaxial/limitState/TclLimitState.cpp index d8badb28e7..aed1ad5481 100644 --- a/SRC/material/uniaxial/limitState/TclLimitState.cpp +++ b/SRC/material/uniaxial/limitState/TclLimitState.cpp @@ -53,13 +53,6 @@ static void printCommand(int argc, TCL_Char **argv) //Package Commands extern LimitCurve *Tcl_addWrapperLimitCurve(limCrvObj *, ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); -extern int OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain); - typedef struct limitCurvePackageCommand { char *funcName; void * (*funcPtr)(int argc, TCL_Char **argv); diff --git a/SRC/material/uniaxial/stiffness/TclModelBuilderStiffnessDegradationCommand.cpp b/SRC/material/uniaxial/stiffness/TclModelBuilderStiffnessDegradationCommand.cpp index 2868a6c279..5599bac5a9 100644 --- a/SRC/material/uniaxial/stiffness/TclModelBuilderStiffnessDegradationCommand.cpp +++ b/SRC/material/uniaxial/stiffness/TclModelBuilderStiffnessDegradationCommand.cpp @@ -43,15 +43,9 @@ extern void *OPS_EnergyStiffnessDegradation(void); extern void *OPS_ConstantStiffnessDegradation(void); extern void *OPS_PincheiraStiffnessDegradation(void); +#include #include -extern int OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain); - int TclModelBuilderStiffnessDegradationCommand(ClientData clientData, Tcl_Interp *interp, diff --git a/SRC/material/uniaxial/strength/TclModelBuilderStrengthDegradationCommand.cpp b/SRC/material/uniaxial/strength/TclModelBuilderStrengthDegradationCommand.cpp index 7ed9633f57..e58d8c868c 100644 --- a/SRC/material/uniaxial/strength/TclModelBuilderStrengthDegradationCommand.cpp +++ b/SRC/material/uniaxial/strength/TclModelBuilderStrengthDegradationCommand.cpp @@ -47,15 +47,9 @@ extern void *OPS_ConstantStrengthDegradation(void); extern void *OPS_ACIStrengthDegradation(void); extern void *OPS_PetrangeliStrengthDegradation(void); +#include #include -extern int OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain); - static void printCommand(int argc, TCL_Char **argv) { opserr << "Input command: "; diff --git a/SRC/material/uniaxial/unloading/TclModelBuilderUnloadingRuleCommand.cpp b/SRC/material/uniaxial/unloading/TclModelBuilderUnloadingRuleCommand.cpp index c781bd26a2..37bfb08092 100644 --- a/SRC/material/uniaxial/unloading/TclModelBuilderUnloadingRuleCommand.cpp +++ b/SRC/material/uniaxial/unloading/TclModelBuilderUnloadingRuleCommand.cpp @@ -30,9 +30,6 @@ #include -#include -#include - #include #include #include @@ -44,15 +41,9 @@ extern void *OPS_EnergyUnloadingRule(void); extern void *OPS_ConstantUnloadingRule(void); extern void *OPS_KarsanUnloadingRule(void); +#include #include -extern int OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain); - int TclModelBuilderUnloadingRuleCommand(ClientData clientData, Tcl_Interp *interp, diff --git a/SRC/matrix/ID.cpp b/SRC/matrix/ID.cpp index 75b3e25c8f..04225c4819 100644 --- a/SRC/matrix/ID.cpp +++ b/SRC/matrix/ID.cpp @@ -363,7 +363,7 @@ ID::operator[](int x) int -ID::resize(int newSize){ +ID::resize(int newSize, int fill_value){ // first check that newSize is valid if (newSize <= 0) { @@ -383,7 +383,7 @@ ID::resize(int newSize){ // without having to go get more space for (int i=sz; i arraySize) { @@ -397,7 +397,7 @@ ID::resize(int newSize){ newData[i] = data[i]; // zero the new for (int j=sz; jdata; } void Print() { diff --git a/SRC/matrix/Matrix.cpp b/SRC/matrix/Matrix.cpp index 815b01ac49..c4ca9cd005 100644 --- a/SRC/matrix/Matrix.cpp +++ b/SRC/matrix/Matrix.cpp @@ -188,12 +188,13 @@ Matrix::Matrix(const Matrix &other) // Move ctor #ifdef USE_CXX11 Matrix::Matrix(Matrix &&other) -:numRows(other.numRows), numCols(other.numCols), dataSize(other.dataSize), data(other.data), fromFree(0) +:numRows(other.numRows), numCols(other.numCols), dataSize(other.dataSize), data(other.data), fromFree(other.fromFree) { other.numRows = 0; other.numCols = 0; other.dataSize = 0; other.data = 0; + other.fromFree = 1; } #endif @@ -203,9 +204,12 @@ Matrix::Matrix(Matrix &&other) Matrix::~Matrix() { - if (data != 0) - if (fromFree == 0) + if (data != 0 ) { + if (fromFree == 0 && dataSize > 0){ delete [] data; + data = 0; + } + } // if (data != 0) free((void *) data); } @@ -220,8 +224,10 @@ Matrix::setData(double *theData, int row, int col) // delete the old if allocated if (data != 0) if (fromFree == 0) + { delete [] data; - + data = 0; + } numRows = row; numCols = col; dataSize = row*col; @@ -269,8 +275,10 @@ Matrix::resize(int rows, int cols) { // free the old space if (data != 0) - if (fromFree == 0) + if (fromFree == 0){ delete [] data; + data = 0; + } // if (data != 0) free((void *) data); fromFree = 0; @@ -389,6 +397,7 @@ Matrix::Solve(const Vector &b, Vector &x) const if (matrixWork != 0) { delete [] matrixWork; + matrixWork = 0; } matrixWork = new (nothrow) double[dataSize]; sizeDoubleWork = dataSize; @@ -405,6 +414,7 @@ Matrix::Solve(const Vector &b, Vector &x) const if (intWork != 0) { delete [] intWork; + intWork = 0; } intWork = new (nothrow) int[n]; sizeIntWork = n; @@ -484,6 +494,7 @@ Matrix::Solve(const Matrix &b, Matrix &x) const if (matrixWork != 0) { delete [] matrixWork; + matrixWork = 0; } matrixWork = new (nothrow) double[dataSize]; sizeDoubleWork = dataSize; @@ -500,6 +511,7 @@ Matrix::Solve(const Matrix &b, Matrix &x) const if (intWork != 0) { delete [] intWork; + intWork = 0; } intWork = new (nothrow) int[n]; sizeIntWork = n; @@ -583,6 +595,7 @@ Matrix::Invert(Matrix &theInverse) const if (matrixWork != 0) { delete [] matrixWork; + matrixWork = 0; } matrixWork = new (nothrow) double[dataSize]; sizeDoubleWork = dataSize; @@ -599,6 +612,7 @@ Matrix::Invert(Matrix &theInverse) const if (intWork != 0) { delete [] intWork; + intWork = 0; } intWork = new (nothrow) int[n]; sizeIntWork = n; @@ -1187,7 +1201,10 @@ Matrix::operator=(const Matrix &other) #endif if (this->data != 0) + { delete [] this->data; + this->data = 0; + } int theSize = other.numCols*other.numRows; @@ -1220,17 +1237,21 @@ Matrix::operator=( Matrix &&other) return *this; - if (this->data != 0) + if (this->data != 0 && fromFree == 0){ delete [] this->data; + this->data = 0; + } - data = other.data; + this->data = other.data; this->dataSize = other.numCols*other.numRows; this->numCols = other.numCols; this->numRows = other.numRows; + this->fromFree = other.fromFree; other.data = 0; other.dataSize = 0; other.numCols = 0; other.numRows = 0; + other.fromFree = 1; return *this; } @@ -1989,3 +2010,24 @@ Matrix::Eigen3(const Matrix &M) return 0; } + + + +Vector Matrix::diagonal() const +{ + + if (numRows != numCols) + { + opserr << "Matrix::diagonal() - Matrix is not square numRows = " << numRows << " numCols = " << numCols << " returning truncated diagonal." << endln; + } + + int size = numRows < numCols ? numRows : numCols; + Vector diagonal(size); + + for (int i = 0; i < size; ++i) + { + diagonal(i) = data[i*numRows + i]; + } + + return diagonal; +} diff --git a/SRC/matrix/Matrix.h b/SRC/matrix/Matrix.h index f9c49ab0d9..5776b4f1cd 100644 --- a/SRC/matrix/Matrix.h +++ b/SRC/matrix/Matrix.h @@ -64,6 +64,7 @@ class Matrix inline int noCols() const; void Zero(void); int resize(int numRow, int numCol); + Vector diagonal() const; int Assemble(const Matrix &,const ID &rows, const ID &cols, double fact = 1.0); diff --git a/SRC/matrix/Vector.cpp b/SRC/matrix/Vector.cpp index 010a0c3fd5..9509e27a0c 100644 --- a/SRC/matrix/Vector.cpp +++ b/SRC/matrix/Vector.cpp @@ -137,13 +137,16 @@ Vector::~Vector() { if (theData != 0 && fromFree == 0) delete [] theData; + theData = 0; } int Vector::setData(double *newData, int size){ - if (theData != 0 && fromFree == 0) + if (theData != 0 && fromFree == 0) { delete [] theData; + theData = 0; + } sz = size; theData = newData; fromFree = 1; @@ -171,8 +174,10 @@ Vector::resize(int newSize){ else if (newSize > sz) { // delete the old array - if (theData != 0 && fromFree == 0) + if (theData != 0 && fromFree == 0) { delete [] theData; + theData = 0; +} sz = 0; fromFree = 0; @@ -651,9 +656,10 @@ Vector::operator[](int x) dataNew[j] = 0.0; if (fromFree == 0) - if (theData != 0) + if (theData != 0){ delete [] theData; - + theData = 0; +} theData = dataNew; sz = x+1; } @@ -732,8 +738,10 @@ Vector::operator=(const Vector &V) #endif // Check that we are not deleting an empty Vector - if (this->theData != 0) delete [] this->theData; - + if (this->theData != 0){ + delete [] this->theData; + this->theData = 0; + } this->sz = V.sz; // Check that we are not creating an empty Vector @@ -757,7 +765,10 @@ Vector::operator=(Vector &&V) // first check we are not trying v = v if (this != &V) { // opserr << "move assign!\n"; - if (this->theData != 0) delete [] this->theData; + if (this->theData != 0){ + delete [] this->theData; + this->theData = 0; + } theData = V.theData; this->sz = V.sz; V.theData = 0; diff --git a/SRC/modelbuilder/tcl/TclModelBuilder.cpp b/SRC/modelbuilder/tcl/TclModelBuilder.cpp index 6d82ef2674..5eb993d3e2 100644 --- a/SRC/modelbuilder/tcl/TclModelBuilder.cpp +++ b/SRC/modelbuilder/tcl/TclModelBuilder.cpp @@ -2277,8 +2277,7 @@ TclCommand_addElementalLoad(ClientData clientData, Tcl_Interp *interp, int argc, //(2) 5 temperature points, i.e. 4 layers //(3) 2 temperature points, i.e. 1 layers: linear or uniform - double t1, locY1, t2, locY2, t3, locY3, t4, locY4, t5, locY5, - t6, locY6, t7, locY7, t8, locY8, t9, locY9; + double t1, locY1, t2, locY2; //t3, locY3, t4, locY4, t5, locY5, t6, locY6, t7, locY7, t8, locY8, t9, locY9; // 9 temperature points are given,i.e. 8 layers are defined; Also the 9 corresponding vertical coordinate is given. // the temperature at each fiber is obtained by interpolating of temperatures at the nearby temperature points. //Start to add source file @@ -4218,9 +4217,9 @@ TclCommand_doBlock2D(ClientData clientData, Tcl_Interp *interp, int argc, // int numNodes = nodeTags.Size(); // assumes 15 is largest string for individual nodeTags - count = 10 + strlen(eleType) + strlen(additionalEleArgs) + 15 * (numNodes+1); + count = int(10 + strlen(eleType) + strlen(additionalEleArgs) + 15 * (numNodes+1)); char *eleCommand = new char[count]; - int initialCount = 8 + strlen(eleType); + int initialCount = int(8 + strlen(eleType)); int eleID = startEleNum; if (numNodes == 9) { @@ -4388,9 +4387,9 @@ TclCommand_doBlock3D(ClientData clientData, Tcl_Interp *interp, int argc, int numNodes = nodeTags.Size(); // assumes 15 is largest string for individual nodeTags - count = 10 + strlen(eleType) + strlen(additionalEleArgs) + 15 * (numNodes+1); + count = int(10 + strlen(eleType) + strlen(additionalEleArgs) + 15 * (numNodes+1)); char *eleCommand = new char[count]; - int initialCount = 8 + strlen(eleType); + int initialCount = int(8 + strlen(eleType)); int eleID = startEleNum; for (kk=0; kk -#include +#include "equiSolnAlgo/EquiSolnAlgo.h" #include #include #include diff --git a/SRC/recorder/ElementRecorderRMS.cpp b/SRC/recorder/ElementRecorderRMS.cpp new file mode 100644 index 0000000000..09a4a88904 --- /dev/null +++ b/SRC/recorder/ElementRecorderRMS.cpp @@ -0,0 +1,935 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// Written: fmk +// +// Description: This file contains the class implementatation of +// EnvelopeElementRecorderRMS. +// +// What: "@(#) EnvelopeElementRecorderRMS.C, revA" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +void* +OPS_ElementRecorderRMS() +{ + if (OPS_GetNumRemainingInputArgs() < 5) { + opserr << "WARING: recorder Element "; + opserr << "-ele -file -dT
reponse"; + return 0; + } + + const char** data = 0; + int nargrem = 0; + OPS_Stream *theOutputStream = 0; + const char* filename = 0; + + const int STANDARD_STREAM = 0; + const int DATA_STREAM = 1; + const int XML_STREAM = 2; + const int DATABASE_STREAM = 3; + const int BINARY_STREAM = 4; + const int DATA_STREAM_CSV = 5; + const int TCP_STREAM = 6; + const int DATA_STREAM_ADD = 7; + + int eMode = STANDARD_STREAM; + + bool echoTimeFlag = false; + double dT = 0.0; + bool doScientific = false; + + int precision = 6; + + bool closeOnWrite = false; + + const char *inetAddr = 0; + int inetPort; + + ID elements(0, 6); + ID dofs(0, 6); + + while (OPS_GetNumRemainingInputArgs() > 0) { + + const char* option = OPS_GetString(); + + if (strcmp(option, "-time") == 0) { + echoTimeFlag = true; + } + else if (strcmp(option, "-load") == 0) { + echoTimeFlag = true; + } + else if (strcmp(option, "-scientific") == 0) { + doScientific = true; + } + else if (strcmp(option, "-file") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + filename = OPS_GetString(); + } + eMode = DATA_STREAM; + } + else if (strcmp(option, "-fileAdd") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + filename = OPS_GetString(); + } + eMode = DATA_STREAM_ADD; + } + else if (strcmp(option, "-closeOnWrite") == 0) { + closeOnWrite = true; + } + else if (strcmp(option, "-csv") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + filename = OPS_GetString(); + } + eMode = DATA_STREAM_CSV; + } + else if (strcmp(option, "-tcp") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + inetAddr = OPS_GetString(); + } + if (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + if (OPS_GetIntInput(&num, &inetPort) < 0) { + opserr << "WARNING: failed to read inetPort\n"; + return 0; + } + } + eMode = TCP_STREAM; + } + else if (strcmp(option, "-xml") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + filename = OPS_GetString(); + } + eMode = XML_STREAM; + } + else if (strcmp(option, "-binary") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + filename = OPS_GetString(); + } + eMode = BINARY_STREAM; + } + else if (strcmp(option, "-dT") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + if (OPS_GetDoubleInput(&num, &dT) < 0) { + opserr << "WARNING: failed to read dT\n"; + return 0; + } + } + } + else if (strcmp(option, "-precision") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + if (OPS_GetIntInput(&num, &precision) < 0) { + opserr << "WARNING: failed to read precision\n"; + return 0; + } + } + } + else if (strcmp(option, "-ele") == 0) { + int numEle = 0; + while (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + int el; + if (OPS_GetIntInput(&num, &el) < 0) { + break; + } + elements[numEle++] = el; + } + } + else if (strcmp(option, "-eleRange") == 0) { + int start, end; + if (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + if (OPS_GetIntInput(&num, &start) < 0) { + opserr << "WARNING: failed to read start element\n"; + return 0; + } + } + if (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + if (OPS_GetIntInput(&num, &end) < 0) { + opserr << "WARNING: failed to read end element\n"; + return 0; + } + } + if (start > end) { + int swap = end; + end = start; + start = swap; + } + int numEle = 0; + for (int i = start; i <= end; i++) + elements[numEle++] = i; + } + else if (strcmp(option, "-region") == 0) { + int tag; + if (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + if (OPS_GetIntInput(&num, &tag) < 0) { + opserr << "WARNING: failed to read region tag\n"; + return 0; + } + } + Domain *domain = OPS_GetDomain(); + MeshRegion *theRegion = domain->getRegion(tag); + if (theRegion == 0) { + opserr << "WARNING: region does not exist\n"; + return 0; + } + const ID &eleRegion = theRegion->getElements(); + int numEle = 0; + for (int i = 0; i < eleRegion.Size(); i++) + elements[numEle++] = eleRegion(i); + } + else if (strcmp(option, "-dof") == 0) { + int numDOF = 0; + while (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + int dof; + if (OPS_GetIntInput(&num, &dof) < 0) { + OPS_ResetCurrentInputArg(-1); + break; + } + dofs[numDOF++] = dof - 1; + } + } + else { + // first unknown string then is assumed to start + // element response request + nargrem = 1 + OPS_GetNumRemainingInputArgs(); + data = new const char *[nargrem]; + data[0] = option; + for (int i = 1; i < nargrem; i++) + data[i] = OPS_GetString(); + } + } + + // data handler + if (eMode == DATA_STREAM && filename != 0) + theOutputStream = new DataFileStream(filename, OVERWRITE, 2, 0, closeOnWrite, precision, doScientific); + else if (eMode == DATA_STREAM_ADD && filename != 0) + theOutputStream = new DataFileStreamAdd(filename, OVERWRITE, 2, 0, closeOnWrite, precision, doScientific); + else if (eMode == DATA_STREAM_CSV && filename != 0) + theOutputStream = new DataFileStream(filename, OVERWRITE, 2, 1, closeOnWrite, precision, doScientific); + else if (eMode == XML_STREAM && filename != 0) + theOutputStream = new XmlFileStream(filename); + //else if (eMode == DATABASE_STREAM && tableName != 0) + // theOutputStream = new DatabaseStream(theDatabase, tableName); + else if (eMode == BINARY_STREAM && filename != 0) + theOutputStream = new BinaryFileStream(filename); + else if (eMode == TCP_STREAM && inetAddr != 0) + theOutputStream = new TCP_Stream(inetPort, inetAddr); + else + theOutputStream = new StandardStream(); + + theOutputStream->setPrecision(precision); + + Domain* domain = OPS_GetDomain(); + if (domain == 0) + return 0; + ElementRecorderRMS* recorder = new ElementRecorderRMS(&elements, + data, nargrem, *domain, *theOutputStream, dT, &dofs); + + return recorder; +} + + +ElementRecorderRMS::ElementRecorderRMS() +:Recorder(RECORDER_TAGS_ElementRecorderRMS), + numEle(0), numDOF(0), eleID(0), dof(0), theResponses(0), theDomain(0), + theHandler(0), deltaT(0), nextTimeStampToRecord(0.0), + runningTotal(0), currentData(0), count(0), + initializationDone(false), responseArgs(0), numArgs(0), addColumnInfo(0) +{ + +} + + +ElementRecorderRMS::ElementRecorderRMS(const ID *ele, + const char **argv, + int argc, + Domain &theDom, + OPS_Stream &theOutputHandler, + double dT, + const ID *indexValues) + :Recorder(RECORDER_TAGS_ElementRecorderRMS), + numEle(0), eleID(0), numDOF(0), dof(0), theResponses(0), theDomain(&theDom), + theHandler(&theOutputHandler), deltaT(dT), nextTimeStampToRecord(0.0), + runningTotal(0), currentData(0), count(0), + initializationDone(false), responseArgs(0), numArgs(0), addColumnInfo(0) +{ + opserr << "ElementRMS:: constructor\n"; + + if (ele != 0) { + numEle = ele->Size(); + eleID = new ID(*ele); + if (eleID == 0 || eleID->Size() != numEle) + opserr << "ElementRecorder::ElementRecorder() - out of memory\n"; + } + + if (indexValues != 0) { + dof = new ID(*indexValues); + numDOF = dof->Size(); + } + + // + // create a copy of the response request + // + + responseArgs = new char *[argc]; + if (responseArgs == 0) { + opserr << "ElementRecorder::ElementRecorder() - out of memory\n"; + numEle = 0; + } + + for (int i=0; itag("Data"); // Data + + if (runningTotal != 0) { + + opserr << "ElementRMS DESTRUCTOR - runin\n" << runningTotal->Size() << "\n"; + + for (int j=0; jSize(); j++) + if (count != 0) { + double value = (*runningTotal)(j); + (*runningTotal)(j) = sqrt(value/(count)); + } + theHandler->write(*runningTotal); + } + + theHandler->endTag(); // Data + } + + if (theHandler != 0) + delete theHandler; + + if (runningTotal != 0) + delete runningTotal; + + if (currentData != 0) + delete currentData; + + // + // clean up the memory + // + + if (theResponses != 0) { + for (int i = 0; i < numEle; i++) + if (theResponses[i] != 0) + delete theResponses[i]; + + delete [] theResponses; + } + + + + // + // invoke destructor on response args + // + + for (int i=0; iinitialize() != 0) { + opserr << "ElementRecorder::record() - failed to initialize\n"; + return -1; + } + } + + int result = 0; + if (deltaT == 0.0 || timeStamp >= nextTimeStampToRecord) { + + if (deltaT != 0.0) + nextTimeStampToRecord = timeStamp + deltaT; + + int loc = 0; + // for each element do a getResponse() & put the result in current data + for (int i=0; i< numEle; i++) { + if (theResponses[i] != 0) { + // ask the element for the reponse + int res; + if (( res = theResponses[i]->getResponse()) < 0) + result += res; + else { + // from the response determine no of cols for each + Information &eleInfo = theResponses[i]->getInformation(); + const Vector &eleData = eleInfo.getData(); + // for (int j=0; j= 0 && index < dataSize) + (*currentData)(loc++) = eleData(index); + else + (*currentData)(loc++) = 0.0; + } + } + } + } + } + + // add data contribution to runningTotal + count++; + int sizeData = currentData->Size(); + for (int i=0; iZero(); + count = 0; + return 0; +} + +int +ElementRecorderRMS::setDomain(Domain &theDom) +{ + theDomain = &theDom; + return 0; +} + +int +ElementRecorderRMS::sendSelf(int commitTag, Channel &theChannel) +{ + addColumnInfo = 1; + + if (theChannel.isDatastore() == 1) { + opserr << "ElementRecorderRMS::sendSelf() - does not send data to a datastore\n"; + return -1; + } + initializationDone = false; + // + // into an ID, place & send eleID size, numArgs and length of all responseArgs + // + + static ID idData(7); + if (eleID != 0) + idData(0) = eleID->Size(); + else + idData(0) = 0; + + idData(1) = numArgs; + + idData(5) = this->getTag(); + idData(6) = numDOF; + + int msgLength = 0; + for (int i=0; igetClassTag(); + } else + idData(3) = 0; + + + if (theChannel.sendID(0, commitTag, idData) < 0) { + opserr << "ElementRecorderRMS::sendSelf() - failed to send idData\n"; + return -1; + } + + static Vector dData(1); + dData(1) = deltaT; + if (theChannel.sendVector(0, commitTag, dData) < 0) { + opserr << "ElementRecorderRMS::sendSelf() - failed to send dData\n"; + return -1; + } + + + // + // send the eleID + // + + if (eleID != 0) + if (theChannel.sendID(0, commitTag, *eleID) < 0) { + opserr << "ElementRecorderRMS::sendSelf() - failed to send idData\n"; + return -1; + } + + // send dof + if (dof != 0) + if (theChannel.sendID(0, commitTag, *dof) < 0) { + opserr << "ElementRecorder::sendSelf() - failed to send dof\n"; + return -1; + } + + // + // create a single char array holding all strings + // will use string terminating character to differentiate strings on other side + // + + if (msgLength == 0) { + opserr << "ElementRecorderRMS::sendSelf() - no data to send!!\n"; + return -1; + } + + char *allResponseArgs = new char[msgLength]; + if (allResponseArgs == 0) { + opserr << "ElementRecorderRMS::sendSelf() - out of memory\n"; + return -1; + } + + char *currentLoc = allResponseArgs; + for (int j=0; jsendSelf(commitTag, theChannel) < 0) { + opserr << "ElementRecorderRMS::sendSelf() - failed to send the DataOutputHandler\n"; + return -1; + } + + // + // clean up & return success + // + + delete [] allResponseArgs; + return 0; +} + + +int +ElementRecorderRMS::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + addColumnInfo = 1; + + if (theChannel.isDatastore() == 1) { + opserr << "ElementRecorderRMS::recvSelf() - does not recv data to a datastore\n"; + return -1; + } + + if (responseArgs != 0) { + for (int i=0; isetTag(idData(5)); + + numEle = eleSize; + + static Vector dData(1); + if (theChannel.recvVector(0, commitTag, dData) < 0) { + opserr << "ElementRecorderRMS::recvSelf() - failed to recv dData\n"; + return -1; + } + deltaT = dData(1); + + + // + // resize & recv the eleID + // + + if (eleSize != 0) { + eleID = new ID(eleSize); + if (eleID == 0) { + opserr << "ElementRecorder::recvSelf() - failed to recv idData\n"; + return -1; + } + if (theChannel.recvID(0, commitTag, *eleID) < 0) { + opserr << "ElementRecorder::recvSelf() - failed to recv idData\n"; + return -1; + } + } + + + // + // resize & recv the dof + // + + if (numDOF != 0) { + dof = new ID(numDOF); + if (dof == 0) { + opserr << "ElementRecorder::recvSelf() - failed to create dof\n"; + return -1; + } + if (theChannel.recvID(0, commitTag, *dof) < 0) { + opserr << "ElementRecorder::recvSelf() - failed to recv dof\n"; + return -1; + } + } + + // + // recv the single char array of element response args + // + + if (msgLength == 0) { + opserr << "ElementRecorderRMS::recvSelf() - 0 sized string for responses\n"; + return -1; + } + + char *allResponseArgs = new char[msgLength]; + if (allResponseArgs == 0) { + opserr << "ElementRecorderRMS::recvSelf() - out of memory\n"; + return -1; + } + + Message theMessage(allResponseArgs, msgLength); + if (theChannel.recvMsg(0, commitTag, theMessage) < 0) { + opserr << "ElementRecorderRMS::recvSelf() - failed to recv message\n"; + return -1; + } + + // + // now break this single array into many + // + + responseArgs = new char *[numArgs]; + if (responseArgs == 0) { + opserr << "ElementRecorderRMS::recvSelf() - out of memory\n"; + return -1; + } + + char *currentLoc = allResponseArgs; + for (int j=0; jrecvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "NodeRecorder::sendSelf() - failed to send the DataOutputHandler\n"; + return -1; + } + + // + // clean up & return success + // + + delete [] allResponseArgs; + return 0; + +} + +int +ElementRecorderRMS::initialize(void) +{ + if (theDomain == 0) + return 0; + + if (theResponses != 0) { + for (int i = 0; i < numEle; i++) + delete theResponses[i]; + delete [] theResponses; + } + + int numDbColumns = 0; + + // + // Set the response objects: + // 1. create an array of pointers for them + // 2. iterate over the elements invoking setResponse() to get the new objects & determine size of data + // + + int i =0; + ID xmlOrder(0,64); + ID responseOrder(0,64); + + if (eleID != 0) { + + // + // if we have an eleID we know Reponse size so allocate Response holder & loop over & ask each element + // + + int eleCount = 0; + int responseCount = 0; + + // loop over ele & set Reponses + for (i=0; igetElement((*eleID)(i)); + if (theEle != 0) { + xmlOrder[eleCount] = i+1; + eleCount++; + } + } + + theHandler->setOrder(xmlOrder); + + // + // if we have an eleID we know Reponse size so allocate Response holder & loop over & ask each element + // + + // allocate memory for Reponses & set to 0 + theResponses = new Response *[numEle]; + if (theResponses == 0) { + opserr << "ElementRecorder::initialize() - out of memory\n"; + return -1; + } + + for (int k=0; kgetElement((*eleID)(i)); + + if (theEle == 0) { + theResponses[i] = 0; + } else { + opserr << *theEle; + + for (int a=0; asetResponse((const char **)responseArgs, numArgs, *theHandler); + if (theResponses[i] != 0) { + opserr << "HAS RESPONSE\n"; + // from the response type determine no of cols for each + Information &eleInfo = theResponses[i]->getInformation(); + const Vector &eleData = eleInfo.getData(); + int dataSize = eleData.Size(); + if (numDOF == 0) + numDbColumns += dataSize; + else + numDbColumns += numDOF; + + if (addColumnInfo == 1) { + if (numDOF == 0) + for (int j=0; jsetOrder(responseOrder); + + } else { + + // + // if no eleID we don't know response size so make initial guess & loop over & ask ele + // if guess to small, we enlarge + // + + // initial size & allocation + int numResponse = 0; + numEle = 12; + theResponses = new Response *[numEle]; + + if (theResponses == 0) { + opserr << "ElementRecorder::initialize() - out of memory\n"; + return -1; + } + + for (int k=0; kgetElements(); + Element *theEle; + + while ((theEle = theElements()) != 0) { + Response *theResponse = theEle->setResponse((const char **)responseArgs, numArgs, *theHandler); + if (theResponse != 0) { + if (numResponse == numEle) { + // Why is this created locally and not used? -- MHS + Response **theNextResponses = new Response *[numEle*2]; + if (theNextResponses != 0) { + for (int i=0; igetInformation(); + const Vector &eleData = eleInfo.getData(); + numDbColumns += eleData.Size(); + + numResponse++; + + } + } + numEle = numResponse; + } + + // + // create the matrix & vector that holds the data + // + + opserr << numEle << " " << numDbColumns << "\n"; + + runningTotal = new Vector(numDbColumns); + currentData = new Vector(numDbColumns); + if (runningTotal == 0 || currentData == 0) { + opserr << "ElementRecorderRMS::ElementRecorderRMS() - out of memory\n"; + exit(-1); + } + runningTotal->Zero(); + currentData->Zero(); + + initializationDone = true; + return 0; +} + +//added by SAJalali +double ElementRecorderRMS::getRecordedValue(int clmnId, int rowOffset, bool reset) +{ + double res = 0; + if (!initializationDone) + return res; + if (clmnId >= runningTotal->Size()) + return res; + res = (*runningTotal)(clmnId); + if (count != 0) + res = sqrt(res/count); + if (reset) + count = 0; + return (res*res)/count; +} diff --git a/SRC/recorder/ElementRecorderRMS.h b/SRC/recorder/ElementRecorderRMS.h new file mode 100644 index 0000000000..0d1d86c682 --- /dev/null +++ b/SRC/recorder/ElementRecorderRMS.h @@ -0,0 +1,99 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.10 $ +// $Date: 2009-04-14 21:14:22 $ +// $Source: /usr/local/cvs/OpenSees/SRC/recorder/ElementRecorderRMS.h,v $ + +#ifndef ElementRecorderRMS_h +#define ElementRecorderRMS_h + +// Written: fmk +// +// What: "@(#) ElementRecorderRMS.h, revA" + +#include +#include +#include +#include + + +class Domain; +class Vector; +class Matrix; +class Element; +class Response; +class FE_Datastore; + +class ElementRecorderRMS: public Recorder +{ + public: + ElementRecorderRMS(); + ElementRecorderRMS(const ID *eleID, + const char **argv, + int argc, + Domain &theDomain, + OPS_Stream &theOutputHandler, + double deltaT = 0.0, + const ID *dof =0); + + ~ElementRecorderRMS(); + + int record(int commitTag, double timeStamp); + int restart(void); + + int setDomain(Domain &theDomain); + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + virtual double getRecordedValue(int clmnId, int rowOffset, bool reset); //added by SAJalali + + protected: + + private: + int initialize(void); + + int numEle; + int numDOF; + + ID *eleID; + ID *dof; + + Response **theResponses; + + Domain *theDomain; + OPS_Stream *theHandler; + + double deltaT; + double nextTimeStampToRecord; + + Vector *runningTotal; + Vector *currentData; + int count; + + bool initializationDone; + char **responseArgs; + int numArgs; + + int addColumnInfo; +}; + + +#endif diff --git a/SRC/recorder/EnvelopeElementRecorder.cpp b/SRC/recorder/EnvelopeElementRecorder.cpp index 05c7d52bd6..cb7d49bbcb 100644 --- a/SRC/recorder/EnvelopeElementRecorder.cpp +++ b/SRC/recorder/EnvelopeElementRecorder.cpp @@ -249,6 +249,7 @@ OPS_EnvelopeElementRecorder() } } + // data handler if (eMode == DATA_STREAM && filename != 0) theOutputStream = new DataFileStream(filename, OVERWRITE, 2, 0, closeOnWrite, precision, doScientific); @@ -1013,4 +1014,4 @@ double EnvelopeElementRecorder::getRecordedValue(int clmnId, int rowOffset, bool if (reset) first = true; return res; -} \ No newline at end of file +} diff --git a/SRC/recorder/GmshRecorder.cpp b/SRC/recorder/GmshRecorder.cpp index 93bdc48117..3c6acc60d6 100644 --- a/SRC/recorder/GmshRecorder.cpp +++ b/SRC/recorder/GmshRecorder.cpp @@ -1283,6 +1283,7 @@ GmshRecorder::setGMSHType() gmshtypes[ELE_TAG_FourNodeQuad] = GMSH_QUAD; gmshtypes[ELE_TAG_FourNodeQuad3d] = GMSH_QUAD; gmshtypes[ELE_TAG_Tri31] = GMSH_TRIANGLE; + gmshtypes[ELE_TAG_SixNodeTri] = GMSH_TRIANGLE; gmshtypes[ELE_TAG_BeamWithHinges2d] = GMSH_LINE; gmshtypes[ELE_TAG_BeamWithHinges3d] = GMSH_LINE; gmshtypes[ELE_TAG_EightNodeBrick] = GMSH_HEXAHEDRON; @@ -1304,6 +1305,8 @@ GmshRecorder::setGMSHType() gmshtypes[ELE_TAG_PlateMITC4] = GMSH_QUAD; gmshtypes[ELE_TAG_ShellMITC4] = GMSH_QUAD; gmshtypes[ELE_TAG_ShellMITC9] = GMSH_POLY_VERTEX; + gmshtypes[ELE_TAG_ASDShellQ4] = GMSH_QUAD; + gmshtypes[ELE_TAG_ASDShellT3] = GMSH_TRIANGLE; gmshtypes[ELE_TAG_Plate1] = GMSH_QUAD; gmshtypes[ELE_TAG_Brick] = GMSH_HEXAHEDRON; gmshtypes[ELE_TAG_BbarBrick] = GMSH_HEXAHEDRON; @@ -1311,6 +1314,8 @@ GmshRecorder::setGMSHType() gmshtypes[ELE_TAG_EnhancedQuad] = GMSH_QUAD; gmshtypes[ELE_TAG_ConstantPressureVolumeQuad] = GMSH_QUAD; gmshtypes[ELE_TAG_NineNodeMixedQuad] = GMSH_POLY_VERTEX; + gmshtypes[ELE_TAG_NineNodeQuad] = GMSH_POLY_VERTEX; + gmshtypes[ELE_TAG_EightNodeQuad] = GMSH_POLY_VERTEX; gmshtypes[ELE_TAG_DispBeamColumn2d] = GMSH_LINE; gmshtypes[ELE_TAG_TimoshenkoBeamColumn2d] = GMSH_LINE; gmshtypes[ELE_TAG_DispBeamColumn3d] = GMSH_LINE; diff --git a/SRC/recorder/MPCORecorder.cpp b/SRC/recorder/MPCORecorder.cpp index 62f76d2b1a..7f1dbf8c53 100755 --- a/SRC/recorder/MPCORecorder.cpp +++ b/SRC/recorder/MPCORecorder.cpp @@ -124,8 +124,8 @@ macros **************************************************************************************/ -#ifndef M_PI -#define M_PI 3.14159265358979323846 +#ifndef M_PI +#define M_PI 3.14159265358979323846 #endif // element tags not defined in an accessible .h file... \todo check them... @@ -172,11 +172,11 @@ typedef unsigned int H5F_scope_t; // enum (uint) in hdf5 HDF5 version info */ -#define H5_VERS_MAJOR 1 /* For major interface/format changes */ -#define H5_VERS_MINOR 10 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 1 /* For tweaks, bug-fixes, or development */ -#define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */ - /* Empty string for real releases. */ +#define H5_VERS_MAJOR 1 /* For major interface/format changes */ +#define H5_VERS_MINOR 10 /* For minor interface/format changes */ +#define H5_VERS_RELEASE 1 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */ + /* Empty string for real releases. */ #define H5_VERS_INFO "HDF5 library version: 1.10.1" /* Full version string */ /* @@ -640,7 +640,9 @@ namespace utils { ele_tag == ELE_TAG_ShellNLDKGQThermal || ele_tag == ELE_TAG_ShellDKGT || ele_tag == ELE_TAG_ShellNLDKGT || - ele_tag == ELE_TAG_ShellANDeS + ele_tag == ELE_TAG_ShellANDeS || + ele_tag == ELE_TAG_ASDShellQ4 || + ele_tag == ELE_TAG_ASDShellT3 ); } @@ -3533,6 +3535,13 @@ namespace mpco { get class tag, geometry and integration rule type */ int elem_type = current_element->getClassTag(); + + if (elem_type == ELE_TAG_Subdomain) + { + //Skip subdomains + continue; + } + ElementGeometryType::Enum geom_type; ElementIntegrationRuleType::Enum int_rule_type; getGeometryAndIntRuleByClassTag(elem_type, geom_type, int_rule_type); @@ -3715,7 +3724,8 @@ namespace mpco { else if ( // ./shell elem_class_tag == ELE_TAG_ShellDKGT || - elem_class_tag == ELE_TAG_ShellNLDKGT + elem_class_tag == ELE_TAG_ShellNLDKGT || + elem_class_tag == ELE_TAG_ASDShellT3 ) { geom_type = ElementGeometryType::Triangle_3N; int_type = ElementIntegrationRuleType::Triangle_GaussLegendre_2C; @@ -3747,6 +3757,7 @@ namespace mpco { elem_class_tag == ELE_TAG_ShellNLDKGQ || elem_class_tag == ELE_TAG_ShellMITC4 || elem_class_tag == ELE_TAG_ShellMITC4Thermal || + elem_class_tag == ELE_TAG_ASDShellQ4 || // ./up elem_class_tag == ELE_TAG_BBarFourNodeQuadUP || elem_class_tag == ELE_TAG_FourNodeQuadUP @@ -3760,6 +3771,7 @@ namespace mpco { else if ( // ./quad elem_class_tag == ELE_TAG_NineNodeMixedQuad || + elem_class_tag == ELE_TAG_NineNodeQuad || // ./shell elem_class_tag == ELE_TAG_ShellMITC9 || // ./up @@ -4274,7 +4286,7 @@ int MPCORecorder::sendSelf(int commitTag, Channel &theChannel) // send misc info { - ID aux(8); + ID aux(9); aux(0) = getTag(); aux(1) = m_data->send_self_count; // use the send self counter as p_id in the receiver aux(2) = static_cast(m_data->filename.size()); @@ -4283,6 +4295,8 @@ int MPCORecorder::sendSelf(int commitTag, Channel &theChannel) aux(5) = static_cast(m_data->has_region); aux(6) = static_cast(m_data->node_set.size()); aux(7) = static_cast(m_data->elem_set.size()); + aux(8) = static_cast(m_data->sens_grad_indices.size()); + if (theChannel.sendID(0, commitTag, aux) < 0) { opserr << "MPCORecorder::sendSelf() - failed to send misc info\n"; return -1; @@ -4373,7 +4387,7 @@ int MPCORecorder::sendSelf(int commitTag, Channel &theChannel) int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) { if (theChannel.isDatastore() == 1) { - opserr << "MPCORecorder::sendSelf() - does not send data to a datastore\n"; + opserr << "MPCORecorder::recvSelf() - does not recv data to a datastore\n"; return -1; } @@ -4391,10 +4405,11 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker size_t aux_res_merged_string_size(0); size_t aux_node_set_size(0); size_t aux_elem_set_size(0); + size_t aux_sens_grad_indices_size(0); { - ID aux(8); + ID aux(9); if (theChannel.recvID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to recv misc info\n"; + opserr << "MPCORecorder::recvSelf() - " << m_data->p_id << " - failed to recv misc info\n"; return -1; } setTag(aux(0)); @@ -4402,7 +4417,7 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker aux_filename_size = aux(2); aux_node_res_size = aux(3); aux_res_merged_string_size = aux(4); - m_data->has_region = aux(5) != 0; + m_data->has_region = aux(5);// != 0; aux_node_set_size = static_cast(aux(6)); aux_elem_set_size = static_cast(aux(7)); } @@ -4412,7 +4427,7 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker std::vector aux(aux_filename_size); Message msg(aux.data(), static_cast(aux_filename_size)); if (theChannel.recvMsg(0, commitTag, msg) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to recv filename\n"; + opserr << "MPCORecorder::recvSelf() - failed to recv filename\n"; return -1; } m_data->filename = std::string(aux.begin(), aux.end()); @@ -4422,7 +4437,7 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker { Vector aux(3); if (theChannel.recvVector(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to recv output frequency\n"; + opserr << "MPCORecorder::recvSelf() - failed to recv output frequency\n"; return -1; } m_data->output_freq.type = static_cast(static_cast(aux(0))); @@ -4434,7 +4449,7 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker if (aux_node_res_size > 0) { ID aux(static_cast(aux_node_res_size)); if (theChannel.recvID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to recv node result requests\n"; + opserr << "MPCORecorder::recvSelf() - failed to recv node result requests\n"; return -1; } m_data->nodal_results_requests.resize(aux_node_res_size); @@ -4443,14 +4458,14 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker } // recv node result requests (sens grad indices) - if (m_data->sens_grad_indices.size() > 0) { - ID aux(static_cast(aux_node_res_size)); + if (aux_sens_grad_indices_size > 0) { + ID aux(static_cast(aux_sens_grad_indices_size)); if (theChannel.recvID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to recv node result requests (sensitivity parameter indices)\n"; + opserr << "MPCORecorder::recvSelf() - failed to recv node result requests (sensitivity parameter indices)\n"; return -1; } - m_data->sens_grad_indices.resize(aux_node_res_size); - for (size_t i = 0; i < aux_node_res_size; i++) + m_data->sens_grad_indices.resize(aux_sens_grad_indices_size); + for (size_t i = 0; i < aux_sens_grad_indices_size; i++) m_data->sens_grad_indices[i] = aux(static_cast(i)); } @@ -4458,8 +4473,8 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker if (aux_res_merged_string_size > 0) { std::vector aux(aux_res_merged_string_size); Message msg(aux.data(), static_cast(aux_res_merged_string_size)); - if (theChannel.sendMsg(0, commitTag, msg) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to recv element result requests\n"; + if (theChannel.recvMsg(0, commitTag, msg) < 0) { + opserr << "MPCORecorder::recvSelf() - failed to recv element result requests\n"; return -1; } std::vector aux_1; @@ -4476,7 +4491,7 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker if (aux_node_set_size > 0) { ID aux(static_cast(aux_node_set_size)); if (theChannel.recvID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to recv node set\n"; + opserr << "MPCORecorder::recvSelf() - failed to recv node set\n"; return -1; } m_data->node_set.resize(aux_node_set_size); @@ -4488,7 +4503,7 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker if (aux_elem_set_size > 0) { ID aux(static_cast(aux_elem_set_size)); if (theChannel.recvID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to recv elem set\n"; + opserr << "MPCORecorder::recvSelf() - failed to recv elem set\n"; return -1; } m_data->elem_set.resize(aux_elem_set_size); @@ -4531,6 +4546,7 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker } } } + _info << "]\n"; _info << "elem set:" << "\n" << "["; { int n_counter(0); @@ -4609,7 +4625,7 @@ int MPCORecorder::initialize() std::stringstream ss_filename; for (size_t i = 0; i < filename_words.size() - 1; i++) ss_filename << filename_words[i] << '.'; - if (m_data->send_self_count != 0) { // > 0 -> we are in p0, < 0 -> we are in slave procs, = 0 -> not in parallel + if (m_data->send_self_count != 0) { // > 0 -> we are in p0, < 0 -> we are in secondary procs, = 0 -> not in parallel ss_filename << "p" << m_data->p_id << '.'; } ss_filename << filename_words.back(); diff --git a/SRC/recorder/Makefile b/SRC/recorder/Makefile index f5e8865119..714baae4e6 100644 --- a/SRC/recorder/Makefile +++ b/SRC/recorder/Makefile @@ -9,7 +9,9 @@ endif OBJS = Recorder.o \ DatastoreRecorder.o \ ElementRecorder.o \ + ElementRecorderRMS.o \ NodeRecorder.o \ + NodeRecorderRMS.o \ EnvelopeElementRecorder.o \ NormElementRecorder.o \ NormEnvelopeElementRecorder.o \ diff --git a/SRC/recorder/NodeRecorder.cpp b/SRC/recorder/NodeRecorder.cpp index 808b9c7c63..08cee97838 100644 --- a/SRC/recorder/NodeRecorder.cpp +++ b/SRC/recorder/NodeRecorder.cpp @@ -572,6 +572,7 @@ NodeRecorder::record(int commitTag, double timeStamp) Node *theNode = theNodes[i]; if (dataFlag == 0) { + // AddingSensitivity:BEGIN /////////////////////////////////// if (gradIndex < 0) { const Vector &theResponse = theNode->getTrialDisp(); @@ -602,6 +603,7 @@ NodeRecorder::record(int commitTag, double timeStamp) // AddingSensitivity:END ///////////////////////////////////// } else if (dataFlag == 1) { + const Vector &theResponse = theNode->getTrialVel(); for (int j=0; jgetIncrDisp(); for (int j=0; j +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +void* +OPS_NodeRecorderRMS() +{ + if (OPS_GetNumRemainingInputArgs() < 5) { + opserr << "WARING: recorder EnvelopeNode "; + opserr << "-node -dof -file -dT
reponse"; + return 0; + } + + const char* responseID = 0; + OPS_Stream *theOutputStream = 0; + const char* filename = 0; + + const int STANDARD_STREAM = 0; + const int DATA_STREAM = 1; + const int XML_STREAM = 2; + const int DATABASE_STREAM = 3; + const int BINARY_STREAM = 4; + const int DATA_STREAM_CSV = 5; + const int TCP_STREAM = 6; + const int DATA_STREAM_ADD = 7; + + int eMode = STANDARD_STREAM; + + double dT = 0.0; + bool doScientific = false; + + int precision = 6; + + bool closeOnWrite = false; + + const char *inetAddr = 0; + int inetPort; + + TimeSeries **theTimeSeries = 0; + + ID nodes(0, 6); + ID dofs(0, 6); + ID timeseries(0, 6); + + while (OPS_GetNumRemainingInputArgs() > 0) { + + const char* option = OPS_GetString(); + responseID = option; + + if (strcmp(option, "-scientific") == 0) { + doScientific = true; + } + else if (strcmp(option, "-file") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + filename = OPS_GetString(); + } + eMode = DATA_STREAM; + } + else if (strcmp(option, "-fileAdd") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + filename = OPS_GetString(); + } + eMode = DATA_STREAM_ADD; + } + else if (strcmp(option, "-closeOnWrite") == 0) { + closeOnWrite = true; + } + else if (strcmp(option, "-csv") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + filename = OPS_GetString(); + } + eMode = DATA_STREAM_CSV; + } + else if (strcmp(option, "-tcp") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + inetAddr = OPS_GetString(); + } + if (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + if (OPS_GetIntInput(&num, &inetPort) < 0) { + opserr << "WARNING: failed to read inetPort\n"; + return 0; + } + } + eMode = TCP_STREAM; + } + else if (strcmp(option, "-xml") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + filename = OPS_GetString(); + } + eMode = XML_STREAM; + } + else if (strcmp(option, "-binary") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + filename = OPS_GetString(); + } + eMode = BINARY_STREAM; + } + else if (strcmp(option, "-dT") == 0) { + if (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + if (OPS_GetDoubleInput(&num, &dT) < 0) { + opserr << "WARNING: failed to read dT\n"; + return 0; + } + } + } + else if (strcmp(option, "-timeSeries") == 0) { + int numTimeSeries = 0; + while (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + int ts; + if (OPS_GetIntInput(&num, &ts) < 0) { + // OPS_ResetCurrentInputArg(-1); + break; + } + timeseries[numTimeSeries++] = ts; + } + theTimeSeries = new TimeSeries *[numTimeSeries]; + for (int j = 0; j 0) { + int num = 1; + if (OPS_GetIntInput(&num, &precision) < 0) { + opserr << "WARNING: failed to read precision\n"; + return 0; + } + } + } + else if (strcmp(option, "-node") == 0) { + int numNodes = 0; + while (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + int nd; + if (OPS_GetIntInput(&num, &nd) < 0) { + // OPS_ResetCurrentInputArg(-1); + break; + } + nodes[numNodes++] = nd; + } + } + else if (strcmp(option, "-nodeRange") == 0) { + int start, end; + if (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + if (OPS_GetIntInput(&num, &start) < 0) { + opserr << "WARNING: failed to read start node\n"; + return 0; + } + } + if (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + if (OPS_GetIntInput(&num, &end) < 0) { + opserr << "WARNING: failed to read end node\n"; + return 0; + } + } + if (start > end) { + int swap = end; + end = start; + start = swap; + } + int numNodes = 0; + for (int i = start; i <= end; i++) + nodes[numNodes++] = i; + } + else if (strcmp(option, "-region") == 0) { + int tag; + if (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + if (OPS_GetIntInput(&num, &tag) < 0) { + opserr << "WARNING: failed to read region tag\n"; + return 0; + } + } + Domain *domain = OPS_GetDomain(); + MeshRegion *theRegion = domain->getRegion(tag); + if (theRegion == 0) { + opserr << "WARNING: region does not exist\n"; + return 0; + } + const ID &nodeRegion = theRegion->getNodes(); + int numNodes = 0; + for (int i = 0; i < nodeRegion.Size(); i++) + nodes[numNodes++] = nodeRegion(i); + } + else if (strcmp(option, "-dof") == 0) { + int numDOF = 0; + while (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + int dof; + if (OPS_GetIntInput(&num, &dof) < 0) { + // OPS_ResetCurrentInputArg(-1); + break; + } + dofs[numDOF++] = dof - 1; + } + } + } + + // data handler + if (eMode == DATA_STREAM && filename != 0) + theOutputStream = new DataFileStream(filename, OVERWRITE, 2, 0, closeOnWrite, precision, doScientific); + else if (eMode == DATA_STREAM_ADD && filename != 0) + theOutputStream = new DataFileStreamAdd(filename, OVERWRITE, 2, 0, closeOnWrite, precision, doScientific); + else if (eMode == DATA_STREAM_CSV && filename != 0) + theOutputStream = new DataFileStream(filename, OVERWRITE, 2, 1, closeOnWrite, precision, doScientific); + else if (eMode == XML_STREAM && filename != 0) + theOutputStream = new XmlFileStream(filename); + //else if (eMode == DATABASE_STREAM && tableName != 0) + // theOutputStream = new DatabaseStream(theDatabase, tableName); + else if (eMode == BINARY_STREAM && filename != 0) + theOutputStream = new BinaryFileStream(filename); + else if (eMode == TCP_STREAM && inetAddr != 0) + theOutputStream = new TCP_Stream(inetPort, inetAddr); + else + theOutputStream = new StandardStream(); + + theOutputStream->setPrecision(precision); + + Domain* domain = OPS_GetDomain(); + if (domain == 0) + return 0; + NodeRecorderRMS* recorder = new NodeRecorderRMS(dofs, &nodes, + responseID, *domain, *theOutputStream, + dT, theTimeSeries); + + return recorder; +} + + +NodeRecorderRMS::NodeRecorderRMS() +:Recorder(RECORDER_TAGS_NodeRecorderRMS), + theDofs(0), theNodalTags(0), theNodes(0), + currentData(0), runningTotal(0), count(0), + theDomain(0), theHandler(0), + deltaT(0.0), nextTimeStampToRecord(0.0), + initializationDone(false), + numValidNodes(0), addColumnInfo(0), theTimeSeries(0), timeSeriesValues(0) +{ + +} + +NodeRecorderRMS::NodeRecorderRMS(const ID &dofs, + const ID *nodes, + const char *dataToStore, + Domain &theDom, + OPS_Stream &theOutputHandler, + double dT, + TimeSeries **theSeries) +:Recorder(RECORDER_TAGS_NodeRecorderRMS), + theDofs(0), theNodalTags(0), theNodes(0), + currentData(0), runningTotal(0), count(0), + theDomain(&theDom), theHandler(&theOutputHandler), + deltaT(dT), nextTimeStampToRecord(0.0), + initializationDone(false), numValidNodes(0), + addColumnInfo(0), theTimeSeries(theSeries), timeSeriesValues(0) +{ + // verify dof are valid + int numDOF = dofs.Size(); + theDofs = new ID(0, numDOF); + + int count = 0; + int i; + for (i=0; i= 0) { + (*theDofs)[count] = dof; + count++; + } else { + opserr << "NodeRecorderRMS::NodeRecorderRMS - invalid dof " << dof; + opserr << " will be ignored\n"; + } + } + + + // + // create memory to hold nodal ID's (neeed parallel) + // + + if (nodes != 0) { + int numNode = nodes->Size(); + if (numNode != 0) { + theNodalTags = new ID(*nodes); + if (theNodalTags == 0 || theNodalTags->Size() != nodes->Size()) { + opserr << "NodeRecorder::NodeRecorder - out of memory\n"; + } + } + } + + if (theTimeSeries != 0) { + timeSeriesValues = new double [numDOF]; + for (int i=0; i 0) + dataFlag = 10 + mode; + else + dataFlag = 10; + } else if ((strncmp(dataToStore, "sensitivity",11) == 0)) { + int grad = atoi(&(dataToStore[11])); + if (grad > 0) + dataFlag = 1000 + grad; + else + dataFlag = 10; + } else if ((strncmp(dataToStore, "velSensitivity",14) == 0)) { + int grad = atoi(&(dataToStore[14])); + if (grad > 0) + dataFlag = 2000 + grad; + else + dataFlag = 10; + } else if ((strncmp(dataToStore, "accSensitivity",14) == 0)) { + int grad = atoi(&(dataToStore[14])); + if (grad > 0) + dataFlag = 3000 + grad; + else + dataFlag = 10; + + } else { + dataFlag = 10; + opserr << "NodeRecorderRMS::NodeRecorder - dataToStore " << dataToStore; + opserr << "not recognized (disp, vel, accel, incrDisp, incrDeltaDisp)\n"; + } + + if (dataFlag == 7 || dataFlag == 8 || dataFlag == 9) { + theOutputHandler.setAddCommon(1); + } +} + + +NodeRecorderRMS::~NodeRecorderRMS() +{ + // + // write the data + // + + if (theHandler != 0 && runningTotal != 0) { + + theHandler->tag("Data"); // Data + + int numResponse = runningTotal->Size(); + + if (runningTotal != 0) { + for (int j=0; jwrite(*runningTotal); + + theHandler->endTag(); // Data + } + + // + // clean up the memory + // + + int numDOF = theDofs->Size(); + + if (theDofs != 0) + delete theDofs; + + if (theNodalTags != 0) + delete theNodalTags; + + if (theHandler != 0) + delete theHandler; + + if (currentData != 0) + delete currentData; + + if (runningTotal != 0) + delete runningTotal; + + if (theNodes != 0) + delete [] theNodes; + + if (theTimeSeries != 0) { + for (int i=0; iinitialize() != 0) { + opserr << "NodeRecorderRMS::record() - failed in initialize()\n"; + return -1; + } + + + int numDOF = theDofs->Size(); + + if (deltaT == 0.0 || timeStamp >= nextTimeStampToRecord) { + + if (deltaT != 0.0) + nextTimeStampToRecord = timeStamp + deltaT; + + double timeSeriesTerm = 0.0; + + if (theTimeSeries != 0) { + for (int i=0; igetFactor(timeStamp); + } + } + + // + // if need nodal reactions get the domain to calculate them + // before we iterate over the nodes + // + + if (dataFlag == 7) + theDomain->calculateNodalReactions(0); + else if (dataFlag == 8) + theDomain->calculateNodalReactions(1); + if (dataFlag == 9) + theDomain->calculateNodalReactions(2); + + + for (int i=0; igetTrialDisp(); + for (int j=0; j dof) { + (*currentData)(cnt) = response(dof) + timeSeriesTerm; + }else + (*currentData)(cnt) = 0.0 + timeSeriesTerm; + + cnt++; + } + + } else if (dataFlag == 10000) { + const Vector &response = theNode->getTrialDisp(); + double sum = 0.0; + for (int j=0; j dof) { + sum += (response(dof) + timeSeriesTerm) * (response(dof) + timeSeriesTerm); + } else + sum += timeSeriesTerm * timeSeriesTerm; + } + + (*currentData)(cnt) = sqrt(sum); + cnt++; + + } else if (dataFlag == 1) { + const Vector &response = theNode->getTrialVel(); + for (int j=0; j dof) { + (*currentData)(cnt) = response(dof) + timeSeriesTerm; + } else + (*currentData)(cnt) = 0.0 + timeSeriesTerm; + + cnt++; + } + } else if (dataFlag == 2) { + const Vector &response = theNode->getTrialAccel(); + for (int j=0; j dof) { + (*currentData)(cnt) = response(dof) + timeSeriesTerm; + } else + (*currentData)(cnt) = 0.0 + timeSeriesTerm; + + cnt++; + } + } else if (dataFlag == 3) { + const Vector &response = theNode->getIncrDisp(); + for (int j=0; j dof) { + (*currentData)(cnt) = response(dof); + } else + (*currentData)(cnt) = 0.0; + + cnt++; + } + } else if (dataFlag == 4) { + const Vector &response = theNode->getIncrDeltaDisp(); + for (int j=0; j dof) { + (*currentData)(cnt) = response(dof); + } else + (*currentData)(cnt) = 0.0; + + cnt++; + } + } else if (dataFlag == 5) { + const Vector &theResponse = theNode->getUnbalancedLoad(); + for (int j=0; j dof) { + (*currentData)(cnt) = theResponse(dof); + } else + (*currentData)(cnt) = 0.0; + + cnt++; + } + + } else if (dataFlag == 6) { + const Vector &theResponse = theNode->getUnbalancedLoadIncInertia(); + for (int j=0; j dof) { + (*currentData)(cnt) = theResponse(dof); + } else + (*currentData)(cnt) = 0.0; + + cnt++; + } + + } else if (dataFlag == 7 || dataFlag == 8 || dataFlag == 9) { + const Vector &theResponse = theNode->getReaction(); + for (int j=0; j dof) { + (*currentData)(cnt) = theResponse(dof); + } else + (*currentData)(cnt) = 0.0; + + cnt++; + } + + } else if (dataFlag > 10) { + int mode = dataFlag - 10; + int column = mode - 1; + const Matrix &theEigenvectors = theNode->getEigenvectors(); + if (theEigenvectors.noCols() > column) { + int noRows = theEigenvectors.noRows(); + for (int j=0; j dof) { + (*currentData)(cnt) = theEigenvectors(dof,column); + } else + (*currentData)(cnt) = 0.0; + cnt++; + } + } else { + for (int j=0; jSize(); + for (int i=0; iZero(); + count = 0; + return 0; +} + + +int +NodeRecorderRMS::setDomain(Domain &theDom) +{ + theDomain = &theDom; + initializationDone = false; + return 0; +} + + +int +NodeRecorderRMS::sendSelf(int commitTag, Channel &theChannel) +{ + addColumnInfo = 1; + + int numDOF = theDofs->Size(); + + if (theChannel.isDatastore() == 1) { + opserr << "NodeRecorderRMS::sendSelf() - does not send data to a datastore\n"; + return -1; + } + + initializationDone = false; + static ID idData(7); + idData.Zero(); + + if (theDofs != 0) + idData(0) = numDOF; + if (theNodalTags != 0) + idData(1) = theNodalTags->Size(); + if (theHandler != 0) { + idData(2) = theHandler->getClassTag(); + } + + idData(3) = dataFlag; + + + idData(5) = this->getTag(); + + if (theTimeSeries == 0) + idData[6] = 0; + else + idData[6] = 1; + + if (theChannel.sendID(0, commitTag, idData) < 0) { + opserr << "NodeRecorderRMS::sendSelf() - failed to send idData\n"; + return -1; + } + + if (theDofs != 0) + if (theChannel.sendID(0, commitTag, *theDofs) < 0) { + opserr << "NodeRecorderRMS::sendSelf() - failed to send dof id's\n"; + return -1; + } + + if (theNodalTags != 0) + if (theChannel.sendID(0, commitTag, *theNodalTags) < 0) { + opserr << "NodeRecorderRMS::sendSelf() - failed to send nodal tags\n"; + return -1; + } + + static Vector data(2); + data(0) = deltaT; + data(1) = nextTimeStampToRecord; + if (theChannel.sendVector(0, commitTag, data) < 0) { + opserr << "NodeRecorderRMS::sendSelf() - failed to send data\n"; + return -1; + } + + if (theHandler->sendSelf(commitTag, theChannel) < 0) { + opserr << "NodeRecorderRMS::sendSelf() - failed to send the DataOutputHandler\n"; + return -1; + } + + if (theTimeSeries != 0) { + ID timeSeriesTags(numDOF); + for (int i=0; igetClassTag(); + } else + timeSeriesTags[i] = -1; + } + if (theChannel.sendID(0, commitTag, timeSeriesTags) < 0) { + opserr << "NodeRecorderRMS::sendSelf() - failed to send time series tags\n"; + return -1; + } + for (int i=0; isendSelf(commitTag, theChannel) < 0) { + opserr << "NodeRecorderRMS::sendSelf() - time series failed in send\n"; + return -1; + + } + } + } + } + + return 0; +} + +int +NodeRecorderRMS::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + addColumnInfo = 1; + + if (theChannel.isDatastore() == 1) { + opserr << "NodeRecorderRMS::sendSelf() - does not send data to a datastore\n"; + return -1; + } + + static ID idData(7); + if (theChannel.recvID(0, commitTag, idData) < 0) { + opserr << "NodeRecorderRMS::recvSelf() - failed to send idData\n"; + return -1; + } + + int numDOFs = idData(0); + int numNodes = idData(1); + + dataFlag = idData(3); + + this->setTag(idData(5)); + + + + // + // get the DOF ID data + // + + if (theDofs == 0 || theDofs->Size() != numDOFs) { + if (theDofs != 0) + delete theDofs; + + if (numDOFs != 0) { + theDofs = new ID(numDOFs); + if (theDofs == 0 || theDofs->Size() != numDOFs) { + opserr << "NodeRecorderRMS::recvSelf() - out of memory\n"; + return -1; + } + } + } + if (theDofs != 0) + if (theChannel.recvID(0, commitTag, *theDofs) < 0) { + opserr << "NodeRecorderRMS::recvSelf() - failed to recv dof data\n"; + return -1; + } + + // + // get the NODAL tag data + // + + if (theNodalTags == 0 || theNodalTags->Size() != numNodes) { + if (theNodalTags != 0) + delete theNodalTags; + + if (numNodes != 0) { + theNodalTags = new ID(numNodes); + if (theNodalTags == 0 || theNodalTags->Size() != numNodes) { + opserr << "NodeRecorderRMS::recvSelf() - out of memory\n"; + return -1; + } + } + } + if (theNodalTags != 0) + if (theChannel.recvID(0, commitTag, *theNodalTags) < 0) { + opserr << "NodeRecorderRMS::recvSelf() - failed to recv dof data\n"; + return -1; + } + + + static Vector data(2); + if (theChannel.recvVector(0, commitTag, data) < 0) { + opserr << "NodeRecorderRMS::sendSelf() - failed to receive data\n"; + return -1; + } + deltaT = data(0); + nextTimeStampToRecord = data(1); + + if (theHandler != 0) + delete theHandler; + + theHandler = theBroker.getPtrNewStream(idData(2)); + if (theHandler == 0) { + opserr << "NodeRecorderRMS::sendSelf() - failed to get a data output handler\n"; + return -1; + } + + if (theHandler->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "NodeRecorderRMS::sendSelf() - failed to send the DataOutputHandler\n"; + return -1; + } + + + if (idData[6] == 1) { + theTimeSeries = new TimeSeries *[numDOFs]; + ID timeSeriesTags(numDOFs); + if (theChannel.recvID(0, commitTag, timeSeriesTags) < 0) { + opserr << "NodeRecorderRMS::recvSelf() - failed to recv time series tags\n"; + return -1; + } + for (int i=0; irecvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "NodeRecorderRMS::recvSelf() - time series failed in recv\n"; + return -1; + } + } + } + } + + return 0; +} + + +int +NodeRecorderRMS::initialize(void) +{ + if (theDofs == 0 || theDomain == 0) { + opserr << "NodeRecorderRMS::initialize() - either nodes, dofs or domain has not been set\n"; + return -1; + } + + // + // create & set nodal array pointer + // + + if (theNodes != 0) + delete [] theNodes; + + numValidNodes = 0; + + if (theNodalTags != 0) { + int numNode = theNodalTags->Size(); + theNodes = new Node *[numNode]; + if (theNodes == 0) { + opserr << "NodeRecorderRMS::domainChanged - out of memory\n"; + return -1; + } + + for (int i=0; igetNode(nodeTag); + if (theNode != 0) { + theNodes[numValidNodes] = theNode; + numValidNodes++; + } + } + } else { + + int numNodes = theDomain->getNumNodes(); + if (numNodes != 0) { + theNodes = new Node *[numNodes]; + + if (theNodes == 0) { + opserr << "NodeRecorder::domainChanged - out of memory\n"; + return -1; + } + NodeIter &theDomainNodes = theDomain->getNodes(); + Node *theNode; + numValidNodes = 0; + while (((theNode = theDomainNodes()) != 0) && (numValidNodes < numNodes)) { + theNodes[numValidNodes] = theNode; + numValidNodes++; + } + } else + numValidNodes = 0; + } + + // + // need to create the data description, i.e. what each column of data is + // + + // + // need to create the data description, i.e. what each column of data is + // + + char outputData[32]; + char dataType[10]; + + if (dataFlag == 0) { + strcpy(dataType,"D"); + } else if (dataFlag == 1) { + strcpy(dataType,"V"); + } else if (dataFlag == 2) { + strcpy(dataType,"A"); + } else if (dataFlag == 3) { + strcpy(dataType,"dD"); + } else if (dataFlag == 4) { + strcpy(dataType,"ddD"); + } else if (dataFlag == 5) { + strcpy(dataType,"U"); + } else if (dataFlag == 6) { + strcpy(dataType,"U"); + } else if (dataFlag == 7) { + strcpy(dataType,"R"); + } else if (dataFlag == 8) { + strcpy(dataType,"R"); + } else if (dataFlag == 10000) { + strcpy(dataType,"|D|"); + } else if (dataFlag > 10) { + sprintf(dataType,"E%d", dataFlag-10); + } else + strcpy(dataType,"Unknown"); + + + // + // resize the output matrix + // + + int numDOF = theDofs->Size(); + int numValidResponse = numValidNodes*numDOF; + + if (dataFlag == 10000) + numValidResponse = numValidNodes; + + currentData = new Vector(numValidResponse); + runningTotal = new Vector(numValidResponse); + runningTotal->Zero(); + + ID dataOrder(numValidResponse); + ID xmlOrder(numValidNodes); + + if (theNodalTags != 0 && addColumnInfo == 1) { + + int count = 0; + int nodeCount = 0; + + int numNode = theNodalTags->Size(); + for (int i=0; igetNode(nodeTag); + if (theNode != 0) { + xmlOrder(nodeCount++) = i+1; + for (int j=0; jsetOrder(xmlOrder); + } + + for (int i=0; igetTag(); + + theHandler->tag("NodeOutput"); + theHandler->attr("nodeTag", nodeTag); + + for (int j=0; jSize(); j++) { + + sprintf(outputData, "%s%d", dataType, j+1); + theHandler->tag("ResponseType",outputData); + } + + theHandler->endTag(); + } + + if (theNodalTags != 0 && addColumnInfo == 1) { + theHandler->setOrder(dataOrder); + } + + initializationDone = true; + + return 0; +} +//added by SAJalali +double NodeRecorderRMS::getRecordedValue(int clmnId, int rowOffset, bool reset) +{ + double res = 0; + if (!initializationDone) + return res; + if (clmnId >= runningTotal->Size() && count == 0) + return res; + if (count != 0) + res = sqrt(((*runningTotal)(clmnId)*(*runningTotal)(clmnId))/count); + if (reset) + count = 0; + return res; +} diff --git a/SRC/recorder/NodeRecorderRMS.h b/SRC/recorder/NodeRecorderRMS.h new file mode 100644 index 0000000000..392dc41ceb --- /dev/null +++ b/SRC/recorder/NodeRecorderRMS.h @@ -0,0 +1,91 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +#ifndef NodeRecorderRMS_h +#define NodeRecorderRMS_h + +// Written: fmk + + +#include +#include +#include +#include +#include + +class Domain; +class FE_Datastore; +class Node; + +class NodeRecorderRMS: public Recorder +{ + public: + NodeRecorderRMS(); + NodeRecorderRMS(const ID &theDof, + const ID *theNodes, + const char *dataToStore, + Domain &theDomain, + OPS_Stream &theOutputHandler, + double deltaT = 0.0, + TimeSeries **theTimeSeries =0); + + ~NodeRecorderRMS(); + + int record(int commitTag, double timeStamp); + int restart(void); + + int setDomain(Domain &theDomain); + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + + virtual double getRecordedValue(int clmnId, int rowOffset, bool reset); //added by SAJalali + + protected: + + private: + int initialize(void); + + ID *theDofs; + ID *theNodalTags; + Node **theNodes; + + Vector *currentData; + Vector *runningTotal; + int count; + + Domain *theDomain; + OPS_Stream *theHandler; + + int dataFlag; // flag indicating what it is to be stored in recorder + + double deltaT; + double nextTimeStampToRecord; + + bool initializationDone; + int numValidNodes; + + int addColumnInfo; + TimeSeries **theTimeSeries; + double *timeSeriesValues; + +}; + +#endif diff --git a/SRC/recorder/PVDRecorder.cpp b/SRC/recorder/PVDRecorder.cpp index 1a4f97079b..2c83fdc251 100644 --- a/SRC/recorder/PVDRecorder.cpp +++ b/SRC/recorder/PVDRecorder.cpp @@ -35,9 +35,9 @@ #include #include #include -#include -#include -#include +#include "PFEMElement/BackgroundDef.h" +#include "PFEMElement/Particle.h" +#include "PFEMElement/ParticleGroup.h" std::map PVDRecorder::vtktypes; @@ -1824,6 +1824,7 @@ PVDRecorder::setVTKType() vtktypes[ELE_TAG_FourNodeQuad] = VTK_QUAD; vtktypes[ELE_TAG_FourNodeQuad3d] = VTK_QUAD; vtktypes[ELE_TAG_Tri31] = VTK_TRIANGLE; + vtktypes[ELE_TAG_SixNodeTri] = VTK_TRIANGLE; vtktypes[ELE_TAG_BeamWithHinges2d] = VTK_LINE; vtktypes[ELE_TAG_BeamWithHinges3d] = VTK_LINE; vtktypes[ELE_TAG_EightNodeBrick] = VTK_HEXAHEDRON; @@ -1845,6 +1846,8 @@ PVDRecorder::setVTKType() vtktypes[ELE_TAG_PlateMITC4] = VTK_QUAD; vtktypes[ELE_TAG_ShellMITC4] = VTK_QUAD; vtktypes[ELE_TAG_ShellMITC9] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_ASDShellQ4] = VTK_QUAD; + vtktypes[ELE_TAG_ASDShellT3] = VTK_TRIANGLE; vtktypes[ELE_TAG_Plate1] = VTK_QUAD; vtktypes[ELE_TAG_Brick] = VTK_HEXAHEDRON; vtktypes[ELE_TAG_BbarBrick] = VTK_HEXAHEDRON; @@ -1852,6 +1855,8 @@ PVDRecorder::setVTKType() vtktypes[ELE_TAG_EnhancedQuad] = VTK_QUAD; vtktypes[ELE_TAG_ConstantPressureVolumeQuad] = VTK_QUAD; vtktypes[ELE_TAG_NineNodeMixedQuad] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_NineNodeQuad] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_EightNodeQuad] = VTK_POLY_VERTEX; vtktypes[ELE_TAG_DispBeamColumn2d] = VTK_LINE; vtktypes[ELE_TAG_TimoshenkoBeamColumn2d] = VTK_LINE; vtktypes[ELE_TAG_DispBeamColumn3d] = VTK_LINE; diff --git a/SRC/recorder/RemoveRecorder.cpp b/SRC/recorder/RemoveRecorder.cpp index 85bdd39454..a0ac335d8f 100644 --- a/SRC/recorder/RemoveRecorder.cpp +++ b/SRC/recorder/RemoveRecorder.cpp @@ -61,10 +61,384 @@ #include #include +#include +#include +#include #include using std::ios; +void *OPS_RemoveRecorder() { + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "WARNING recorder Collapse -ele eleID " + "-node nodeID <-time> <-file fileName?> ? " + << "\n or recorder Collapse -ele eleID1 ? " + "<-sec secID1? secID2? ...> -crit crit1? value1?" + << " <-crit crit2? value2?> <-time> <-file fileName?> " + "<-mass mass1? mass2? ...> <-g gAcc gDir? gPat?>?\n"; + return 0; + } + + // current maximum number of either-or criteria for an element + int maxNumCriteria = 2; + double dT = 0.0; + bool echoTime = false; + int endEleIDs = 2; + int numEle = endEleIDs - 2; + int loc = endEleIDs; + int flags = 0; + int eleData = 0; + int nodeTag = 0; + // new + int nTagbotn = 0; + int nTagmidn = 0; + int nTagtopn = 0; + int globgrav = 0; + const char *fileNameinf = 0; + // end of new + int numSecondaryEle = 0; + + // create an ID to hold ele tags + // ID eleIDs(numEle, numEle+1); + ID eleIDs; + eleIDs = ID(1); + ID secondaryEleIDs = ID(1); + secondaryEleIDs[0] = 0; + bool secondaryFlag = false; + ID secIDs; + // secIDs = 0; + + // optional mass and weight definition + Vector eleMass(1); + eleMass.Zero(); + double gAcc = 0; + int gDir = 0, gPat = 0; + + Vector remCriteria(2 * maxNumCriteria); + remCriteria.Zero(); + int numCrit = 0; + const char *fileName = 0; + + OPS_Stream *theOutputStream = 0; + + Domain *domain = OPS_GetDomain(); + while (flags == 0 && OPS_GetNumRemainingInputArgs() > 0) { + const char *opt = OPS_GetString(); + if (strcmp(opt, "-node") == 0) { + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING need nodeTag\n"; + return 0; + } + int num = 1; + if (OPS_GetIntInput(&num, &nodeTag) < 0) { + opserr << "WARNING recorder Collapse -node - invalid node " + "tag\n"; + return 0; + } + + Node *theNode = domain->getNode(nodeTag); + if (theNode == 0) { + opserr + << "WARNING recorder Collapse -node - invalid node \n"; + return 0; + } + + } else if (strcmp(opt, "-file_infill") == 0 && + OPS_GetNumRemainingInputArgs() > 0) { + fileNameinf = OPS_GetString(); + + } else if (strcmp(opt, "-checknodes") == 0) { + if (OPS_GetNumRemainingInputArgs() < 3) { + opserr << "WARNING need nTagbotn nTagmidn, nTagtopn\n"; + return 0; + } + int data[3], num = 3; + if (OPS_GetIntInput(&num, &data[0]) < 0) { + opserr << "WARNING recorder Collapse -node - invalid " + "nTagbotn " + "nTagmidn, or nTagtopn \n"; + return 0; + } + nTagbotn = data[0]; + nTagmidn = data[1]; + nTagtopn = data[2]; + + } else if (strcmp(opt, "-global_gravaxis") == 0) { + if (OPS_GetNumRemainingInputArgs() < 3) { + opserr << "WARNING need globgrav\n"; + return 0; + } + int num = 1; + if (OPS_GetIntInput(&num, &globgrav) < 0) { + opserr << "WARNING recorder Collapse -global_gravaxis - " + "invalid global axis for gravity \n"; + return 0; + } + + } else if ((strcmp(opt, "-slave") == 0) || + (strcmp(opt, "-secondary") == 0)) { + secondaryFlag = true; + + } else if ((strcmp(opt, "-ele") == 0) || + (strcmp(opt, "-eles") == 0) || + (strcmp(opt, "-element") == 0)) { + // ensure no segmentation fault if user messes up + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING recorder Collapse .. -ele tag1? .. - " + "no ele tags specified\n"; + return 0; + } + + const char *all = OPS_GetString(); + if (strcmp(all, "all") == 0) { + ElementIter &theEleIter = domain->getElements(); + Element *theEle; + while ((theEle = theEleIter()) != 0) { + eleIDs[numEle++] = theEle->getTag(); + } + } else { + OPS_ResetCurrentInputArg(-1); + // + // read in a list of ele until end of command or other flag + // + while (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + int eleTag; + if (OPS_GetIntInput(&num, &eleTag) < 0) { + OPS_ResetCurrentInputArg(-1); + break; + } + if (!secondaryFlag) { + eleIDs[numEle++] = eleTag; + } else { + secondaryEleIDs[numSecondaryEle++] = eleTag; + } + } + secondaryFlag = false; + } + + } else if (strcmp(opt, "-eleRange") == 0) { + // ensure no segmentation fault if user messes up + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "WARNING recorder Element .. -eleRange start? " + "end? .. - no ele tags specified\n"; + return 0; + } + + // + // read in start and end tags of two elements & add set + // [start,end] + // + int startend[2]; + int num = 2; + if (OPS_GetIntInput(&num, &startend[0]) < 0) { + opserr << "WARNING recorder Element -eleRange start? end? " + "- invalid start or end\n"; + return 0; + } + if (startend[0] > startend[1]) { + int swap = startend[1]; + startend[1] = startend[0]; + startend[0] = swap; + } + for (int i = startend[0]; i <= startend[1]; ++i) { + if (!secondaryFlag) { + eleIDs[numEle++] = i; + } else { + secondaryEleIDs[numSecondaryEle++] = i; + } + } + secondaryFlag = false; + + } else if (strcmp(opt, "-region") == 0) { + // allow user to specif elements via a region + + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING recorder Element .. -region tag? .. - " + "no region specified\n"; + return 0; + } + int tag; + int num = 1; + if (OPS_GetIntInput(&num, &tag) < 0) { + opserr << "WARNING recorder Element -region tag? - " + "invalid tag \n"; + return 0; + } + MeshRegion *theRegion = domain->getRegion(tag); + if (theRegion == 0) { + opserr << "WARNING recorder Element -region " << tag + << " - region does not exist\n"; + return 0; + } + const ID &eleRegion = theRegion->getElements(); + for (int i = 0; i < eleRegion.Size(); i++) { + if (secondaryFlag == false) { + eleIDs[numEle++] = eleRegion(i); + } else { + secondaryEleIDs[numSecondaryEle++] = eleRegion(i); + } + } + secondaryFlag = false; + + } else if ((strcmp(opt, "-time") == 0) || + (strcmp(opt, "-load") == 0)) { + // allow user to specify const load + echoTime = true; + } + + else if (strcmp(opt, "-dT") == 0) { + // allow user to specify time step size for recording + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING: no dT is given\n"; + return 0; + } + int num = 1; + if (OPS_GetDoubleInput(&num, &dT) < 0) { + opserr << "WARNING: failed to get dT\n"; + return 0; + } + } + + else if (strcmp(opt, "-file") == 0) { + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING: no fileName is given\n"; + return 0; + } + fileName = OPS_GetString(); + // simulationInfo.addWriteFile(fileName); + } + + else if ((strcmp(opt, "-mass") == 0)) { + if (OPS_GetNumRemainingInputArgs() < numEle) { + opserr << "WARNING: need numEle mass values\n"; + return 0; + } + eleMass.resize(numEle); + eleMass.Zero(); + if (OPS_GetDoubleInput(&numEle, &eleMass(0)) < 0) { + opserr << "WARNING: failed to get mass\n"; + return 0; + } + } + + else if ((strcmp(opt, "-g") == 0)) { + if (OPS_GetNumRemainingInputArgs() < 3) { + opserr << "WARNING: need gAcc, gDir, gPat\n"; + return 0; + } + int num = 3; + double data[3]; + if (OPS_GetDoubleInput(&num, &data[0]) < 0) { + opserr << "WARNING: failed to read gAcc, gDir, gPat\n"; + return 0; + } + + gAcc = data[0]; + gDir = data[1]; + gPat = data[2]; + } + + else if ((strcmp(opt, "-section") == 0) || + (strcmp(opt, "-sec") == 0) || + (strcmp(opt, "-comp") == 0)) { + while (OPS_GetNumRemainingInputArgs() > 0) { + int num = 1; + int secID; + if (OPS_GetIntInput(&num, &secID) < 0) { + OPS_ResetCurrentInputArg(-1); + break; + } + secIDs.insert(secID); + } + } + + else if (strcmp(opt, "-criteria") == 0 || + strcmp(opt, "-crit") == 0) { + int critTag = 0; + double critValue = 0; + + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING: need criteria type\n"; + return 0; + } + + const char *opt1 = OPS_GetString(); + if (strcmp(opt1, "minStrain") == 0) { + critTag = 1; + } else if (strcmp(opt1, "maxStrain") == 0) { + critTag = 2; + } else if (strcmp(opt1, "axialDI") == 0) { + critTag = 3; + + } else if (strcmp(opt1, "flexureDI") == 0) { + critTag = 4; + + } else if (strcmp(opt1, "axialLS") == 0) { + critTag = 5; + } else if (strcmp(opt1, "shearLS") == 0) { + critTag = 6; + + } else if (strcmp(opt1, "INFILLWALL") == 0) { + critTag = 7; + + } else { + opserr << "Error: RemoveRecorder - Removal Criteria " + << opt1 << " not recognized\n"; + return 0; + } + + if (critTag != 7) { + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING: need criteria value\n"; + return 0; + } + int num = 1; + if (OPS_GetDoubleInput(&num, &critValue) < 0) { + opserr << "WARNING recorder Remove -crit critTag? " + "critValue?... invalid critValue \n"; + return 0; + } + } + + remCriteria[2 * numCrit] = critTag; + // new + if (critTag != 7) { + remCriteria[2 * numCrit + 1] = critValue; + } else { + remCriteria[2 * numCrit + 1] = 100.0; + } + numCrit++; + if (critTag != 7) { + loc += 3; + } else { + loc += 2; + secIDs = ID(1); + secIDs[1] = 1; // this is not used directly, gets rid of + // the "-sec" for infillwall + } + } else { + flags = 1; + } + + // if user has specified no element tags lets assume he wants them + // all + if (numEle == 0) { + ElementIter &theEleIter = domain->getElements(); + Element *theEle; + while ((theEle = theEleIter()) != 0) { + eleIDs[numEle++] = theEle->getTag(); + } + } + } + theOutputStream = new DummyStream(); + + return new RemoveRecorder( + nodeTag, eleIDs, secIDs, secondaryEleIDs, remCriteria, *domain, + *theOutputStream, echoTime, dT, fileName, eleMass, gAcc, gDir, + gPat, nTagbotn, nTagmidn, nTagtopn, globgrav, fileNameinf); +} + //#define MMTDEBUG //#define MMTDEBUGIO @@ -90,7 +464,7 @@ ofstream RemoveRecorder::theFile; RemoveRecorder::RemoveRecorder(int nodeID, ID &eleIDs, ID &secIDs, - ID &slaveTags, + ID &secondaryTags, Vector remCriteria, Domain &theDomainPtr, OPS_Stream &s, @@ -114,8 +488,8 @@ RemoveRecorder::RemoveRecorder(int nodeID, numSecs(secIDs.Size()), criteria(remCriteria), theDomain(&theDomainPtr), - slaveEleTags(slaveTags.Size()), - slaveFlag(false), + secondaryEleTags(secondaryTags.Size()), + secondaryFlag(false), echoTimeFlag(echotimeflag), deltaT(deltat), nextTimeStampToRecord(0.0), @@ -157,16 +531,16 @@ RemoveRecorder::RemoveRecorder(int nodeID, } else secTags[0] = 0; - if (slaveTags[0] != 0 || slaveTags.Size() != 1) { - slaveFlag = true; - for (int l=0 ; lelimSecondaries(timeStamp) != 0) { + opserr<<"Error: Collapse Recorder - failed to remove secondary components to element "<getElement(slaveEleTags[i]); - ID slaveNodes = theEle->getExternalNodes(); + Element *theEle = theDomain->getElement(secondaryEleTags[i]); + ID secondaryNodes = theEle->getExternalNodes(); for (int k = 0; kgetNumExternalNodes(); k++) { int nodeRemFlag = 0; for (int m =0; melimNode(slaveNodes[k], timeStamp); + this->elimNode(secondaryNodes[k], timeStamp); #ifdef MMTDEBUG - opserr<<" eliminated node "<elimElem(slaveEleTags[i], timeStamp); + this->elimElem(secondaryEleTags[i], timeStamp); #ifdef MMTDEBUG - opserr<<" eliminated element "< @@ -94,13 +96,6 @@ extern void* OPS_VTK_Recorder(); //extern TclModelBuilder *theDamageTclModelBuilder; - extern int OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain); - typedef struct externalRecorderCommand { char *funcName; void *(*funcPtr)(); @@ -654,15 +649,15 @@ enum outputMode {STANDARD_STREAM, DATA_STREAM, XML_STREAM, DATABASE_STREAM, BIN const char *fileNameinf = 0; // end of new - int numSlaveEle = 0; + int numSecondaryEle = 0; // create an ID to hold ele tags //ID eleIDs(numEle, numEle+1); ID eleIDs; eleIDs = ID(1); - ID slaveEleIDs = ID(1); - slaveEleIDs[0] = 0; - bool slaveFlag = false; + ID secondaryEleIDs = ID(1); + secondaryEleIDs[0] = 0; + bool secondaryFlag = false; ID secIDs = 0; // secIDs = 0; @@ -731,8 +726,8 @@ enum outputMode {STANDARD_STREAM, DATA_STREAM, XML_STREAM, DATABASE_STREAM, BIN // end of new - else if ((strcmp(argv[loc],"-slave") == 0)) { - slaveFlag = true; + else if ((strcmp(argv[loc],"-slave") == 0) || (strcmp(argv[loc],"-secondary") == 0)) { + secondaryFlag = true; loc++; } @@ -752,11 +747,11 @@ enum outputMode {STANDARD_STREAM, DATA_STREAM, XML_STREAM, DATABASE_STREAM, BIN loc++; int eleTag; while (loc < argc && Tcl_GetInt(interp, argv[loc], &eleTag) == TCL_OK) { - if (slaveFlag == false) + if (secondaryFlag == false) eleIDs[numEle++] = eleTag; else - slaveEleIDs[numSlaveEle++] = eleTag; - slaveFlag = false; + secondaryEleIDs[numSecondaryEle++] = eleTag; + secondaryFlag = false; loc++; } @@ -805,12 +800,12 @@ enum outputMode {STANDARD_STREAM, DATA_STREAM, XML_STREAM, DATABASE_STREAM, BIN } for (int i=start; i<=end; i++) - if (slaveFlag == false) + if (secondaryFlag == false) eleIDs[numEle++] = i; else - slaveEleIDs[numSlaveEle++] = i; + secondaryEleIDs[numSecondaryEle++] = i; - slaveFlag = false; + secondaryFlag = false; loc += 3; } @@ -833,12 +828,12 @@ enum outputMode {STANDARD_STREAM, DATA_STREAM, XML_STREAM, DATABASE_STREAM, BIN } const ID &eleRegion = theRegion->getElements(); for (int i=0; i +#include "eigenSOE/EigenSOE.h" #include class AnalysisModel; diff --git a/SRC/system_of_eqn/linearSOE/bandGEN/DistributedBandGenLinSOE.cpp b/SRC/system_of_eqn/linearSOE/bandGEN/DistributedBandGenLinSOE.cpp index 1e4030b9b1..657659d0f7 100644 --- a/SRC/system_of_eqn/linearSOE/bandGEN/DistributedBandGenLinSOE.cpp +++ b/SRC/system_of_eqn/linearSOE/bandGEN/DistributedBandGenLinSOE.cpp @@ -113,7 +113,7 @@ DistributedBandGenLinSOE::setSize(Graph &theGraph) else { // from each distributed soe recv it's graph - // and merge them into master graph + // and merge them into primary graph FEM_ObjectBroker theBroker; for (int j=0; jrecvID(0, 0, otherSize); diff --git a/SRC/system_of_eqn/linearSOE/fullGEN/FullGenLinLapackSolver.h b/SRC/system_of_eqn/linearSOE/fullGEN/FullGenLinLapackSolver.h index 56f361dd07..643c7e7bb3 100644 --- a/SRC/system_of_eqn/linearSOE/fullGEN/FullGenLinLapackSolver.h +++ b/SRC/system_of_eqn/linearSOE/fullGEN/FullGenLinLapackSolver.h @@ -38,7 +38,7 @@ #ifndef FullGenLinLapackSolver_h #define FullGenLinLapackSolver_h -#include +#include "FullGenLinSolver.h" class FullGenLinLapackSolver : public FullGenLinSolver { diff --git a/SRC/system_of_eqn/linearSOE/petsc/PetscSOE.cpp b/SRC/system_of_eqn/linearSOE/petsc/PetscSOE.cpp index 19fa60c149..8a1619a82e 100644 --- a/SRC/system_of_eqn/linearSOE/petsc/PetscSOE.cpp +++ b/SRC/system_of_eqn/linearSOE/petsc/PetscSOE.cpp @@ -17,21 +17,19 @@ ** Filip C. Filippou (filippou@ce.berkeley.edu) ** ** ** ** ****************************************************************** */ - -// $Revision: 1.7 $ -// $Date: 2010-02-25 23:21:31 $ -// $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/linearSOE/petsc/PetscSOE.cpp,v $ - -// Written: fmk & om -// Created: 7/98 -// Revision: A -// + // Description: This file contains the implementation for PetscSOE +#include + -#include "PetscSOE.h" -#include "PetscSolver.h" +#include +#include +#include +#include #include +#include + #include #include #include @@ -41,364 +39,824 @@ #include #include -PetscSOE::PetscSOE(PetscSolver &theSOESolver, int bs) -:LinearSOE(theSOESolver, LinSOE_TAGS_PetscSOE), - isFactored(0),size(0), processID(0), numProcesses(0), B(0), X(0), - indices(0), vectX(0), vectB(0), A(0), x(0), b(0), blockSize(bs), - numChannels(0), theChannels(0), localCol(0) + +#include +#include +#include +#include +#include +#include +#include + + +using namespace std; + + + + +PetscSOE::PetscSOE(PetscSolver &theSOESolver, MatType matType, int bs) + : LinearSOE(theSOESolver, LinSOE_TAGS_PetscSOE), + isFactored(0), size(0), processID(0), numProcesses(0), B(0), X(0), + indices(0), vectX(0), vectB(0), A(0), M(0), x(0), b(0), blockSize(bs), + numChannels(0), theChannels(0), localCol(0), mType(matType) { theSOESolver.setLinearSOE(*this); + init_done = false; + startRow = -1; + endRow = -1; } - int PetscSOE::getNumEqn(void) const { return size; } - + PetscSOE::~PetscSOE() { + cout << "PetscSOE::~PetscSOE()\n"; if (theChannels != 0) + { delete [] theChannels; + } if (localCol != 0) - for (int i=0; i= 0) + { + cout << "Processor " << processID << " printing PETSc log\n"; + PetscViewer viewer; + + PetscViewerASCIIGetStdout(PETSC_COMM_WORLD, &viewer); + PetscLogView(viewer); + PetscFinalize(); + } + + } -int +int PetscSOE::setSize(Graph &theGraph) { - PetscInitialize(0, PETSC_NULL, (char *)0, PETSC_NULL); - MPI_Comm_size(PETSC_COMM_WORLD, &numProcesses); - MPI_Comm_rank(PETSC_COMM_WORLD, &processID); - int result = 0; int ierr = 0; - // - // first determine system size - // - - if (numProcesses == 1) { - - // if single process, the system size is size of graph - size = theGraph.getNumVertex(); - isFactored = 0; - - } else { - - // first determine local max - size = 0; - isFactored = 0; - VertexIter &theVertices = theGraph.getVertices(); - Vertex *theVertex; - while ((theVertex = theVertices()) != 0) { - int vertexTag = theVertex->getTag(); - if (vertexTag > size) - size = vertexTag; - } - static ID data(1); - - // all local max's sent to P0 which determines the max - // and informs all others - - if (processID != 0) { - Channel *theChannel = theChannels[0]; - - data(0) = size; - theChannel->sendID(0, 0, data); - theChannel->recvID(0, 0, data); - - size = data(0); - } else { - - for (int j=0; jrecvID(0, 0, data); - if (data(0) > size) - size = data(0); - } - data(0) = size; - for (int j=0; jsendID(0, 0, data); - } + + + if (!init_done) + { + + MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); + MPI_Comm_rank(MPI_COMM_WORLD, &processID); + + //Check if petsc_options.txt is present + if (FILE *file = fopen(PETSCSOE_PETSCOPTIONS_FILENAME, "r")) + { + fclose(file); + cout << " + PetscSOE::setSize() [" << processID << "] : Found petsc_options.txt file. \n"; + PetscInitialize(0, PETSC_NULL, PETSCSOE_PETSCOPTIONS_FILENAME, "PetscSOE::setSize - Initialize with file"); + PetscPopSignalHandler(); + } + else + { + PetscInitialize(0, PETSC_NULL, (char *)0, "PetscSOE::setSize - Initialize"); + PetscPopSignalHandler(); + } + + PetscLogAllBegin(); + + + init_done = true; + } + + + // + // first determine system size + // + + PETSCSOE_DEBUGOUT << " + PetscSOE::setSize() [" << processID << "] : Getting local max dof tag\n"; + + // Size of the system is the maximum DOF tag + 1 + + // Each processor visits its DOF graph and determines the maximum DOF tag + // for its domain. + Vertex* theVertex; + VertexIter& theVertices = theGraph.getVertices(); + + #ifdef max // This is needed because, to my frustration, someone, somewhere overloaded max() + #undef max // Angrily, J. Abell + #endif + + int mindoftag = std::numeric_limits::max(); + int maxdoftag = 0; + + while ((theVertex = theVertices()) != 0) + { + int tag = theVertex->getTag(); + + if (tag > maxdoftag) + { + maxdoftag = tag; + } + if (tag < mindoftag) + { + mindoftag = tag; + } + } + size = maxdoftag; + + + // Then, all maximumg tags (size) are sent to P0 which gets the global maximum. + + PETSCSOE_DEBUGOUT << " + PetscSOE::setSize() [" << processID << "] : Determining global maximum dof tag\n"; + isFactored = 0; + static ID data(1); + if (processID != 0) + { + Channel *theChannel = theChannels[0]; + + data(0) = size; + theChannel->sendID(0, 0, data); + theChannel->recvID(0, 0, data); + + size = data(0); + } + else + { + + for (int j = 0; j < numChannels; j++) + { + Channel *theChannel = theChannels[j]; + theChannel->recvID(0, 0, data); + + if (data(0) > size) + { + size = data(0); } - size = size+1; // vertices numbered 0 through n-1 } - // invoke the petsc destructors - if (A != 0) MatDestroy(A); - if (b != 0) VecDestroy(b); - if (x != 0) VecDestroy(x); - - // - // now we create the opensees vector objects - // + data(0) = size; - // delete the old vectors - if (B != 0) delete [] B; - if (X != 0) delete [] X; - - // create the new - B = new double[size]; - X = new double[size]; - - if (B == 0 || X == 0) { - opserr << "WARNING PetscSOE::PetscSOE :"; - opserr << " ran out of memory for vectors (size) ("; - opserr << size << ") \n"; - size = 0; - result = -1; + for (int j = 0; j < numChannels; j++) + { + Channel *theChannel = theChannels[j]; + theChannel->sendID(0, 0, data); } - - // zero the vectors - for (int j=0; j= 0) + { + + PETSCSOE_DEBUGOUT << " + PetscSOE::setSize() - [" << processID << "] : Initializing PETSc\n"; + // PetscOptionsGetInt(PETSC_NULL, "-n", &size, PETSC_NULL); + + ierr = MatCreate(PETSC_COMM_WORLD, &A); + CHKERRQ(ierr); + + + ierr = MatSetType(A, MATMPIAIJ); + CHKERRQ(ierr); + + + int ndofs = nlocaldofs[processID]; + + // Performance opportunity. + //Can use 2nd and 3rd parameters to customize which rows belong to what processor. + // ierr = MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, size, size); + ierr = MatSetSizes(A, ndofs, ndofs, size, size); + // CHKERRQ(ierr); + + + // Disable auto-ownership + // MatGetOwnershipRange(A, &startRow, &endRow); + + PETSCSOE_DEBUGOUT << " + PetscSOE::setSize() - Process " << processID << " owns rows from " << startRow << " to " << endRow << endl; + + //Define custom ownership + PetscInt* d_nnz[numProcesses]; + PetscInt* o_nnz[numProcesses]; + PetscInt d_nnz_global[ndofs]; + PetscInt o_nnz_global[ndofs]; + + for (int proc = 0; proc < numProcesses; proc++) + { + int ndofs_proc = nlocaldofs[proc]; + d_nnz[proc] = new PetscInt[ndofs_proc]; + o_nnz[proc] = new PetscInt[ndofs_proc]; } - - if (vectX != 0) - delete vectX; - - if (vectB != 0) - delete vectB; - - vectX = new Vector(X, size); - vectB = new Vector(B, size); - // - // now create petsc matrix and vector objects - // + + // Initialize diagonal to at least one nonzero element (the diagonal) for current proc + // Initialize off-diagonal to zero + for (int proc = 0; proc < numProcesses; proc++) + { + PetscInt dval = 0; + if (proc == processID) + { + dval = 1; + } - if (numProcesses == 1) { - - // we determine the number of non-zeros & number of nonzero's - // in each row of A - int *rowA = new int[size]; // will contain no of non-zero entries - // in each row - - int NNZ = 0; - for (int a=0; agetAdjacency(); - int idSize = theAdjacency.Size(); - - NNZ += idSize +1; - rowA[a] = idSize +1; // +1 for the diagonal entry + for (int row = 0; row < nlocaldofs[proc]; row++) + { + d_nnz[proc][row] = dval; + o_nnz[proc][row] = 0; } + } + + //Iterate the vertices again to determine the number of nonzeros at each dof.... + Vertex* theVertex; + VertexIter& theVertices = theGraph.getVertices(); + + while ((theVertex = theVertices()) != 0) + { + int dof = theVertex->getTag(); + const ID& adj = theVertex->getAdjacency(); + //Iterate over adjacent dofs and determine whether they are in the "diagonal" block of the PETSc matrix + // or not.... + // Diagonal here means that the adjacent dof also belongs to this processor + for (int i = 0; i < adj.Size(); i++) + { + int col = adj(i); + + for (int proc = 0; proc < numProcesses; proc++) + { + // If the dof number belongs to this processor + if ( startRow_vec[proc] <= dof && dof <= endRow_vec[proc] ) + { + int row = dof - startRow_vec[proc]; + if ( startRow_vec[proc] <= col && col <= endRow_vec[proc] ) + { + d_nnz[proc][row ] += 1; + } + else + { + o_nnz[proc][row ] += 1; + } + } + + // Check the symmetric condition of this (dofs are symmetricly connected!) + // If the dof number belongs to this processor + if ( startRow_vec[proc] <= col && col <= endRow_vec[proc] ) + { + int row = col - startRow_vec[proc]; + if ( startRow_vec[proc] <= dof && dof <= endRow_vec[proc] ) + { + d_nnz[proc][row ] += 1; + } + else + { + o_nnz[proc][row ] += 1; + } + } + } + } + } + + // Now reduce the arrays to one global one in the local processor + for (int proc = 0; proc < numProcesses; proc++) + { + MPI_Reduce( + d_nnz[proc], + d_nnz_global, + nlocaldofs[proc], + MPI_INT, + MPI_SUM, + proc , // Because this is the process number in the petsc_comm communicator + PETSC_COMM_WORLD); + MPI_Reduce( + o_nnz[proc], + o_nnz_global, + nlocaldofs[proc], + MPI_INT, + MPI_SUM, + proc , // Because this is the process number in the petsc_comm communicator + PETSC_COMM_WORLD); + } - // - // Call Petsc VecCreate & MatCreate; NOTE: using previously allocated storage for vectors - // - // ierr = PetscOptionsGetInt(PETSC_NULL, "-n", &size, &flg); CHKERRQ(ierr); - - if (blockSize == 1) { - ierr = MatCreateSeqAIJ(PETSC_COMM_SELF, size, size, 0, rowA, &A); CHKERRQ(ierr); - } else { - ierr = MatCreateSeqBAIJ(PETSC_COMM_SELF, blockSize, size,size, 0, rowA, &A); CHKERRQ(ierr); + + + for (int row = 0; row < nlocaldofs[processID]; row++) + { + if (d_nnz_global[row] < PETSCSOE_MIN_DNNZ) + { + d_nnz_global[row] = PETSCSOE_MIN_DNNZ; + } + if (o_nnz_global[row] < PETSCSOE_MIN_ONNZ) + { + o_nnz_global[row] = PETSCSOE_MIN_ONNZ; + } + if (d_nnz_global[row] > ndofs) + { + d_nnz_global[row] = ndofs; + } + if (o_nnz_global[row] > ndofs) + { + o_nnz_global[row] = ndofs; } - - ierr = VecCreateSeqWithArray(PETSC_COMM_WORLD, size, X, &x); CHKERRQ(ierr); - ierr = VecCreateSeqWithArray(PETSC_COMM_WORLD, size, B, &b); CHKERRQ(ierr); - - // invoke setSize() on the Solver - LinearSOESolver *tSolver = this->getSolver(); - int solverOK = tSolver->setSize(); - if (solverOK < 0) { - opserr << "WARNING:PetscSOE::setSize :"; - opserr << " solver failed setSize()\n"; - return solverOK; - } - - // clear up the memory we used - delete [] rowA; - - - } else { - - // - // Call Petsc VecCreate & MatCreate; NOTE: using previously allocated storage for vectors - // - // - - ierr = PetscOptionsGetInt(PETSC_NULL, "-n", &size, &flg); CHKERRQ(ierr); - // ierr = MatCreateMPIAIJ(PETSC_COMM_WORLD, PETSC_DECIDE, PETSC_DECIDE,size, size, &A); CHKERRQ(ierr); - ierr = MatCreate(PETSC_COMM_WORLD, &A); CHKERRQ(ierr); - ierr = MatSetFromOptions(A);CHKERRQ(ierr); - ierr = MatGetOwnershipRange(A, &startRow, &endRow);CHKERRQ(ierr); - - ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD, endRow-startRow, size, &X[startRow], &x); CHKERRQ(ierr); - ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD, endRow-startRow, size, &B[startRow], &b); CHKERRQ(ierr); - - // invoke setSize() on the Solver - LinearSOESolver *tSolver = this->getSolver(); - int solverOK = tSolver->setSize(); - if (solverOK < 0) { - opserr << "WARNING:PetscSOE::setSize :"; - opserr << " solver failed setSize()\n"; - return solverOK; - } - } - - return result; + } + + + // ierr = MatCreateAIJ(PETSC_COMM_WORLD, ndofs, ndofs, size, size, 0, d_nnz, 0, o_nnz, &A); + // CHKERRQ(ierr); + + // PetscErrorCode MatMPIAIJSetPreallocation(Mat B,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[]) + // B - the matrix + // d_nz - number of nonzeros per row in DIAGONAL portion of local submatrix (same value is used for all local rows) + // d_nnz - array containing the number of nonzeros in the various rows of the DIAGONAL portion of the local submatrix (possibly different for each row) or NULL (PETSC_NULL_INTEGER in Fortran), if d_nz is used to specify the nonzero structure. The size of this array is equal to the number of local rows, i.e 'm'. For matrices that will be factored, you must leave room for (and set) the diagonal entry even if it is zero. + // o_nz - number of nonzeros per row in the OFF-DIAGONAL portion of local submatrix (same value is used for all local rows). + // o_nnz - array containing the number of nonzeros in the various rows of the OFF-DIAGONAL portion of the local submatrix (possibly different for each row) or NULL (PETSC_NULL_INTEGER in Fortran), if o_nz is used to specify the nonzero structure. The size of this array is equal to the number of local rows, i.e 'm'. + + MatMPIAIJSetPreallocation(A, 0, d_nnz_global, 0, o_nnz_global); + + // ierr = MatMPIAIJSetPreallocation(A, 650, PETSC_NULL, 650, PETSC_NULL); + // ierr = MatMPIAIJSetPreallocation(A, 650, PETSC_NULL, 650, PETSC_NULL); + + // CHKERRQ(ierr); + // ierr = MatSeqAIJSetPreallocation(A, 650 , PETSC_NULL); + // CHKERRQ(ierr); + + + MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE); + + + + ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD, blockSize, ndofs , size, &X[startRow], &x); + CHKERRQ(ierr); + ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD, blockSize, ndofs , size, &B[startRow], &b); + CHKERRQ(ierr); + + for (int proc = 0; proc < numProcesses; proc++) + { + delete [] d_nnz[proc]; + delete [] o_nnz[proc]; + } + + // cout << "Preallocation done! " << endl; + } + else + { + // cout << "Process " << processID << " owns rows from " << startRow << " to " << endRow << endl; + } + + // invoke setSize() on the Solver + LinearSOESolver *tSolver = this->getSolver(); + int solverOK = tSolver->setSize(); + + if (solverOK < 0) + { + cerr << "WARNING:PetscSOE::setSize :"; + cerr << " solver failed setSize()\n"; + return solverOK; + } + + // MatGetOwnershipRange(A, &startRow, &endRow); + + + PETSCSOE_DEBUGOUT << "Process " << processID << " owns rows from " << startRow << " to " << endRow << endl; + + + return result; +} + + + +int +PetscSOE::setSize(int MaxDOFtag) +{ + int result = -1; + cerr << "PetscSOE::setSize(int MaxDOFtag) -- DEPRECATED! Should not get called\n"; + + return result; + } -int +int PetscSOE::addA(const Matrix &m, const ID &id, double fact) { - isFactored = 0; - // check for a quick return - if (fact == 0.0) return 0; + if (processID >= 0) + { + isFactored = 0; + + // check for a quick return + if (fact == 0.0) + { + return 0; + } + - // check that m and id are of similar size - int idSize = id.Size(); - if (idSize != m.noRows() && idSize != m.noCols()) { - opserr << "PetscSOE::addA() - Matrix and ID not of similar sizes\n"; - return -1; + int idSize = id.Size(); + + if (idSize != m.noRows() && idSize != m.noCols()) + { + cerr << "PetscSOE::addA() - Matrix and ID not of similar sizes\n"; + return -1; } - + int n = id.Size(); - int row; - int col; - double value; - for (int i=0; i= 0) { - for (int j=0; j= 0) { - value = m(i,j)*fact; - int ierr = MatSetValues(A,1,&row,1,&col,&value,ADD_VALUES); - if (ierr) opserr << processID << " " << row << " " << col << endln; - CHKERRQ(ierr); - } - } + + + int indx_ij[n ]; + + double values[n * n]; + + + // const int * iddata = id.getData(); + // const double * matdata = m.getData(); + int pos = 0; + int nsmall = 0; + + for (int i = 0; i < n; i++) + { + if (id(i) >= 0) + { + indx_ij[nsmall] = id(i); + nsmall++; } } - return 0; + int ii = 0; + for (int i = 0; i < n; i++) + { + int jj = 0; + if (id(i) >= 0) + { + for (int j = 0; j < n; j++) // Row-major, like C + { + if (id(j) >= 0) + { + values[ii * nsmall + jj] = m(i, j) * fact; + pos++; + jj++; + } + } + ii++; + } + } + + int ierr = MatSetValues(A, nsmall, indx_ij, nsmall, indx_ij, values, ADD_VALUES); + + CHKERRQ(ierr); + } + + return 0; } - -int + +int PetscSOE::addB(const Vector &v, const ID &id, double fact) { - // check for a quick return - if (fact == 0.0) return 0; + if (processID >= 0) + { + // check for a quick return + if (fact == 0.0) + { + return 0; + } // check that m and id are of similar size - int idSize = id.Size(); - if (idSize != v.Size() ) { - opserr << "BandGenLinSOE::addB() - Vector and ID not of similar sizes\n"; - return -1; - } - - if (fact == 1.0) { // do not need to multiply if fact == 1.0 - for (int i=0; i= 0) - B[pos] += v(i); - } - } else if (fact == -1.0) { - for (int i=0; i= 0) - B[pos] -= v(i); - } - } else { - for (int i=0; i= 0) - B[pos] += v(i) * fact; - } - } - return 0; + int idSize = id.Size(); + + if (idSize != v.Size() ) + { + cerr << "addB::addB() - Vector and ID not of similar sizes\n"; + return -1; + } + + if (fact == 1.0) // do not need to multiply if fact == 1.0 + { + for (int i = 0; i < idSize; i++) + { + int pos = id(i); + + if (pos < size && pos >= 0) + { + B[pos] += v(i); + if (B[pos] != B[pos]) + { + cerr << "PetscSOE::addB() - rank = " << processID << "- NaN found! At pos=" << pos << endl; + return -1; + } + } + } + } + else if (fact == -1.0) + { + for (int i = 0; i < idSize; i++) + { + int pos = id(i); + + if (pos < size && pos >= 0) + { + B[pos] -= v(i); + } + } + } + else + { + for (int i = 0; i < idSize; i++) + { + int pos = id(i); + + if (pos < size && pos >= 0) + { + B[pos] += v(i) * fact; + } + } + } + } + + return 0; } int PetscSOE::setB(const Vector &v, double fact) { - // check for a quick return - if (fact == 0.0) return 0; + if (processID >= 0) + { + // check for a quick return + if (fact == 0.0) + { + return 0; + } - if (v.Size() != size) { - opserr << "WARNING BandGenLinSOE::setB() -"; - opserr << " incompatible sizes " << size << " and " << v.Size() << endln; - return -1; + if (v.Size() != size) + { + cerr << "WARNING BandGenLinSOE::setB() -"; + cerr << " incomptable sizes " << size << " and " << v.Size() << endln; + return -1; } - - if (fact == 1.0) { // do not need to multiply if fact == 1.0 - for (int i=0; i= 0 ) + { + MatZeroEntries(A); + } } - -void + +void PetscSOE::zeroB(void) { + // if ( processID_world > 0 ) + // { + double *Bptr = B; - for (int i=0; i 1) { - if (myVectorB.Size() != size) - myVectorB.resize(size); - - if (processID != 0) { - Channel *theChannel = theChannels[0]; - - theChannel->sendVector(0, 0, *vectB); - theChannel->recvVector(0, 0, myVectorB); - } else { - if (recvVector.Size() != size) - recvVector.resize(size); - - myVectorB = *vectB; - for (int j=0; jrecvVector(0, 0, recvVector); - myVectorB += recvVector; - } - for (int j=0; jsendVector(0, 0, myVectorB); - } - } - return myVectorB; + } - } else - return *vectB; + return *vectB; } -double +double PetscSOE::normRHS(void) { this->getB(); - double norm =0.0; + double norm = 0.0; double *Bptr = B; - for (int i=0; i= 0) - X[loc] = value; + { + X[loc] = value; + } } -void +void PetscSOE::setX(const Vector &xData) { if (xData.Size() == size && vectX != 0) + { *vectX = xData; + } } int PetscSOE::setSolver(PetscSolver &newSolver) { - newSolver.setLinearSOE(*this); - - if (size != 0) { - int solverOK = newSolver.setSize(); - if (solverOK < 0) { - opserr << "WARNING:PetscSOE::setSolver :"; - opserr << "the new solver could not setSeize() - staying with old\n"; - return solverOK; - } - } - - return this->LinearSOE::setSolver(newSolver); + newSolver.setLinearSOE(*this); + + if (size != 0) + { + int solverOK = newSolver.setSize(); + + if (solverOK < 0) + { + cerr << "WARNING:PetscSOE::setSolver :"; + cerr << "the new solver could not setSeize() - staying with old\n"; + return solverOK; + } + } + + return this->LinearSOE::setSolver(newSolver); } -int +int PetscSOE::sendSelf(int cTag, Channel &theChannel) { - processID = 0; - int sendID =0; - // if P0 check if already sent. If already sent use old processID; if not allocate a new process - // id for remote part of object, enlarge channel * to hold a channel * for this remote object. + // check if already using this object + bool found = false; - // if not P0, send current processID + for (int i = 0; i < numChannels; i++) + if (theChannels[i] == &theChannel) + { + // sendID = i + 1; + found = true; + } - if (processID == 0) { + // if new object, enlarge Channel pointers to hold new channel * & allocate new ID + if (found == false) + { + int nextNumChannels = numChannels + 1; + Channel **nextChannels = new Channel *[nextNumChannels]; + + if (nextNumChannels == 0) + { + cerr << "DistributedBandGenLinSOE::sendSelf() - failed to allocate channel array of size: " << + nextNumChannels << endln; + return -1; + } - // check if already using this object - bool found = false; - for (int i=0; i= 0) + { + for (int j = 0; j < n; j++) + { + col = id(j); + + if (col >= 0) + { + value = m(i, j) * fact; + int ierr = MatSetValues(M, 1, &row, 1, &col, &value, ADD_VALUES); + + if (ierr) + { + cerr << processID << " " << row << " " << col << endln; + } + + CHKERRQ(ierr); + } + } + } + } + + return 0; +} + + +int +PetscSOE::addK(const Matrix &m, const ID &id, double fact) +{ + + isFactored = 0; + + // check for a quick return + if (fact == 0.0) + { + return 0; + } + + + // check that m and id are of similar size + int idSize = id.Size(); + + if (idSize != m.noRows() && idSize != m.noCols()) + { + std::cerr << "PetscSOE::addM() - Matrix and ID not of similar sizes\n"; + return -1; + } + + int n = id.Size(); + int row; + int col; + double value; + + for (int i = 0; i < n; i++) + { + row = id(i); + + if (row >= 0) + { + for (int j = 0; j < n; j++) + { + col = id(j); + + if (col >= 0) + { + value = m(i, j) * fact; + int ierr = MatSetValues(K, 1, &row, 1, &col, &value, ADD_VALUES); + + if (ierr) + { + cerr << processID << " " << row << " " << col << endln; + } + + CHKERRQ(ierr); + } + } + } + } + + return 0; +} + + +void +PetscSOE::zeroM(void) +{ + isFactored = 0; + MatZeroEntries(M); +} + + + +void +PetscSOE::zeroK(void) +{ + isFactored = 0; + MatZeroEntries(K); +} + + + + +int +PetscSOE::setEigenSize(Graph &theGraph) +{ + + return -1; +} diff --git a/SRC/system_of_eqn/linearSOE/petsc/PetscSOE.h b/SRC/system_of_eqn/linearSOE/petsc/PetscSOE.h index 840f3a6dea..f0dc6135b4 100644 --- a/SRC/system_of_eqn/linearSOE/petsc/PetscSOE.h +++ b/SRC/system_of_eqn/linearSOE/petsc/PetscSOE.h @@ -17,12 +17,12 @@ ** Filip C. Filippou (filippou@ce.berkeley.edu) ** ** ** ** ****************************************************************** */ - -// $Revision: 1.4 $ -// $Date: 2007-02-14 20:12:32 $ + +// $Revision: 1.3 $ +// $Date: 2005/05/18 19:24:49 $ // $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/linearSOE/petsc/PetscSOE.h,v $ - - + + // Written: fmk & om // Created: 7/98 // Revision: A @@ -40,71 +40,98 @@ #include #include -//extern "C" { + #include -//} + +// Uncomment or define -D_DEBUG_PETSCSOE to enable debugging +// #define _DEBUG_PETSCSOE + +#ifdef _DEBUG_PETSCSOE +#define PETSCSOE_DEBUGOUT cout // or any other ostream +#else +#define PETSCSOE_DEBUGOUT 0 && cout +#endif + +#define PETSCSOE_MIN_DNNZ 10 +#define PETSCSOE_MIN_ONNZ 30 +#define PETSCSOE_PETSCOPTIONS_FILENAME "petsc_options.txt" class PetscSolver; class PetscSOE : public LinearSOE { - public: - PetscSOE(PetscSolver &theSolver, int blockSize=1); - +public: + PetscSOE(PetscSolver &theSolver, MatType matType = MATMPIAIJ, int blockSize = 1); + ~PetscSOE(); int getNumEqn(void) const; int setSize(Graph &theGraph); - + int setSize(int MaxDOFtag); + int setEigenSize(Graph &theGraph); + + int addA(const Matrix &, const ID &, double fact = 1.0); - int addB(const Vector &, const ID &, double fact = 1.0); - int setB(const Vector &, double fact = 1.0); + int addB(const Vector &, const ID &, double fact = 1.0); + int addM(const Matrix &, const ID &, double fact = 1.0); + int addK(const Matrix &, const ID &, double fact = 1.0); + + int setB(const Vector &, double fact = 1.0); void zeroA(void); void zeroB(void); + void zeroM(void); + void zeroK(void); const Vector &getX(void); const Vector &getB(void); double normRHS(void); - void setX(int loc, double value); - void setX(const Vector &x); + void setX(int loc, double value); + void setX(const Vector &x); - int setSolver(PetscSolver &newSolver); + int setSolver(PetscSolver &newSolver); int sendSelf(int commitTag, Channel &theChannel); - int recvSelf(int commitTag, Channel &theChannel, - FEM_ObjectBroker &theBroker); - + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + + friend class PetscSolver; friend class ActorPetscSOE; friend class ShadowPetscSOE; - - protected: + +protected: int setChannels(int nChannels, Channel **theChannels); - - private: + +private: int isFactored; int size; int processID; int numProcesses; + bool init_done;//GZ_added + double *B, *X; int *indices; Vector *vectX; Vector *vectB; Mat A; + Mat M; + Mat K; Vec x, b; int blockSize; - PetscTruth flg; - + int numChannels; Channel **theChannels; ID **localCol; + MatType mType;//Guanzhou + int startRow, endRow; + }; #endif - + diff --git a/SRC/system_of_eqn/linearSOE/petsc/PetscSolver.cpp b/SRC/system_of_eqn/linearSOE/petsc/PetscSolver.cpp old mode 100644 new mode 100755 index 2500b2613c..feb646887c --- a/SRC/system_of_eqn/linearSOE/petsc/PetscSolver.cpp +++ b/SRC/system_of_eqn/linearSOE/petsc/PetscSolver.cpp @@ -17,21 +17,9 @@ ** Filip C. Filippou (filippou@ce.berkeley.edu) ** ** ** ** ****************************************************************** */ - -// $Revision: 1.6 $ -// $Date: 2007-02-14 20:12:32 $ -// $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/linearSOE/petsc/PetscSolver.cpp,v $ - -// Written: fmk & om -// Created: 7/98 -// Revision: A -// -// Description: This file contains the class implementation for -// FullGenLinLapackSolver. It solves the FullGenLinSOE object by calling -// Lapack routines. -// -// What: "@(#) FullGenLinLapackSolver.h, revA" + +#include #include #include #include @@ -41,63 +29,95 @@ #include #include #include +#include +#include "petscksp.h" + +#include +#include +#include +#include +#include -int PetscSolver::numSolver=0; +using namespace std; +//------------------------------------- PetscSolver::PetscSolver() - :LinearSOESolver(SOLVER_TAGS_PetscSolver), - rTol(PETSC_DEFAULT), aTol(PETSC_DEFAULT), dTol(PETSC_DEFAULT), maxIts(PETSC_DEFAULT) + : LinearSOESolver(SOLVER_TAGS_PetscSolver), + rTol(PETSC_DEFAULT), aTol(PETSC_DEFAULT), dTol(PETSC_DEFAULT), maxIts(PETSC_DEFAULT), matType(MATMPIAIJ), + is_KSP_initialized(false) { - numSolver++; + } PetscSolver::PetscSolver(KSPType meth, PCType pre) - :LinearSOESolver(SOLVER_TAGS_PetscSolver), method(meth), preconditioner(pre), - rTol(PETSC_DEFAULT), aTol(PETSC_DEFAULT), dTol(PETSC_DEFAULT), maxIts(PETSC_DEFAULT) + : LinearSOESolver(SOLVER_TAGS_PetscSolver), method(meth), preconditioner(pre), + rTol(PETSC_DEFAULT), aTol(PETSC_DEFAULT), dTol(PETSC_DEFAULT), maxIts(PETSC_DEFAULT), matType(MATMPIAIJ), + is_KSP_initialized(false) { - numSolver++; + } -PetscSolver::PetscSolver(KSPType meth, PCType pre, double relTol, double absTol, double divTol, int maxIterations) - :LinearSOESolver(SOLVER_TAGS_PetscSolver), method(meth), preconditioner(pre), - rTol(relTol), aTol(absTol), dTol(divTol), maxIts(maxIterations) +PetscSolver::PetscSolver(KSPType meth, PCType pre, double relTol, double absTol, double divTol, int maxIterations, MatType mat) + : LinearSOESolver(SOLVER_TAGS_PetscSolver), method(meth), preconditioner(pre), + rTol(relTol), aTol(absTol), dTol(divTol), maxIts(maxIterations), matType(mat), + is_KSP_initialized(false) { - numSolver++; + } PetscSolver::~PetscSolver() { - - KSPDestroy(ksp); - numSolver--; - /* - if (numSolver == 0) - PetscFinalize(); - */ + // KSPDestroy(&ksp); + // CHKERRQ(ierr); } - int PetscSolver::solve(void) { - int size = theSOE->size; - int factored = theSOE->isFactored; - - int numProcesses = theSOE->numProcesses; - int processID = theSOE->processID; - - int ierr; - ierr = MatAssemblyBegin(theSOE->A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); - ierr = MatAssemblyEnd(theSOE->A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); - - // - // if parallel, we must zero X & form the total B: each processor has own contributions - // - - static Vector recvVector(1); - - if (numProcesses > 1) { + + int size = theSOE->size; + // int numProcesses = theSOE->numProcesses; + int processID = theSOE->processID; + int ierr; + + if (processID >= 0) + { + + //MatSetType(theSOE->A, matType); + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") MatAssemblyBegin\n"; + ierr = MatAssemblyBegin(theSOE->A, MAT_FINAL_ASSEMBLY); + CHKERRQ(ierr); + + ierr = MatAssemblyEnd(theSOE->A, MAT_FINAL_ASSEMBLY); + CHKERRQ(ierr); + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") MatAssemblyEnd\n"; + + + if (not is_KSP_initialized) + { + + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") KSPCreate Begin\n"; + KSPCreate(PETSC_COMM_WORLD, &ksp); + KSPSetFromOptions(ksp); + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") KSPCreate End\n"; + + + is_KSP_initialized = true; + } + + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") KSPSetOperators Begin\n"; + KSPSetOperators(ksp, theSOE->A, theSOE->A); + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") KSPSetOperators End\n"; + + } + + + + // Everyone sends the assembled vector B to the rank 0 processor. Which sends it back... + static Vector recvVector(1); + + Vector *vectX = theSOE->vectX; Vector *vectB = theSOE->vectB; @@ -107,218 +127,182 @@ PetscSolver::solve(void) // // form B on each // - + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") FormBBegin\n"; int numChannels = theSOE->numChannels; Channel **theChannels = theSOE->theChannels; - - if (processID != 0) { - Channel *theChannel = theChannels[0]; - - theChannel->sendVector(0, 0, *vectB); - theChannel->recvVector(0, 0, *vectB); - - } else { - - if (recvVector.Size() != size) - recvVector.resize(size); - for (int j=0; jrecvVector(0, 0, recvVector); - *vectB += recvVector; - } - for (int j=0; jsendVector(0, 0, *vectB); - } + + if (processID != 0) + { + Channel *theChannel = theChannels[0]; + + theChannel->sendVector(0, 0, *vectB); + theChannel->recvVector(0, 0, *vectB); + + double vectBNorm = vectB->Norm(); + if (std::isnan(vectBNorm)) + { + cout << "norm(vectB) = " << vectBNorm << endl; + return -1; + } + + } + else //Master process assembles b vector. This is a bottleneck and can be improved with + //a collective reduction + { + + if (recvVector.Size() != size) + { + recvVector.resize(size); + } + + //Better done with ALLREDUCE + for (int j = 0; j < numChannels; j++) + { + Channel *theChannel = theChannels[j]; + theChannel->recvVector(0, 0, recvVector); + *vectB += recvVector; + + double rvNorm = recvVector.Norm() ; + if (std::isnan(rvNorm)) + { + cout << "norm(recvVector) = " << rvNorm << endl; + return -1; + } + } + + //Better done with a BCast + for (int j = 0; j < numChannels; j++) + { + Channel *theChannel = theChannels[j]; + theChannel->sendVector(0, 0, *vectB); + } } - } + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") FormBEnd\n"; - // - // solve and mark as having been solved - // - Vec &x = theSOE->x; - Vec &b = theSOE->b; - ierr = KSPSolve(ksp, b, x); CHKERRQ(ierr); - theSOE->isFactored = 1; + // + // solve and mark as having been solved + // - // - // if parallel, we must form the total X: each processor has startRow through endRow-1 - // + double t1 = 0; + double t2 = 0; + PetscTime(&t1); + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") SolveBegin\n"; + if (processID >= 0) + { + ierr = KSPSolve(ksp, theSOE->b, theSOE->x); + CHKERRQ(ierr); + theSOE->isFactored = 1; + } + PetscTime(&t2); + double delta_time = t2 - t1; + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") SolveEnd dt = " << delta_time << "s \n"; - if (numProcesses > 1) { - Vector *vectX = theSOE->vectX; - int numChannels = theSOE->numChannels; - Channel **theChannels = theSOE->theChannels; - - if (processID != 0) { - Channel *theChannel = theChannels[0]; - - theChannel->sendVector(0, 0, *vectX); - theChannel->recvVector(0, 0, *vectX); - - } else { - - if (recvVector.Size() != size) - recvVector.resize(size); - - for (int j=0; jrecvVector(0, 0, recvVector); - *vectX += recvVector; - } - for (int j=0; jsendVector(0, 0, *vectX); - } + + + + // + // if parallel, we must form the total X: each processor has startRow through endRow-1 + // + vectX = theSOE->vectX; + + numChannels = theSOE->numChannels; + theChannels = theSOE->theChannels; + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") SendXBegin\n"; + if (processID != 0) + { + Channel *theChannel = theChannels[0]; + + theChannel->sendVector(0, 0, *vectX); + theChannel->recvVector(0, 0, *vectX); + + } + else //Again, the master process forms the global X vector which is then sent to all processors + { + + if (recvVector.Size() != size) + { + recvVector.resize(size); + } + + //Better done with ALLREDUCE + for (int j = 0; j < numChannels; j++) + { + Channel *theChannel = theChannels[j]; + theChannel->recvVector(0, 0, recvVector); + *vectX += recvVector; + } + + //Better done with a BCast + for (int j = 0; j < numChannels; j++) + { + Channel *theChannel = theChannels[j]; + theChannel->sendVector(0, 0, *vectX); + } } - } - return ierr; + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") SendXEnd\n"; + // Destroy KSP and collect the error at P0 + KSPDestroy(&ksp); + is_KSP_initialized = false; + + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") Logging Begin\n"; + +#ifdef _ENABLE_PETSC_LOGGER + PetscViewer viewer; + PetscViewerASCIIOpen(PETSC_COMM_WORLD, "petsc_log.txt" , &viewer); + PetscLogView(viewer); +#endif + + PETSCSOLVER_DEBUGOUT << "PetscSolver::solve (" << processID << ") Logging End - Done solve\n"; + + return ierr; } + + + + int PetscSolver::setSize() { - /* - * Create linear solver context - */ - - KSPCreate(PETSC_COMM_WORLD, &ksp); - - /* - * Set operators. NOTE: matrix that defines the linear system - * also serves as the preconditioning matrix. - */ - - KSPSetOperators(ksp, theSOE->A, theSOE->A, DIFFERENT_NONZERO_PATTERN); - - /* - * Set solution scheme & tolerances - */ - - int ierr; - ierr = KSPSetType(ksp, method); CHKERRQ(ierr); - ierr = KSPSetTolerances(ksp, rTol, aTol, dTol, maxIts); - - /* - * Set preconditioning scheme - */ - - KSPGetPC(ksp, &pc); - ierr = PCSetType(pc, preconditioner); CHKERRQ(ierr); + /* + * Create linear solver context + */ + if (theSOE->processID >= 0) + { + KSPCreate(PETSC_COMM_WORLD, &ksp); + } - /* - * Finally mark so that uses last solution as initial guess in each solution - * NOTE: maybe change this as another user supplied option - */ - // ierr = KSPSetInitialGuessNonzero(ksp, PETSC_TRUE); CHKERRQ(ierr); - return ierr; + return 0; } -int +int PetscSolver::setLinearSOE(PetscSOE &theSys) { - theSOE = &theSys; - return 0; + theSOE = &theSys; + return 0; } int PetscSolver::sendSelf(int cTag, Channel &theChannel) { - static ID idData(3); - idData(0) = maxIts; - if (strcmp(method, KSPCG) == 0) - idData(1) = 0; - else if (strcmp(method, KSPBICG) == 0) - idData(1) = 1; - else if (strcmp(method, KSPRICHARDSON) == 0) - idData(1) = 2; - else if (strcmp(method, KSPCHEBYCHEV) == 0) - idData(1) = 3; - else if (strcmp(method, KSPGMRES) ==0) - idData(1) = 4; - else { - opserr << "PetscSolver::sendSelf() - unknown method set\n"; - return -1; - } - - if (strcmp(preconditioner, PCJACOBI) == 0) - idData(2) = 0; - else if (strcmp(preconditioner, PCILU) == 0) - idData(2) = 1; - else if (strcmp(preconditioner, PCICC) == 0) - idData(2) = 2; - else if (strcmp(preconditioner, PCBJACOBI) == 0) - idData(2) = 3; - else if (strcmp(preconditioner, PCNONE) == 0) - idData(2) = 4; - else { - opserr << "PetscSolver::sendSelf() - unknown preconditioner set\n"; - return -1; - } - - theChannel.sendID(0, cTag, idData); - - static Vector data(3); - data(0) = rTol; - data(1) = aTol; - data(2) = dTol; - - theChannel.sendVector(0, cTag, data); - return 0; + + return 0; } int -PetscSolver::recvSelf(int cTag, Channel &theChannel, - FEM_ObjectBroker &theBroker) +PetscSolver::recvSelf(int cTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) { - static ID idData(3); - theChannel.recvID(0, cTag, idData); - maxIts = idData(0); - if (idData(1) == 0) - method = KSPCG; - else if (idData(1) == 1) - method = KSPBICG; - else if (idData(1) == 2) - method = KSPRICHARDSON; - else if (idData(1) == 3) - method = KSPCHEBYCHEV; - else if (idData(1) == 4) - method = KSPGMRES; - else { - opserr << "PetscSolver::recvSelf() - unknown method recvd\n"; - return -1; - } - - if (idData(2) == 0) - preconditioner = PCJACOBI; - else if (idData(2) == 1) - preconditioner = PCILU; - else if (idData(2) == 2) - preconditioner = PCICC; - else if (idData(2) == 3) - preconditioner = PCBJACOBI; - else if (idData(2) == 4) - preconditioner = PCNONE; - else { - opserr << "PetscSolver::sendSelf() - unknown preconditioner set\n"; - return -1; - } - - - static Vector data(3); - theChannel.recvVector(0, cTag, data); - rTol = data(0); - aTol = data(1); - dTol = data(2); - - return 0; + + + return 0; } diff --git a/SRC/system_of_eqn/linearSOE/petsc/PetscSolver.h b/SRC/system_of_eqn/linearSOE/petsc/PetscSolver.h index b5d12a73fe..a15e185c08 100644 --- a/SRC/system_of_eqn/linearSOE/petsc/PetscSolver.h +++ b/SRC/system_of_eqn/linearSOE/petsc/PetscSolver.h @@ -17,67 +17,65 @@ ** Filip C. Filippou (filippou@ce.berkeley.edu) ** ** ** ** ****************************************************************** */ - -// $Revision: 1.4 $ -// $Date: 2007-02-14 20:12:32 $ -// $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/linearSOE/petsc/PetscSolver.h,v $ - - -// Written: fmk -// Created: Tue Sep 26 16:27:47: 1996 -// Revision: A -// -// Description: This file contains the class definition for -// PetscSolver. It solves the FullGenLinSOE object by calling -// Lapack routines. -// -// What: "@(#) PetscSolver.h, revA" + #ifndef PetscSolver_h #define PetscSolver_h -//extern "C" { #include -//} - #include + +// Uncomment or define -D_DEBUG_PETSCSOLVER to enable debugging +// #define _DEBUG_PETSCSOLVER + +#ifdef _DEBUG_PETSCSOLVER +#define PETSCSOLVER_DEBUGOUT cout // or any other ostream +#else +#define PETSCSOLVER_DEBUGOUT 0 && cout +#endif + +// Uncomment to enable logger that will creat petsc_log.txt on each +// run, to profile PETSc. +// #define _ENABLE_PETSC_LOGGER + class PetscSOE; class PetscSolver : public LinearSOESolver { - public: - PetscSolver(); - PetscSolver(KSPType method, PCType preconditioner); - PetscSolver(KSPType method, PCType preconditioner, double rTol, double aTol, double dTol, int maxIts); +public: + PetscSolver(); + PetscSolver(KSPType method, PCType preconditioner); + PetscSolver(KSPType method, PCType preconditioner, double rTol, double aTol, double dTol, int maxIts, MatType mat=MATMPIAIJ);//Guanzhou ~PetscSolver(); int solve(void); int setSize(void); virtual int setLinearSOE(PetscSOE &theSOE); - + int sendSelf(int commitTag, Channel &theChannel); - int recvSelf(int commitTag, Channel &theChannel, - FEM_ObjectBroker &theBroker); + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); friend class ActorPetscSOE; friend class ShadowPetscSOE; - - protected: + +protected: PetscSOE *theSOE; - private: - KSP ksp; +private: + KSP ksp; PC pc; int its; KSPType method; PCType preconditioner; double rTol; double aTol; - double dTol; + double dTol; int maxIts; + MatType matType; - static int numSolver; + bool is_KSP_initialized; }; #endif diff --git a/SRC/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.cpp b/SRC/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.cpp old mode 100644 new mode 100755 index 5c27e91b8f..a3cfb5878f --- a/SRC/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.cpp +++ b/SRC/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.cpp @@ -17,14 +17,14 @@ ** Filip C. Filippou (filippou@ce.berkeley.edu) ** ** ** ** ****************************************************************** */ - + // $Revision: 1.2 $ -// $Date: 2005-05-18 19:26:59 $ +// $Date: 2005/05/18 19:26:59 $ // $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.cpp,v $ - -// Written: fmk + +// Written: fmk // Created: 04/05 - + // What: "@(#) PetscSparseSeqSolver.h, revA" #include @@ -36,32 +36,32 @@ #include PetscSparseSeqSolver::PetscSparseSeqSolver(KSPType meth, PCType pre) - :SparseGenRowLinSolver(SOLVER_TAGS_PetscSparseSeqSolver), - rTol(PETSC_DEFAULT), aTol(PETSC_DEFAULT), dTol(PETSC_DEFAULT), maxIts(PETSC_DEFAULT) + : SparseGenRowLinSolver(SOLVER_TAGS_PetscSparseSeqSolver), + rTol(PETSC_DEFAULT), aTol(PETSC_DEFAULT), dTol(PETSC_DEFAULT), maxIts(PETSC_DEFAULT) { - PetscInitialize(0, PETSC_NULL, (char *)0, PETSC_NULL); + PetscInitialize(0, PETSC_NULL, (char*)0, PETSC_NULL); - method = meth; - preconditioner = pre; + method = meth; + preconditioner = pre; } PetscSparseSeqSolver::PetscSparseSeqSolver(KSPType meth, PCType pre, double relTol, double absTol, double divTol, int maxIterations) - :SparseGenRowLinSolver(SOLVER_TAGS_PetscSparseSeqSolver), - rTol(relTol), aTol(absTol), dTol(divTol), maxIts(maxIterations) + : SparseGenRowLinSolver(SOLVER_TAGS_PetscSparseSeqSolver), + rTol(relTol), aTol(absTol), dTol(divTol), maxIts(maxIterations) { - PetscInitialize(0, PETSC_NULL, (char *)0, PETSC_NULL); + PetscInitialize(0, PETSC_NULL, (char*)0, PETSC_NULL); - method = meth; - preconditioner = pre; + method = meth; + preconditioner = pre; } PetscSparseSeqSolver::~PetscSparseSeqSolver() { - MatDestroy(A); - VecDestroy(x); - VecDestroy(b); - KSPDestroy(ksp); + MatDestroy(&A); + VecDestroy(&x); + VecDestroy(&b); + KSPDestroy(&ksp); } @@ -69,100 +69,107 @@ PetscSparseSeqSolver::~PetscSparseSeqSolver() int PetscSparseSeqSolver::solve(void) { - PetscErrorCode ierr = KSPSolve(ksp, b, x); CHKERRQ(ierr); + PetscErrorCode ierr = KSPSolve(ksp, b, x); + CHKERRQ(ierr); - return ierr; + return ierr; } int PetscSparseSeqSolver::getNumIterations(void) { - PetscErrorCode ierr = KSPGetIterationNumber(ksp, &its); - - return its; + PetscErrorCode ierr = KSPGetIterationNumber(ksp, &its); + + return its; } int PetscSparseSeqSolver::setSize() { - int n = theSOE->size; - int nnz = theSOE->nnz; - double *Adata = theSOE->A; - double *Xdata = theSOE->X; - double *Bdata = theSOE->B; - int *colA = theSOE->colA; - int *rowStartA = theSOE->rowStartA; - - - /* - * Call Petsc VecCreate & MatCreate; NOTE: using previously allocated storage - * - */ - - PetscTruth flg; - PetscErrorCode ierr = PetscOptionsGetInt(PETSC_NULL,"-n", &n, &flg); CHKERRQ(ierr); - ierr = VecCreateSeqWithArray(PETSC_COMM_WORLD, n, Xdata, &x); CHKERRQ(ierr); - ierr = VecCreateSeqWithArray(PETSC_COMM_WORLD, n, Bdata, &b); CHKERRQ(ierr); - ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_WORLD, n, n, rowStartA, colA, Adata , &A); - - /* - * Create linear solver context - */ - - KSPCreate(PETSC_COMM_WORLD, &ksp); - - /* - * Set operators. NOTE: matrix that defines the linear system - * also serves as the preconditioning matrix. - */ - - KSPSetOperators(ksp, A, A, DIFFERENT_NONZERO_PATTERN); - - /* - * Set solution scheme & tolerances - */ - - ierr = KSPSetType(ksp, method); CHKERRQ(ierr); - ierr = KSPSetTolerances(ksp, rTol, aTol, dTol, maxIts); - - /* - * Set preconditioning scheme - */ - - KSPGetPC(ksp, &pc); - ierr = PCSetType(pc, preconditioner); CHKERRQ(ierr); - - /* - * Finally mark so that uses last solution as initial guess in each solution - * NOTE: maybe change this as another user supplied option - */ - - ierr = KSPSetInitialGuessNonzero(ksp, PETSC_TRUE); CHKERRQ(ierr); - - return ierr; + int n = theSOE->size; + int nnz = theSOE->nnz; + double* Adata = theSOE->A; + double* Xdata = theSOE->X; + double* Bdata = theSOE->B; + int* colA = theSOE->colA; + int* rowStartA = theSOE->rowStartA; + + + /* + * Call Petsc VecCreate & MatCreate; NOTE: using previously allocated storage + * + */ + + PetscBool flg; // PetsTruth --> PetscBool + PetscErrorCode ierr = PetscOptionsGetInt(PETSC_NULL, NULL , "-n", &n, &flg); + CHKERRQ(ierr); + ierr = VecCreateSeqWithArray(PETSC_COMM_WORLD, 1, n, Xdata, &x); + CHKERRQ(ierr); + ierr = VecCreateSeqWithArray(PETSC_COMM_WORLD, 1, n, Bdata, &b); + CHKERRQ(ierr); + ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_WORLD, n, n, rowStartA, colA, Adata , &A); + + /* + * Create linear solver context + */ + + KSPCreate(PETSC_COMM_WORLD, &ksp); + + /* + * Set operators. NOTE: matrix that defines the linear system + * also serves as the preconditioning matrix. + */ + + KSPSetOperators(ksp, A, A); + + /* + * Set solution scheme & tolerances + */ + + ierr = KSPSetType(ksp, method); + CHKERRQ(ierr); + ierr = KSPSetTolerances(ksp, rTol, aTol, dTol, maxIts); + + /* + * Set preconditioning scheme + */ + + KSPGetPC(ksp, &pc); + ierr = PCSetType(pc, preconditioner); + CHKERRQ(ierr); + + /* + * Finally mark so that uses last solution as initial guess in each solution + * NOTE: maybe change this as another user supplied option + */ + + ierr = KSPSetInitialGuessNonzero(ksp, PETSC_TRUE); + CHKERRQ(ierr); + + return ierr; } -int -PetscSparseSeqSolver::setLinearSOE(SparseGenRowLinSOE &theSystem) +int +PetscSparseSeqSolver::setLinearSOE(SparseGenRowLinSOE& theSystem) { - theSOE = &theSystem; - return 0; + theSOE = &theSystem; + return 0; } int -PetscSparseSeqSolver::sendSelf(int cTag, Channel &theChannel) +PetscSparseSeqSolver::sendSelf(int cTag, Channel& theChannel) { // nothing to do return 0; } int -PetscSparseSeqSolver::recvSelf(int cTag, Channel &theChannel, - FEM_ObjectBroker &theBroker) +PetscSparseSeqSolver::receiveSelf(int cTag, Channel& theChannel, + FEM_ObjectBroker& theBroker) { // nothing to do return 0; diff --git a/SRC/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.h b/SRC/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.h old mode 100644 new mode 100755 index d80437cf3b..5b008db2ae --- a/SRC/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.h +++ b/SRC/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.h @@ -17,16 +17,16 @@ ** Filip C. Filippou (filippou@ce.berkeley.edu) ** ** ** ** ****************************************************************** */ - + // $Revision: 1.2 $ -// $Date: 2005-05-18 19:26:59 $ +// $Date: 2005/05/18 19:26:59 $ // $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.h,v $ - -// Written: fmk + +// Written: fmk // Created: 04/05 // -// Description: This file contains the class definition for +// Description: This file contains the class definition for // PetscSparseSeqSolver. It solves the SparseGenLinSOE object by calling Petsc routines // // What: "@(#) PetscSparseSeqSolver.h, revA" @@ -43,36 +43,36 @@ class SparseGenRowLinSOE; class PetscSparseSeqSolver : public SparseGenRowLinSolver { - public: - PetscSparseSeqSolver(KSPType method, PCType preconditioner); - PetscSparseSeqSolver(KSPType method, PCType preconditioner, double rTol, double aTol, double dTol, int maxIts); - ~PetscSparseSeqSolver(); + public: + PetscSparseSeqSolver(KSPType method, PCType preconditioner); + PetscSparseSeqSolver(KSPType method, PCType preconditioner, double rTol, double aTol, double dTol, int maxIts); + ~PetscSparseSeqSolver(); + + int solve(void); + int setSize(void); + int getNumIterations(void); + virtual int setLinearSOE(SparseGenRowLinSOE& theSOE); - int solve(void); - int setSize(void); - int getNumIterations(void); - virtual int setLinearSOE(SparseGenRowLinSOE &theSOE); - - int sendSelf(int commitTag, Channel &theChannel); - int recvSelf(int commitTag, Channel &theChannel, - FEM_ObjectBroker &theBroker); + int sendSelf(int commitTag, Channel& theChannel); + int receiveSelf(int commitTag, Channel& theChannel, + FEM_ObjectBroker& theBroker); - protected: - SparseGenRowLinSOE *theSOE; + protected: + SparseGenRowLinSOE* theSOE; - private: - KSP ksp; // linear solver context - PC pc; - int its; - KSPType method; - PCType preconditioner; - double rTol; - double aTol; - double dTol; - int maxIts; + private: + KSP ksp; // linear solver context + PC pc; + int its; + KSPType method; + PCType preconditioner; + double rTol; + double aTol; + double dTol; + int maxIts; - Mat A; - Vec x, b; + Mat A; + Vec x, b; }; #endif diff --git a/SRC/system_of_eqn/linearSOE/profileSPD/DistributedProfileSPDLinSOE.cpp b/SRC/system_of_eqn/linearSOE/profileSPD/DistributedProfileSPDLinSOE.cpp index 9ed58eee5a..e32c316a21 100644 --- a/SRC/system_of_eqn/linearSOE/profileSPD/DistributedProfileSPDLinSOE.cpp +++ b/SRC/system_of_eqn/linearSOE/profileSPD/DistributedProfileSPDLinSOE.cpp @@ -141,7 +141,7 @@ DistributedProfileSPDLinSOE::setSize(Graph &theGraph) else { // from each distributed soe recv it's graph - // and merge them into master graph + // and merge them into primary graph FEM_ObjectBroker theBroker; for (int j=0; j +#include "ProfileSPDLinSolver.h" + class ProfileSPDLinSOE; class ProfileSPDLinDirectSolver : public ProfileSPDLinSolver diff --git a/SRC/system_of_eqn/linearSOE/profileSPD/ProfileSPDLinSubstrSolver.h b/SRC/system_of_eqn/linearSOE/profileSPD/ProfileSPDLinSubstrSolver.h index 82eb6a2ead..c7d51bdfb5 100644 --- a/SRC/system_of_eqn/linearSOE/profileSPD/ProfileSPDLinSubstrSolver.h +++ b/SRC/system_of_eqn/linearSOE/profileSPD/ProfileSPDLinSubstrSolver.h @@ -41,7 +41,7 @@ #define ProfileSPDLinSubstrSolver_h #include -#include +#include "ProfileSPDLinDirectSolver.h" class ProfileSPDLinSOE; diff --git a/SRC/system_of_eqn/linearSOE/sparseGEN/DistributedSparseGenColLinSOE.cpp b/SRC/system_of_eqn/linearSOE/sparseGEN/DistributedSparseGenColLinSOE.cpp index 3d8dc858ee..24469da5ac 100644 --- a/SRC/system_of_eqn/linearSOE/sparseGEN/DistributedSparseGenColLinSOE.cpp +++ b/SRC/system_of_eqn/linearSOE/sparseGEN/DistributedSparseGenColLinSOE.cpp @@ -149,7 +149,7 @@ DistributedSparseGenColLinSOE::setSize(Graph &theGraph) else { // from each distributed soe recv it's graph - // and merge them into master graph + // and merge them into primary graph FEM_ObjectBroker theBroker; for (int j=0; jrecvID(0, 0, otherSize); @@ -225,7 +225,7 @@ DistributedSparseGenRowLinSOE::setSize(Graph &theGraph) } // - // now master list has been created we recv from each process the edges corresponding + // now primary list has been created we recv from each process the edges corresponding // to shared vertices. // diff --git a/SRC/tcl/TclFeViewer.cpp b/SRC/tcl/TclFeViewer.cpp index 982f4a9c6e..a32c26cc5d 100644 --- a/SRC/tcl/TclFeViewer.cpp +++ b/SRC/tcl/TclFeViewer.cpp @@ -306,7 +306,7 @@ TclFeViewer::record(int cTag, double timeStamp) double zAvg = (theBounds(2) + theBounds(5))/2.0; if (vrpSet == 0) - this->setVRP(xAvg, yAvg, zAvg); + this->setVRP(float(xAvg), float(yAvg), float(zAvg)); double diff, xDiff, yDiff, zDiff; xDiff = (theBounds(3) - theBounds(0)); @@ -321,11 +321,11 @@ TclFeViewer::record(int cTag, double timeStamp) diff *= 1.25 * 0.5; if (vpwindowSet == 0) - this->setViewWindow(-diff,diff,-diff,diff); + this->setViewWindow(float(-diff),float(diff),float(-diff),float(diff)); if (clippingPlaneDistancesSet == 0) { diff = sqrt(xDiff*xDiff + yDiff*yDiff + zDiff * zDiff); - this->setPlaneDist(diff,-diff); + this->setPlaneDist(float(diff),float(-diff)); } } @@ -335,7 +335,7 @@ TclFeViewer::record(int cTag, double timeStamp) ElementIter &theElements = theDomain->getElements(); Element *theEle; while ((theEle = theElements()) != 0) { - res = theEle->displaySelf(*theRenderer, theEleMode, theDisplayFact); + res = theEle->displaySelf(*theRenderer, theEleMode, float(theDisplayFact)); if (res < 0) { opserr << "Renderer::displayModel() - Element: \n"; opserr << theEle->getTag() << " failed to display itself\n"; @@ -347,7 +347,7 @@ TclFeViewer::record(int cTag, double timeStamp) NodeIter &theNodes = theDomain->getNodes(); Node *theNode; while ((theNode = theNodes()) != 0) { - res = theNode->displaySelf(*theRenderer, theNodeMode, theDisplayFact); + res = theNode->displaySelf(*theRenderer, theNodeMode, float(theDisplayFact)); if (res < 0) { opserr << "Renderer::displayModel() - Node: "; opserr << theNode->getTag() << " failed to display itself\n"; @@ -585,7 +585,7 @@ TclFeViewer_setVRP(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } - theTclFeViewer->setVRP(xLoc,yLoc,zLoc); + theTclFeViewer->setVRP(float(xLoc),float(yLoc),float(zLoc)); return TCL_OK; #endif } @@ -623,7 +623,7 @@ TclFeViewer_setVPN(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } - theTclFeViewer->setVPN(xDirn,yDirn,zDirn); + theTclFeViewer->setVPN(float(xDirn),float(yDirn),float(zDirn)); return 0; #endif } @@ -661,7 +661,7 @@ TclFeViewer_setVUP(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } - theTclFeViewer->setVUP(xDirn,yDirn,zDirn); + theTclFeViewer->setVUP(float(xDirn),float(yDirn),float(zDirn)); return TCL_OK; #endif } @@ -702,7 +702,7 @@ TclFeViewer_setViewWindow(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } - theTclFeViewer->setViewWindow(uMin,uMax,vMin,vMax); + theTclFeViewer->setViewWindow(float(uMin),float(uMax),float(vMin),float(vMax)); return TCL_OK; #endif } @@ -735,7 +735,7 @@ TclFeViewer_setPlaneDist(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } - theTclFeViewer->setPlaneDist(anear, afar); + theTclFeViewer->setPlaneDist(float(anear),float(afar)); return TCL_OK; #endif } @@ -824,7 +824,7 @@ TclFeViewer_setPRP(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } - theTclFeViewer->setPRP(xLoc,yLoc,zLoc); + theTclFeViewer->setPRP(float(xLoc),float(yLoc),float(zLoc)); return TCL_OK; #endif } @@ -866,7 +866,7 @@ TclFeViewer_setPortWindow(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } - theTclFeViewer->setPortWindow(uMin,uMax,vMin,vMax); + theTclFeViewer->setPortWindow(float(uMin),float(uMax),float(vMin),float(vMax)); return TCL_OK; #endif } @@ -902,7 +902,7 @@ TclFeViewer_displayModel(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } - theTclFeViewer->displayModel(displayMode, -1, displayFact); + theTclFeViewer->displayModel(displayMode, -1, float(displayFact)); return TCL_OK; } else { @@ -921,7 +921,7 @@ TclFeViewer_displayModel(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_ERROR; } - theTclFeViewer->displayModel(eleFlag, nodeFlag, displayFact); + theTclFeViewer->displayModel(eleFlag, nodeFlag, float(displayFact)); return TCL_OK; } #endif diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index fcd9b78562..541c241f6d 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -83,6 +83,7 @@ OPS_Stream *opserrPtr = &sserr; #include #include +#include #include #include @@ -142,6 +143,7 @@ OPS_Stream *opserrPtr = &sserr; #include #include #include +#include // accelerators #include @@ -171,6 +173,7 @@ OPS_Stream *opserrPtr = &sserr; // integrators #include +#include #include #include #include @@ -189,6 +192,7 @@ extern void *OPS_ModifiedNewton(void); extern void *OPS_NewtonHallM(void); extern void *OPS_Newmark(void); +extern void *OPS_StagedNewmark(void); extern void *OPS_GimmeMCK(void); extern void *OPS_AlphaOS(void); extern void *OPS_AlphaOS_TP(void); @@ -226,6 +230,7 @@ extern void *OPS_WilsonTheta(void); #include +#include #include #include #include @@ -471,15 +476,6 @@ Domain theDomain; #endif -extern int OPS_ResetInputNoBuilder(ClientData clientData, - Tcl_Interp *interp, - int cArg, - int mArg, - TCL_Char **argv, - Domain *domain); - - - #include MachineBroker *theMachineBroker =0; @@ -762,8 +758,8 @@ int Tcl_InterpOpenSeesObjCmd(ClientData clientData, Tcl_Interp *interp, int obj switch ((enum option) index) { case OPT_CREATE: { TCL_Char *theInterpreterName = Tcl_GetStringResult(interp); - Tcl_Interp *slaveInterp = Tcl_GetSlave(interp, theInterpreterName); - ok = OpenSeesAppInit(slaveInterp); + Tcl_Interp *secondaryInterp = Tcl_GetSlave(interp, theInterpreterName); + ok = OpenSeesAppInit(secondaryInterp); return ok; break; } @@ -913,8 +909,10 @@ int OpenSeesAppInit(Tcl_Interp *interp) { (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); Tcl_CreateCommand(interp, "reactions", &calculateNodalReactions, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "nodeDOFs", &nodeDOFs, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); Tcl_CreateCommand(interp, "nodeCoord", &nodeCoord, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); Tcl_CreateCommand(interp, "setNodeCoord", &setNodeCoord, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); Tcl_CreateCommand(interp, "updateElementDomain", &updateElementDomain, @@ -3357,11 +3355,14 @@ specifySOE(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) count+=2; } + if (matType == 0) { + // PetscSolver *theSolver = new PetscSolver(method, preconditioner, rTol, aTol, dTol, maxIts); PetscSolver *theSolver = new PetscSolver(method, preconditioner, rTol, aTol, dTol, maxIts); theSOE = new PetscSOE(*theSolver); } else { - PetscSparseSeqSolver *theSolver = new PetscSparseSeqSolver(method, preconditioner, rTol, aTol, dTol, maxIts); + // PetscSparseSeqSolver *theSolver = new PetscSparseSeqSolver(method, preconditioner, rTol, aTol, dTol, maxIts); + PetscSparseSeqSolver *theSolver = 0; theSOE = new SparseGenRowLinSOE(*theSolver); } } @@ -3663,15 +3664,15 @@ specifyAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, // check argv[1] for type of Algorithm and create the object if (strcmp(argv[1],"Linear") == 0) { int formTangent = CURRENT_TANGENT; - int factorOnce = 0; - int count = 2; - while (count < argc) { + int factorOnce = 0; + int count = 2; + while (count < argc) { if ((strcmp(argv[count],"-secant") == 0) || (strcmp(argv[count],"-Secant") == 0)) { - formTangent = CURRENT_SECANT; - } else if ((strcmp(argv[count],"-initial") == 0) || (strcmp(argv[count],"-Initial") == 0)) { - formTangent = INITIAL_TANGENT; - } else if ((strcmp(argv[count],"-factorOnce") == 0) || (strcmp(argv[count],"-FactorOnce") ==0 )) { - factorOnce = 1; + formTangent = CURRENT_SECANT; + } else if ((strcmp(argv[count],"-initial") == 0) || (strcmp(argv[count],"-Initial") == 0)) { + formTangent = INITIAL_TANGENT; + } else if ((strcmp(argv[count],"-factorOnce") == 0) || (strcmp(argv[count],"-FactorOnce") ==0 )) { + factorOnce = 1; } count++; } @@ -4025,6 +4026,27 @@ specifyAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, theNewAlgo = new NewtonLineSearch(*theTest, theLineSearch); } + else if (strcmp(argv[1],"ExpressNewton") == 0) { + int nIter = 2, factorOnce = 0, formTangent = CURRENT_TANGENT; + double kMultiplier = 1.0; + if (argc >= 3 && Tcl_GetInt(interp, argv[2], &nIter) != TCL_OK) + return TCL_ERROR; + if (argc >= 4 && Tcl_GetDouble(interp, argv[3], &kMultiplier) != TCL_OK) + return TCL_ERROR; + int count = 4; + while (argc > count) { + if ((strcmp(argv[count],"-initialTangent") == 0) || (strcmp(argv[count],"-InitialTangent") == 0)) { + formTangent = INITIAL_TANGENT; + } else if ((strcmp(argv[count],"-currentTangent") == 0) || (strcmp(argv[count],"-CurrentTangent") ==0 )) { + formTangent = CURRENT_TANGENT; + } else if ((strcmp(argv[count],"-factorOnce") == 0) || (strcmp(argv[count],"-FactorOnce") ==0 )) { + factorOnce = 1; + } + count++; + } + theNewAlgo = new ExpressNewton(nIter,kMultiplier,formTangent,factorOnce); + } + else { opserr << "WARNING No EquiSolnAlgo type " << argv[1] << " exists\n"; return TCL_ERROR; @@ -4334,9 +4356,36 @@ specifyIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, // if the analysis exists - we want to change the Integrator if (theStaticAnalysis != 0) theStaticAnalysis->setIntegrator(*theStaticIntegrator); + } else if (strcmp(argv[1],"StagedLoadControl") == 0) { + double dLambda; + double minIncr, maxIncr; + int numIter; + if (argc < 3) { + opserr << "WARNING incorrect # args - integrator StagedLoadControl dlam \n"; + return TCL_ERROR; } + if (Tcl_GetDouble(interp, argv[2], &dLambda) != TCL_OK) + return TCL_ERROR; + if (argc > 5) { + if (Tcl_GetInt(interp, argv[3], &numIter) != TCL_OK) + return TCL_ERROR; + if (Tcl_GetDouble(interp, argv[4], &minIncr) != TCL_OK) + return TCL_ERROR; + if (Tcl_GetDouble(interp, argv[5], &maxIncr) != TCL_OK) + return TCL_ERROR; + } + else { + minIncr = dLambda; + maxIncr = dLambda; + numIter = 1; + } + theStaticIntegrator = new StagedLoadControl(dLambda, numIter, minIncr, maxIncr); + if (theStaticAnalysis != 0) + theStaticAnalysis->setIntegrator(*theStaticIntegrator); + } + else if (strcmp(argv[1],"ArcLength") == 0) { double arcLength; double alpha; @@ -4495,13 +4544,23 @@ specifyIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, opserr << "\n"; return TCL_ERROR; } + int tangFlag = 0; + if (Tcl_GetInt(interp, argv[2], &node) != TCL_OK) return TCL_ERROR; if (Tcl_GetInt(interp, argv[3], &dof) != TCL_OK) return TCL_ERROR; if (Tcl_GetDouble(interp, argv[4], &increment) != TCL_OK) - return TCL_ERROR; - if (argc > 7) { + return TCL_ERROR; + + if (argc == 6 || argc == 9) + if (argc == 6) { + if (strcmp(argv[5],"-initial") == 0) + tangFlag = 1; + } else if (strcmp(argv[8],"-initial") == 0) + tangFlag = 1; + + if (argc > 6) { if (Tcl_GetInt(interp, argv[5], &numIter) != TCL_OK) return TCL_ERROR; if (Tcl_GetDouble(interp, argv[6], &minIncr) != TCL_OK) @@ -4516,6 +4575,7 @@ specifyIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, } + #ifdef _PARALLEL_PROCESSING theStaticIntegrator = new DistributedDisplacementControl(node,dof-1,increment, @@ -4535,7 +4595,7 @@ specifyIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, } theStaticIntegrator = new DisplacementControl(node, dof-1, increment, &theDomain, - numIter, minIncr, maxIncr); + numIter, minIncr, maxIncr, tangFlag); #endif // if the analysis exists - we want to change the Integrator @@ -4628,6 +4688,9 @@ specifyIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, else if (strcmp(argv[1],"GimmeMCK") == 0 || strcmp(argv[1],"ZZTop") == 0) { theTransientIntegrator = (TransientIntegrator*)OPS_GimmeMCK(); + } + else if (strcmp(argv[1],"StagedNewmark") == 0) { + theTransientIntegrator = (TransientIntegrator*)OPS_StagedNewmark(); // if the analysis exists - we want to change the Integrator if (theTransientAnalysis != 0) @@ -6634,6 +6697,44 @@ eleNodes(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) return TCL_OK; } +int +nodeDOFs(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + if (argc < 2) { + opserr << "WARNING want - nodeDOFs nodeTag?\n"; + return TCL_ERROR; + } + + int tag; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING nodeMass nodeTag? nodeDOF? \n"; + return TCL_ERROR; + } + + char buffer[40]; + + Node *theNode = theDomain.getNode(tag); + if (theNode == 0) { + opserr << "WARNING nodeDOFs node " << tag << " not found" << endln; + return TCL_ERROR; + } + int numDOF = theNode->getNumberDOF(); + + DOF_Group *theDOFgroup = theNode->getDOF_GroupPtr(); + if (theDOFgroup == 0) { + opserr << "WARNING nodeDOFs DOF group null" << endln; + return -1; + } + const ID &eqnNumbers = theDOFgroup->getID(); + for (int i = 0; i < numDOF; i++) { + sprintf(buffer, "%d ", eqnNumbers(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + + return TCL_OK; +} + int nodeMass(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { @@ -9304,6 +9405,41 @@ numIter(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) return TCL_OK; } +int +elementActivate(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + int eleTag; + int argLoc = 1; + int Nelements = argc; + ID activate_us(0, Nelements); + + while (argLoc < argc && Tcl_GetInt(interp, argv[argLoc], &eleTag) == TCL_OK) { + activate_us.insert(eleTag); + ++argLoc; + } + + theDomain.activateElements(activate_us); + + return TCL_OK; +} + +int +elementDeactivate(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + + int eleTag; + int argLoc = 1; + int Nelements = argc; + ID deactivate_us(0, Nelements); + + while (argLoc < argc && Tcl_GetInt(interp, argv[argLoc], &eleTag) == TCL_OK) { + deactivate_us.insert(eleTag); + ++argLoc; + } + + theDomain.deactivateElements(deactivate_us); + return TCL_OK;} + int version(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { diff --git a/SRC/tcl/commands.h b/SRC/tcl/commands.h index 8ab975b263..a6d3f4cb6e 100644 --- a/SRC/tcl/commands.h +++ b/SRC/tcl/commands.h @@ -199,6 +199,9 @@ getNodeTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv int getEleTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); +int +nodeDOFs(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); + int nodeMass(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); @@ -317,12 +320,8 @@ numIter(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); int systemSize(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - - - - - - - - +int +elementActivate(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); +int +elementDeactivate(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); diff --git a/SRC/tcl/mpiMain.cpp b/SRC/tcl/mpiMain.cpp index f542e724d8..2b0194fba3 100644 --- a/SRC/tcl/mpiMain.cpp +++ b/SRC/tcl/mpiMain.cpp @@ -197,9 +197,9 @@ main(int argc, char **argv) if (OPS_rank != 0) { // - // on slave processes we spin waiting to create & run actors + // on secondary processes we spin waiting to create & run actors // - fprintf(stderr, "Slave Process Running %d\n", OPS_rank); + fprintf(stderr, "Secondary Process Running %d\n", OPS_rank); theMachineBroker->runActors(); } else { @@ -207,7 +207,7 @@ main(int argc, char **argv) // // on process 0 we create some ShadowSubdomains & then start the OpenSees interpreter // - fprintf(stderr, "Master Process Running OpenSees Interpreter %d\n", OPS_rank); + fprintf(stderr, "Primary Process Running OpenSees Interpreter %d\n", OPS_rank); // // set some global parameters diff --git a/SRC/tcl/mpiMainTest.cpp b/SRC/tcl/mpiMainTest.cpp index 4d65fd4ade..e7aeb06b1d 100644 --- a/SRC/tcl/mpiMainTest.cpp +++ b/SRC/tcl/mpiMainTest.cpp @@ -65,9 +65,9 @@ main(int argc, char **argv) if (rank != 0) { // - // on slave processes we spin waiting to create & run actors + // on secondary processes we spin waiting to create & run actors // - fprintf(stderr, "Slave Process Running\n"); + fprintf(stderr, "Secondary Process Running\n"); theMachine.runActors(); } else { @@ -75,7 +75,7 @@ main(int argc, char **argv) // // on process 0 we create some ShadowSubdomains & then start the OpenSees interpreter // - fprintf(stderr, "Master Process Running OpenSees Interpreter\n"); + fprintf(stderr, "Primary Process Running OpenSees Interpreter\n"); // // set some global parameters diff --git a/Win32/proj/analysis/analysis.vcxproj b/Win32/proj/analysis/analysis.vcxproj index 36a9216472..68aae94462 100644 --- a/Win32/proj/analysis/analysis.vcxproj +++ b/Win32/proj/analysis/analysis.vcxproj @@ -117,6 +117,7 @@ + @@ -125,6 +126,8 @@ + + @@ -227,6 +230,7 @@ + @@ -235,6 +239,8 @@ + + diff --git a/Win32/proj/analysis/analysis.vcxproj.filters b/Win32/proj/analysis/analysis.vcxproj.filters index 481bcb4e96..102150d379 100644 --- a/Win32/proj/analysis/analysis.vcxproj.filters +++ b/Win32/proj/analysis/analysis.vcxproj.filters @@ -365,6 +365,15 @@ integrator + + integrator + + + integrator + + + integrator + @@ -691,5 +700,14 @@ integrator + + integrator + + + integrator + + + integrator + \ No newline at end of file diff --git a/Win32/proj/element/element.vcxproj b/Win32/proj/element/element.vcxproj index 9d2fec4221..9721ae77a6 100644 --- a/Win32/proj/element/element.vcxproj +++ b/Win32/proj/element/element.vcxproj @@ -122,6 +122,9 @@ + + + @@ -349,6 +352,7 @@ + @@ -383,6 +387,9 @@ + + + @@ -584,6 +591,7 @@ + diff --git a/Win32/proj/element/element.vcxproj.filters b/Win32/proj/element/element.vcxproj.filters index fa2d8a346a..14e791bd95 100644 --- a/Win32/proj/element/element.vcxproj.filters +++ b/Win32/proj/element/element.vcxproj.filters @@ -653,6 +653,9 @@ shell + + shell + HUelements @@ -890,6 +893,18 @@ mixedBeamColumn + + Source Files + + + triangle + + + quad + + + quad + @@ -1351,6 +1366,9 @@ shell + + shell + HUelements @@ -1582,5 +1600,17 @@ mixedBeamColumn + + Header Files + + + triangle + + + quad + + + quad + \ No newline at end of file diff --git a/Win32/proj/material/material.vcxproj b/Win32/proj/material/material.vcxproj index 5cb7764f82..69f29b9533 100644 --- a/Win32/proj/material/material.vcxproj +++ b/Win32/proj/material/material.vcxproj @@ -111,6 +111,7 @@ + @@ -166,6 +167,7 @@ + @@ -189,6 +191,7 @@ + @@ -247,6 +250,7 @@ + @@ -524,6 +528,7 @@ + @@ -579,6 +584,7 @@ + @@ -603,6 +609,7 @@ + @@ -659,6 +666,7 @@ + diff --git a/Win32/proj/material/material.vcxproj.filters b/Win32/proj/material/material.vcxproj.filters index 7b5e5f8092..178c998b6d 100644 --- a/Win32/proj/material/material.vcxproj.filters +++ b/Win32/proj/material/material.vcxproj.filters @@ -145,6 +145,9 @@ uniaxial + + uniaxial + uniaxial @@ -1343,6 +1346,15 @@ uniaxial + + uniaxial + + + uniaxial + + + nD\elasticIsotropic + @@ -1378,6 +1390,9 @@ uniaxial + + uniaxial + uniaxial @@ -2519,5 +2534,14 @@ uniaxial + + uniaxial + + + uniaxial + + + nD\elasticIsotropic + \ No newline at end of file diff --git a/Win32/proj/recorder/recorder.vcxproj b/Win32/proj/recorder/recorder.vcxproj index 3f728d6642..c445671afe 100644 --- a/Win32/proj/recorder/recorder.vcxproj +++ b/Win32/proj/recorder/recorder.vcxproj @@ -107,6 +107,7 @@ + @@ -116,6 +117,7 @@ + @@ -132,9 +134,11 @@ + + diff --git a/Win32/proj/recorder/recorder.vcxproj.filters b/Win32/proj/recorder/recorder.vcxproj.filters index d423e0a7fa..2c1d755b37 100644 --- a/Win32/proj/recorder/recorder.vcxproj.filters +++ b/Win32/proj/recorder/recorder.vcxproj.filters @@ -95,6 +95,12 @@ Source Files + + Source Files + + + Source Files + @@ -175,5 +181,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/Win32/proj/system/system.vcxproj b/Win32/proj/system/system.vcxproj index e12922d4c6..a2022623c6 100644 --- a/Win32/proj/system/system.vcxproj +++ b/Win32/proj/system/system.vcxproj @@ -47,7 +47,7 @@ Disabled - ..\..\..\src\api;..\..\..\src\recorder;..\..\..\src\element;..\..\..\src\element\PFEMElement;..\..\..\src\domain\node;..\..\..\src\domain\component;..\..\..\src\domain\constraints;..\..\..\other\CSPARSE;..\..\..\src\utility;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\tagged;..\..\..\src\graph\graph;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src;..\..\..\src\matrix;..\..\..\src\actor\actor;..\..\..\src\system_of_eqn;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\src\system_of_eqn\linearSOE\cg;c:\Program Files (x86)\tcl;%(AdditionalIncludeDirectories) + ..\..\..\src\api;..\..\..\src\recorder;..\..\..\src\element;..\..\..\src\element\PFEMElement;..\..\..\src\domain\node;..\..\..\src\domain\component;..\..\..\src\domain\constraints;..\..\..\other\CSPARSE;..\..\..\src\utility;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\tagged;..\..\..\src\graph\graph;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src;..\..\..\src\matrix;..\..\..\src\actor\actor;..\..\..\src\system_of_eqn;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\src\system_of_eqn\linearSOE\cg;c:\Program Files (x86)\tcl;c:\Program Files (x86)\tcl\include;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_LIB;_WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -76,7 +76,7 @@ OnlyExplicitInline - ..\..\..\src\api;..\..\..\src\recorder;..\..\..\src\element;..\..\..\src\element\PFEMElement;..\..\..\src\domain\node;..\..\..\src\domain\component;..\..\..\src\domain\constraints;..\..\..\other\CSPARSE;..\..\..\src\utility;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\tagged;..\..\..\src\graph\graph;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src;..\..\..\src\matrix;..\..\..\src\actor\actor;..\..\..\src\system_of_eqn;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\src\system_of_eqn\linearSOE\cg;c:\Program Files (x86)\tcl;%(AdditionalIncludeDirectories) + ..\..\..\src\api;..\..\..\src\recorder;..\..\..\src\element;..\..\..\src\element\PFEMElement;..\..\..\src\domain\node;..\..\..\src\domain\component;..\..\..\src\domain\constraints;..\..\..\other\CSPARSE;..\..\..\src\utility;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\analysis\integrator;..\..\..\src\analysis\fe_ele;..\..\..\src\analysis\dof_grp;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\symSparse;..\..\..\src\analysis\model\simple;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\tagged;..\..\..\src\graph\graph;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src;..\..\..\src\matrix;..\..\..\src\actor\actor;..\..\..\src\system_of_eqn;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\src\system_of_eqn\linearSOE\cg;c:\Program Files (x86)\tcl;c:\Program Files (x86)\tcl\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreaded diff --git a/Win32/proj/tcl/tcl.vcxproj b/Win32/proj/tcl/tcl.vcxproj index 548c21944d..9d966963ce 100644 --- a/Win32/proj/tcl/tcl.vcxproj +++ b/Win32/proj/tcl/tcl.vcxproj @@ -47,7 +47,7 @@ OnlyExplicitInline - ..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\other\CSPARSE;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\optimization\tcl;..\..\..\src\optimization\domain\component;..\..\..\src\optimization\domain;..\..\..\src\actor\machineBroker;..\..\..\src\optimization;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\api;..\..\..\src\material\uniaxial\backbone;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\recorder\response;..\..\..\src\reliability\optimization;..\..\..\src\package;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\damage;..\..\..\src\material\uniaxial\py;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\tcl;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files (x86)\tcl;c:\Program Files (x86)\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\other\CSPARSE;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\optimization\tcl;..\..\..\src\optimization\domain\component;..\..\..\src\optimization\domain;..\..\..\src\actor\machineBroker;..\..\..\src\optimization;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\api;..\..\..\src\material\uniaxial\backbone;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\recorder\response;..\..\..\src\reliability\optimization;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\damage;..\..\..\src\material\uniaxial\py;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\tcl;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files (x86)\tcl;c:\Program Files (x86)\tcl\include;%(AdditionalIncludeDirectories) _LIMITSTATEMATERIAL;WIN32;NDEBUG;_LIB;_TCL85;_WGL;_RELIABILITY;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreaded @@ -75,7 +75,7 @@ Disabled - ..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\other\CSPARSE;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\optimization\tcl;..\..\..\src\optimization\domain\component;..\..\..\src\optimization\domain;..\..\..\src\actor\machineBroker;..\..\..\src\optimization;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\api;..\..\..\src\material\uniaxial\backbone;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\recorder\response;..\..\..\src\reliability\optimization;..\..\..\src\package;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\damage;..\..\..\src\material\uniaxial\py;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\tcl;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files (x86)\tcl;c:\Program Files (x86)\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\other\CSPARSE;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\optimization\tcl;..\..\..\src\optimization\domain\component;..\..\..\src\optimization\domain;..\..\..\src\actor\machineBroker;..\..\..\src\optimization;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\api;..\..\..\src\material\uniaxial\backbone;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\recorder\response;..\..\..\src\reliability\optimization;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\damage;..\..\..\src\material\uniaxial\py;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\tcl;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files (x86)\tcl;c:\Program Files (x86)\tcl\include;%(AdditionalIncludeDirectories) _LIMITSTATEMATERIAL;WIN32;_DEBUG;_LIB;_TCL85;_WGL;_RELIABILITY;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug diff --git a/Win64/OpenSees.sln b/Win64/OpenSees.sln index 40d682eef4..7e63dec807 100644 --- a/Win64/OpenSees.sln +++ b/Win64/OpenSees.sln @@ -56,7 +56,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utility", "proj\utility\uti EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenSeesPy", "proj\openSeesPy\OpenSeesPy.vcxproj", "{F26CA968-C7ED-4246-A732-388C23BF8822}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenSeesPy37", "proj\openSeesPy37\OpenSeesPy37.vcxproj", "{5E3E057B-AE7B-434B-9FC1-C238893D901E}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenSeesPy38", "proj\openSeesPy38\OpenSeesPy38.vcxproj", "{5E3E057B-AE7B-434B-9FC1-C238893D901E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Win64/proj/analysis/analysis.vcxproj b/Win64/proj/analysis/analysis.vcxproj index 8735aa0c71..40ad3fdf54 100644 --- a/Win64/proj/analysis/analysis.vcxproj +++ b/Win64/proj/analysis/analysis.vcxproj @@ -216,6 +216,8 @@ + + @@ -328,6 +330,8 @@ + + diff --git a/Win64/proj/analysis/analysis.vcxproj.filters b/Win64/proj/analysis/analysis.vcxproj.filters index 38fd57c145..059e3d7a6f 100644 --- a/Win64/proj/analysis/analysis.vcxproj.filters +++ b/Win64/proj/analysis/analysis.vcxproj.filters @@ -371,6 +371,12 @@ integrator + + integrator + + + integrator + @@ -703,5 +709,11 @@ integrator + + integrator + + + integrator + \ No newline at end of file diff --git a/Win64/proj/element/element.vcxproj b/Win64/proj/element/element.vcxproj index d1f9d187aa..1a91b61300 100644 --- a/Win64/proj/element/element.vcxproj +++ b/Win64/proj/element/element.vcxproj @@ -205,8 +205,12 @@ + + + + @@ -435,6 +439,7 @@ + @@ -468,8 +473,12 @@ + + + + @@ -670,6 +679,7 @@ + diff --git a/Win64/proj/element/element.vcxproj.filters b/Win64/proj/element/element.vcxproj.filters index 5d99144f19..84ba56a83a 100644 --- a/Win64/proj/element/element.vcxproj.filters +++ b/Win64/proj/element/element.vcxproj.filters @@ -1,1592 +1,1622 @@ - - - - - {8dc53ba4-a20a-4427-bf11-babe5c15d07e} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {4c774e8e-ce1c-4ee6-a77b-796f64208534} - h;hpp;hxx;hm;inl - - - {4d6200e6-10d3-4c65-9db2-8f4a128940f9} - - - {d6824d8c-f5f0-449c-bc5c-4a55c342871e} - - - {c2413ced-fd89-47ec-a53c-7c50d9fbeda0} - - - {95c7eb42-420e-4ebb-9712-0482c73a001b} - - - {db97fed4-cb21-4af2-a581-225349957f04} - - - {59b81d90-87a0-4a4b-a9c5-18d28dd3042a} - - - {76b08a0c-6603-44ab-a9ab-0a7d7e6d2a8a} - - - {16f81571-87c3-4448-8bca-9305cf114483} - - - {8035f8de-4409-40dd-86bf-4a2b940a4a15} - - - {33c5b810-f197-4bf6-b6f1-bb4f417867dd} - - - {3f3077a6-1e37-491e-899e-b5f6fd7b2c41} - - - {1ef69e6e-4d94-49bc-8bbb-a5cc9134a52b} - - - {c7b2f79d-b62a-4d66-b614-7ea05cad8aa9} - - - {1611a2ae-725f-481e-ba94-013664af7bb5} - - - {608c6a97-eb5c-49d8-8b43-f44d9aac6eb3} - - - {dc875f73-4900-4ae7-a177-34d5a3f51385} - - - {34b2aa0b-78b0-4d40-a9c5-459062d2f200} - - - {9fa61ba6-4a0d-419a-9757-c26843b63dbe} - - - {8835abac-54af-40b7-a9cb-01c1b0c1002d} - - - {f7afb4ff-8b91-4c4c-8013-ee37063f770b} - - - {77b7081d-75e4-4e7b-a201-33ff4cb77c42} - - - {b4905908-3711-4bd7-8ad7-de7f01b668d2} - - - {301140e6-b43e-4fa5-a933-9b2ffa1a66a8} - - - {af576cab-4129-41e3-87a4-e15de1de56c9} - - - {295b84c9-249b-459e-9834-ba15b4e56ead} - - - {c4fc2b62-f666-4933-b1bc-0335ea53fb76} - - - {9717ffed-3174-4878-b385-940a387626a9} - - - {c1f531f9-4544-47ae-9c69-19ed46dd3e98} - - - {40ea145c-9bb4-4070-bfd4-f83f708d0c0d} - - - {00e72745-28b6-47a8-b8e1-04f2a25c02c1} - - - {5098eaf3-05b5-4c65-8a81-a2b545b7482b} - - - {24473406-20f3-4a25-9f2b-1e4f17b774a0} - - - {192f6adf-59e2-4e68-8259-4093172b605a} - - - {3c5b233e-0ad7-418e-bf3b-9ad6e0c6e47c} - - - {1da57574-6bdf-44c2-b363-afb3d416e9ad} - - - {9ea02351-3bae-4523-b1f6-2a3ea9a7a393} - - - {1b806f65-5bd2-4429-9294-d36935d459e3} - - - {516fa8a8-dc2b-4a36-a664-8524314d4ce9} - - - {a6ea196c-ed72-411c-ad9b-6628b144ecaa} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - truss - - - truss - - - truss - - - truss - - - truss - - - truss - - - feap - - - feap - - - feap - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - beamWithHinges - - - crdTransf - - - crdTransf - - - crdTransf - - - crdTransf - - - crdTransf - - - crdTransf - - - crdTransf - - - crdTransf - - - quad - - - quad - - - quad - - - quad - - - quad - - - quad - - - quad - - - elasticBeamColumn - - - elasticBeamColumn - - - elasticBeamColumn - - - elasticBeamColumn - - - elasticBeamColumn - - - brick - - - brick - - - brick - - - brick - - - brick - - - brick - - - brick - - - dispBeamColumn - - - dispBeamColumn - - - dispBeamColumn - - - dispBeamColumn - - - joint - - - joint - - - joint - - - joint - - - joint - - - joint - - - joint - - - joint - - - joint - - - joint - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - forceBeamColumn - - - forceBeamColumn - - - forceBeamColumn - - - forceBeamColumn - - - forceBeamColumn - - - forceBeamColumn - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - nonlinearBeamColumn\matrixutil - - - up - - - up - - - up - - - up - - - up - - - up - - - up - - - up - - - dispBeamColumnInt - - - dispBeamColumnInt - - - dispBeamColumnInt - - - dispBeamColumnInt - - - generic - - - generic - - - twoNodeLink - - - adapter - - - adapter - - - adapter - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - pyMacro - - - surfaceLoad - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - triangle - - - shell - - - shell - - - shell - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - HUelements - - - HUelements - - - HUelements - - - HUelements - - - HUelements - - - HUelements - - - Source Files - - - frictionBearing - - - truss - - - shell - - - shell - - - XMUelements - - - XMUelements - - - XMUelements - - - XMUelements - - - UWelements - - - mvlem - - - mvlem - - - componentElement - - - elastomericBearing - - - crdTransf - - - forceBeamColumn - - - forceBeamColumn - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - shell - - - shell - - - catenaryCable - - - forceBeamColumn - - - dispBeamColumn - - - dispBeamColumn - - - shell - - - shell - - - shell - - - dispBeamColumn - - - surfaceLoad - - - tetrahedron - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - absorbentBoundaries - - - dispBeamColumn - - - elasticBeamColumn - - - dispBeamColumn - - - twoNodeLink - - - twoNodeLink - - - Source Files - - - gradientInelasticBeamColumn - - - gradientInelasticBeamColumn - - - gradientInelasticBeamColumn - - - forceBeamColumn\beamIntegration - - - joint - - - mixedBeamColumn - - - mixedBeamColumn - - - pfem - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - truss - - - truss - - - truss - - - truss - - - truss - - - truss - - - feap - - - feap - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - zeroLength - - - crdTransf - - - crdTransf - - - crdTransf - - - crdTransf - - - crdTransf - - - crdTransf - - - crdTransf - - - quad - - - quad - - - quad - - - quad - - - quad - - - quad - - - elasticBeamColumn - - - elasticBeamColumn - - - elasticBeamColumn - - - elasticBeamColumn - - - elasticBeamColumn - - - brick - - - brick - - - brick - - - brick - - - dispBeamColumn - - - dispBeamColumn - - - joint - - - joint - - - joint - - - joint - - - joint - - - joint - - - joint - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - ulBeamColumn - - - forceBeamColumn - - - forceBeamColumn - - - forceBeamColumn - - - forceBeamColumn - - - forceBeamColumn - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - forceBeamColumn\beamIntegration - - - nonlinearBeamColumn\matrixutil - - - up - - - up - - - up - - - up - - - up - - - up - - - dispBeamColumnInt - - - dispBeamColumnInt - - - dispBeamColumnInt - - - generic - - - generic - - - twoNodeLink - - - adapter - - - adapter - - - adapter - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - elastomericBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - frictionBearing\frictionModel - - - pyMacro - - - surfaceLoad - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - triangle - - - shell - - - shell - - - shell - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - HUelements - - - HUelements - - - HUelements - - - HUelements - - - Header Files - - - frictionBearing - - - truss - - - shell - - - shell - - - XMUelements - - - XMUelements - - - XMUelements - - - XMUelements - - - UWelements - - - mvlem - - - mvlem - - - componentElement - - - elastomericBearing - - - crdTransf - - - forceBeamColumn - - - forceBeamColumn - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - shell - - - shell - - - catenaryCable - - - forceBeamColumn - - - dispBeamColumn - - - dispBeamColumn - - - shell - - - shell - - - dispBeamColumn - - - dispBeamColumn - - - shell - - - dispBeamColumn - - - surfaceLoad - - - tetrahedron - - - UWelements - - - UWelements - - - UWelements - - - UWelements - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - pfem - - - absorbentBoundaries - - - dispBeamColumn - - - elasticBeamColumn - - - dispBeamColumn - - - twoNodeLink - - - twoNodeLink - - - Header Files - - - gradientInelasticBeamColumn - - - gradientInelasticBeamColumn - - - forceBeamColumn\beamIntegration - - - joint - - - mixedBeamColumn - - - mixedBeamColumn - - - pfem - - + + + + + {8dc53ba4-a20a-4427-bf11-babe5c15d07e} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {4c774e8e-ce1c-4ee6-a77b-796f64208534} + h;hpp;hxx;hm;inl + + + {4d6200e6-10d3-4c65-9db2-8f4a128940f9} + + + {d6824d8c-f5f0-449c-bc5c-4a55c342871e} + + + {c2413ced-fd89-47ec-a53c-7c50d9fbeda0} + + + {95c7eb42-420e-4ebb-9712-0482c73a001b} + + + {db97fed4-cb21-4af2-a581-225349957f04} + + + {59b81d90-87a0-4a4b-a9c5-18d28dd3042a} + + + {76b08a0c-6603-44ab-a9ab-0a7d7e6d2a8a} + + + {16f81571-87c3-4448-8bca-9305cf114483} + + + {8035f8de-4409-40dd-86bf-4a2b940a4a15} + + + {33c5b810-f197-4bf6-b6f1-bb4f417867dd} + + + {3f3077a6-1e37-491e-899e-b5f6fd7b2c41} + + + {1ef69e6e-4d94-49bc-8bbb-a5cc9134a52b} + + + {c7b2f79d-b62a-4d66-b614-7ea05cad8aa9} + + + {1611a2ae-725f-481e-ba94-013664af7bb5} + + + {608c6a97-eb5c-49d8-8b43-f44d9aac6eb3} + + + {dc875f73-4900-4ae7-a177-34d5a3f51385} + + + {34b2aa0b-78b0-4d40-a9c5-459062d2f200} + + + {9fa61ba6-4a0d-419a-9757-c26843b63dbe} + + + {8835abac-54af-40b7-a9cb-01c1b0c1002d} + + + {f7afb4ff-8b91-4c4c-8013-ee37063f770b} + + + {77b7081d-75e4-4e7b-a201-33ff4cb77c42} + + + {b4905908-3711-4bd7-8ad7-de7f01b668d2} + + + {301140e6-b43e-4fa5-a933-9b2ffa1a66a8} + + + {af576cab-4129-41e3-87a4-e15de1de56c9} + + + {295b84c9-249b-459e-9834-ba15b4e56ead} + + + {c4fc2b62-f666-4933-b1bc-0335ea53fb76} + + + {9717ffed-3174-4878-b385-940a387626a9} + + + {c1f531f9-4544-47ae-9c69-19ed46dd3e98} + + + {40ea145c-9bb4-4070-bfd4-f83f708d0c0d} + + + {00e72745-28b6-47a8-b8e1-04f2a25c02c1} + + + {5098eaf3-05b5-4c65-8a81-a2b545b7482b} + + + {24473406-20f3-4a25-9f2b-1e4f17b774a0} + + + {192f6adf-59e2-4e68-8259-4093172b605a} + + + {3c5b233e-0ad7-418e-bf3b-9ad6e0c6e47c} + + + {1da57574-6bdf-44c2-b363-afb3d416e9ad} + + + {9ea02351-3bae-4523-b1f6-2a3ea9a7a393} + + + {1b806f65-5bd2-4429-9294-d36935d459e3} + + + {516fa8a8-dc2b-4a36-a664-8524314d4ce9} + + + {a6ea196c-ed72-411c-ad9b-6628b144ecaa} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + truss + + + truss + + + truss + + + truss + + + truss + + + truss + + + feap + + + feap + + + feap + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + beamWithHinges + + + crdTransf + + + crdTransf + + + crdTransf + + + crdTransf + + + crdTransf + + + crdTransf + + + crdTransf + + + crdTransf + + + quad + + + quad + + + quad + + + quad + + + quad + + + quad + + + quad + + + elasticBeamColumn + + + elasticBeamColumn + + + elasticBeamColumn + + + elasticBeamColumn + + + elasticBeamColumn + + + brick + + + brick + + + brick + + + brick + + + brick + + + brick + + + brick + + + dispBeamColumn + + + dispBeamColumn + + + dispBeamColumn + + + dispBeamColumn + + + joint + + + joint + + + joint + + + joint + + + joint + + + joint + + + joint + + + joint + + + joint + + + joint + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + forceBeamColumn + + + forceBeamColumn + + + forceBeamColumn + + + forceBeamColumn + + + forceBeamColumn + + + forceBeamColumn + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + nonlinearBeamColumn\matrixutil + + + up + + + up + + + up + + + up + + + up + + + up + + + up + + + up + + + dispBeamColumnInt + + + dispBeamColumnInt + + + dispBeamColumnInt + + + dispBeamColumnInt + + + generic + + + generic + + + twoNodeLink + + + adapter + + + adapter + + + adapter + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + pyMacro + + + surfaceLoad + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + triangle + + + shell + + + shell + + + shell + + + shell + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + HUelements + + + HUelements + + + HUelements + + + HUelements + + + HUelements + + + HUelements + + + Source Files + + + frictionBearing + + + truss + + + shell + + + shell + + + XMUelements + + + XMUelements + + + XMUelements + + + XMUelements + + + UWelements + + + mvlem + + + mvlem + + + componentElement + + + elastomericBearing + + + crdTransf + + + forceBeamColumn + + + forceBeamColumn + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + shell + + + shell + + + catenaryCable + + + forceBeamColumn + + + dispBeamColumn + + + dispBeamColumn + + + shell + + + shell + + + shell + + + dispBeamColumn + + + surfaceLoad + + + tetrahedron + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + absorbentBoundaries + + + dispBeamColumn + + + elasticBeamColumn + + + dispBeamColumn + + + twoNodeLink + + + twoNodeLink + + + Source Files + + + gradientInelasticBeamColumn + + + gradientInelasticBeamColumn + + + gradientInelasticBeamColumn + + + forceBeamColumn\beamIntegration + + + joint + + + mixedBeamColumn + + + mixedBeamColumn + + + pfem + + + forceBeamColumn + + + quad + + + quad + + + triangle + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + truss + + + truss + + + truss + + + truss + + + truss + + + truss + + + feap + + + feap + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + zeroLength + + + crdTransf + + + crdTransf + + + crdTransf + + + crdTransf + + + crdTransf + + + crdTransf + + + crdTransf + + + quad + + + quad + + + quad + + + quad + + + quad + + + quad + + + elasticBeamColumn + + + elasticBeamColumn + + + elasticBeamColumn + + + elasticBeamColumn + + + elasticBeamColumn + + + brick + + + brick + + + brick + + + brick + + + dispBeamColumn + + + dispBeamColumn + + + joint + + + joint + + + joint + + + joint + + + joint + + + joint + + + joint + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + ulBeamColumn + + + forceBeamColumn + + + forceBeamColumn + + + forceBeamColumn + + + forceBeamColumn + + + forceBeamColumn + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + forceBeamColumn\beamIntegration + + + nonlinearBeamColumn\matrixutil + + + up + + + up + + + up + + + up + + + up + + + up + + + dispBeamColumnInt + + + dispBeamColumnInt + + + dispBeamColumnInt + + + generic + + + generic + + + twoNodeLink + + + adapter + + + adapter + + + adapter + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + elastomericBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + frictionBearing\frictionModel + + + pyMacro + + + surfaceLoad + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + triangle + + + shell + + + shell + + + shell + + + shell + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + HUelements + + + HUelements + + + HUelements + + + HUelements + + + Header Files + + + frictionBearing + + + truss + + + shell + + + shell + + + XMUelements + + + XMUelements + + + XMUelements + + + XMUelements + + + UWelements + + + mvlem + + + mvlem + + + componentElement + + + elastomericBearing + + + crdTransf + + + forceBeamColumn + + + forceBeamColumn + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + shell + + + shell + + + catenaryCable + + + forceBeamColumn + + + dispBeamColumn + + + dispBeamColumn + + + shell + + + shell + + + dispBeamColumn + + + dispBeamColumn + + + shell + + + dispBeamColumn + + + surfaceLoad + + + tetrahedron + + + UWelements + + + UWelements + + + UWelements + + + UWelements + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + pfem + + + absorbentBoundaries + + + dispBeamColumn + + + elasticBeamColumn + + + dispBeamColumn + + + twoNodeLink + + + twoNodeLink + + + Header Files + + + gradientInelasticBeamColumn + + + gradientInelasticBeamColumn + + + forceBeamColumn\beamIntegration + + + joint + + + mixedBeamColumn + + + mixedBeamColumn + + + pfem + + + forceBeamColumn + + + quad + + + quad + + + triangle + + \ No newline at end of file diff --git a/Win64/proj/material/material.vcxproj b/Win64/proj/material/material.vcxproj index be178cd84a..9fbb5df3fc 100644 --- a/Win64/proj/material/material.vcxproj +++ b/Win64/proj/material/material.vcxproj @@ -200,6 +200,7 @@ + @@ -226,6 +227,8 @@ + + @@ -265,6 +268,7 @@ + @@ -283,6 +287,7 @@ + @@ -344,6 +349,7 @@ + @@ -612,6 +618,7 @@ + @@ -638,6 +645,8 @@ + + @@ -676,6 +685,7 @@ + @@ -694,6 +704,7 @@ + @@ -754,6 +765,7 @@ + diff --git a/Win64/proj/material/material.vcxproj.filters b/Win64/proj/material/material.vcxproj.filters index f75c29174d..8957149370 100644 --- a/Win64/proj/material/material.vcxproj.filters +++ b/Win64/proj/material/material.vcxproj.filters @@ -145,6 +145,9 @@ uniaxial + + uniaxial + uniaxial @@ -1343,6 +1346,21 @@ uniaxial + + uniaxial + + + uniaxial + + + nD\elasticIsotropic + + + nD\UWmaterials + + + nD\UWmaterials + @@ -1378,6 +1396,9 @@ uniaxial + + uniaxial + uniaxial @@ -2510,5 +2531,20 @@ uniaxial + + uniaxial + + + uniaxial + + + nD\elasticIsotropic + + + nD\UWmaterials + + + nD\UWmaterials + \ No newline at end of file diff --git a/Win64/proj/openSeesPy/OpenSeesPy.vcxproj b/Win64/proj/openSeesPy/OpenSeesPy.vcxproj index ca698509f4..d0470033fc 100644 --- a/Win64/proj/openSeesPy/OpenSeesPy.vcxproj +++ b/Win64/proj/openSeesPy/OpenSeesPy.vcxproj @@ -90,7 +90,7 @@ OnlyExplicitInline - ..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;..\..\..\src\element\tetrahedron;..\..\..\src\element\PFEMElement;..\..\..\src\optimization\domain;..\..\..\src\optimization\domain\component;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\reliability\domain\components;..\..\..\src\actor\machineBroker;..\..\..\src\material\section\integration;..\..\..\src\material\section\repres\reinfBar;..\..\..\src\material\section\repres\reinfLayer;..\..\..\src\material\section\repres\cell;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\material\section\repres\patch;..\..\..\other\CSPARSE;..\..\..\src\recorder\response;..\..\..\src\material\section\fiber;..\..\..\src\element\shell;..\..\..\src\material\uniaxial\backbone;..\..\..\src\domain\groundMotion;..\..\..\src\element\brick;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\UWelements;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\domain\region;..\..\..\src\element\fourNodeQuad;..\..\..\src\reliability\analysis\telm;..\..\..\src\element\forceBeamColumn;..\..\..\src\api;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\material\uniaxial\py;..\..\..\src\damage;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\handler;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files\tcl\include;c:\ProgramData\Anaconda3\include;%(AdditionalIncludeDirectories) + ..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;..\..\..\src\element\tetrahedron;..\..\..\src\element\PFEMElement;..\..\..\src\optimization\domain;..\..\..\src\optimization\domain\component;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\reliability\domain\components;..\..\..\src\actor\machineBroker;..\..\..\src\material\section\integration;..\..\..\src\material\section\repres\reinfBar;..\..\..\src\material\section\repres\reinfLayer;..\..\..\src\material\section\repres\cell;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\material\section\repres\patch;..\..\..\other\CSPARSE;..\..\..\src\recorder\response;..\..\..\src\material\section\fiber;..\..\..\src\element\shell;..\..\..\src\material\uniaxial\backbone;..\..\..\src\domain\groundMotion;..\..\..\src\element\brick;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\UWelements;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\domain\region;..\..\..\src\element\fourNodeQuad;..\..\..\src\reliability\analysis\telm;..\..\..\src\element\forceBeamColumn;..\..\..\src\api;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\material\uniaxial\py;..\..\..\src\damage;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\handler;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;C:\Program Files\Tcl\include;c:\ProgramData\Anaconda3\include;%(AdditionalIncludeDirectories) NDEBUG;_WGL;_RELIABILITY;_WIN32;_WIN64;_FORTRAN;WIN32;WIN64;_CONSOLE;BUILD_tcl;_TCL85;_NO_NEW_RESTREPO;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreaded @@ -109,10 +109,10 @@ /FORCE:MULTIPLE %(AdditionalOptions) - actor.lib;analysis.lib;arpack.lib;blas.lib;cblas.lib;convergence.lib;cssparse.lib;damage.lib;database.lib;DoddRestrepo.lib;domain.lib;drain.lib;element.lib;feap.lib;fedeas.lib;glu32.lib;graph.lib;handler.lib;ifconsol.lib;lapack.lib;libifcoremt.lib;libmmt.lib;material.lib;matrix.lib;modelbuilder.lib;opengl32.lib;optimization.lib;python37.lib;recorder.lib;reliability.lib;renderer.lib;sdmuc.lib;superLU.lib;system.lib;tagged.lib;tcl.lib;tcl86t.lib;tk86t.lib;umfpackC.lib;utility.lib;wsock32.lib;%(AdditionalDependencies) + actor.lib;analysis.lib;arpack.lib;blas.lib;cblas.lib;convergence.lib;cssparse.lib;damage.lib;database.lib;DoddRestrepo.lib;domain.lib;drain.lib;element.lib;feap.lib;fedeas.lib;glu32.lib;graph.lib;handler.lib;ifconsol.lib;lapack.lib;libifcoremt.lib;libmmt.lib;material.lib;matrix.lib;modelbuilder.lib;opengl32.lib;optimization.lib;python38.lib;recorder.lib;reliability.lib;renderer.lib;sdmuc.lib;superLU.lib;system.lib;tagged.lib;tcl.lib;tcl86t.lib;tk86t.lib;umfpackC.lib;utility.lib;wsock32.lib;%(AdditionalDependencies) .\..\..\bin\opensees.pyd true - c:\Program Files\tcl\lib;c:\ProgramData\Anaconda3\libs;..\..\lib;..\..\lib\release;%(AdditionalLibraryDirectories) + C:\Program Files\Tcl\lib;C:\ProgramData\Anaconda3\libs;..\..\lib;..\..\lib\release;%(AdditionalLibraryDirectories) %(IgnoreSpecificDefaultLibraries) .\..\..\bin\OpenSeesPy.pdb Console diff --git a/Win64/proj/openSeesPy37/OpenSeesPy37.rc b/Win64/proj/openSeesPy38/OpenSeesPy38.rc similarity index 100% rename from Win64/proj/openSeesPy37/OpenSeesPy37.rc rename to Win64/proj/openSeesPy38/OpenSeesPy38.rc diff --git a/Win64/proj/openSeesPy37/OpenSeesPy37.vcxproj b/Win64/proj/openSeesPy38/OpenSeesPy38.vcxproj similarity index 97% rename from Win64/proj/openSeesPy37/OpenSeesPy37.vcxproj rename to Win64/proj/openSeesPy38/OpenSeesPy38.vcxproj index 5e6bde4473..a62ac3dc28 100755 --- a/Win64/proj/openSeesPy37/OpenSeesPy37.vcxproj +++ b/Win64/proj/openSeesPy38/OpenSeesPy38.vcxproj @@ -11,7 +11,7 @@ - OpenSeesPy37 + OpenSeesPy38 {5E3E057B-AE7B-434B-9FC1-C238893D901E} OpenSeesPy5 10.0 @@ -59,7 +59,7 @@ OnlyExplicitInline - ..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\element\tetrahedron;..\..\..\src\element\PFEMElement;..\..\..\src\optimization\domain;..\..\..\src\optimization\domain\component;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\reliability\domain\components;..\..\..\src\actor\machineBroker;..\..\..\src\material\section\integration;..\..\..\src\material\section\repres\reinfBar;..\..\..\src\material\section\repres\reinfLayer;..\..\..\src\material\section\repres\cell;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\material\section\repres\patch;..\..\..\other\CSPARSE;..\..\..\src\recorder\response;..\..\..\src\material\section\fiber;..\..\..\src\element\shell;..\..\..\src\material\uniaxial\backbone;..\..\..\src\domain\groundMotion;..\..\..\src\element\brick;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\UWelements;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\domain\region;..\..\..\src\element\fourNodeQuad;..\..\..\src\reliability\analysis\telm;..\..\..\src\element\forceBeamColumn;..\..\..\src\api;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\material\uniaxial\py;..\..\..\src\damage;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files\tcl\include;c:\Program Files\Python37\include;%(AdditionalIncludeDirectories) + ..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\element\tetrahedron;..\..\..\src\element\PFEMElement;..\..\..\src\optimization\domain;..\..\..\src\optimization\domain\component;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\reliability\domain\components;..\..\..\src\actor\machineBroker;..\..\..\src\material\section\integration;..\..\..\src\material\section\repres\reinfBar;..\..\..\src\material\section\repres\reinfLayer;..\..\..\src\material\section\repres\cell;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\material\section\repres\patch;..\..\..\other\CSPARSE;..\..\..\src\recorder\response;..\..\..\src\material\section\fiber;..\..\..\src\element\shell;..\..\..\src\material\uniaxial\backbone;..\..\..\src\domain\groundMotion;..\..\..\src\element\brick;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\UWelements;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\domain\region;..\..\..\src\element\fourNodeQuad;..\..\..\src\reliability\analysis\telm;..\..\..\src\element\forceBeamColumn;..\..\..\src\api;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\material\uniaxial\py;..\..\..\src\damage;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files\tcl\include;c:\Program Files\Python38\include;%(AdditionalIncludeDirectories) NDEBUG;_WGL;_RELIABILITY;_WIN32;_WIN64;_FORTRAN;WIN32;WIN64;_CONSOLE;BUILD_tcl;_TCL85;_NO_NEW_RESTREPO;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreaded @@ -78,10 +78,10 @@ /FORCE:MULTIPLE %(AdditionalOptions) - actor.lib;analysis.lib;arpack.lib;blas.lib;cblas.lib;convergence.lib;cssparse.lib;damage.lib;database.lib;DoddRestrepo.lib;domain.lib;drain.lib;element.lib;feap.lib;fedeas.lib;glu32.lib;graph.lib;handler.lib;ifconsol.lib;lapack.lib;libifcoremt.lib;libmmt.lib;material.lib;matrix.lib;modelbuilder.lib;opengl32.lib;optimization.lib;python37.lib;recorder.lib;reliability.lib;renderer.lib;sdmuc.lib;superLU.lib;system.lib;tagged.lib;tcl.lib;tcl86t.lib;tk86t.lib;umfpackC.lib;utility.lib;wsock32.lib;%(AdditionalDependencies) + actor.lib;analysis.lib;arpack.lib;blas.lib;cblas.lib;convergence.lib;cssparse.lib;damage.lib;database.lib;DoddRestrepo.lib;domain.lib;drain.lib;element.lib;feap.lib;fedeas.lib;glu32.lib;graph.lib;handler.lib;ifconsol.lib;lapack.lib;libifcoremt.lib;libmmt.lib;material.lib;matrix.lib;modelbuilder.lib;opengl32.lib;optimization.lib;python38.lib;recorder.lib;reliability.lib;renderer.lib;sdmuc.lib;superLU.lib;system.lib;tagged.lib;tcl.lib;tcl86t.lib;tk86t.lib;umfpackC.lib;utility.lib;wsock32.lib;%(AdditionalDependencies) .\..\..\bin\opensees.pyd true - c:\Program Files\tcl\lib;c:\Program Files\Python37\libs;..\..\lib;..\..\lib\release;%(AdditionalLibraryDirectories) + c:\Program Files\tcl\lib;c:\Program Files\Python38\libs;..\..\lib;..\..\lib\release;%(AdditionalLibraryDirectories) %(IgnoreSpecificDefaultLibraries) .\..\..\bin\OpenSeesPy.pdb Console @@ -100,7 +100,7 @@ Disabled - ..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\element\tetrahedron;..\..\..\src\element\PFEMElement;..\..\..\src\optimization\domain;..\..\..\src\optimization\domain\component;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\reliability\domain\components;..\..\..\src\actor\machineBroker;..\..\..\src\material\section\integration;..\..\..\src\material\section\repres\reinfBar;..\..\..\src\material\section\repres\reinfLayer;..\..\..\src\material\section\repres\cell;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\material\section\repres\patch;..\..\..\other\CSPARSE;..\..\..\src\recorder\response;..\..\..\src\material\section\fiber;..\..\..\src\element\shell;..\..\..\src\material\uniaxial\backbone;..\..\..\src\domain\groundMotion;..\..\..\src\element\brick;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\UWelements;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\domain\region;..\..\..\src\element\fourNodeQuad;..\..\..\src\reliability\analysis\telm;..\..\..\src\element\forceBeamColumn;..\..\..\src\api;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\material\uniaxial\py;..\..\..\src\damage;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files\tcl\include;c:\Program Files\Python37\include;%(AdditionalIncludeDirectories) + ..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\element\tetrahedron;..\..\..\src\element\PFEMElement;..\..\..\src\optimization\domain;..\..\..\src\optimization\domain\component;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\reliability\domain\components;..\..\..\src\actor\machineBroker;..\..\..\src\material\section\integration;..\..\..\src\material\section\repres\reinfBar;..\..\..\src\material\section\repres\reinfLayer;..\..\..\src\material\section\repres\cell;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\material\section\repres\patch;..\..\..\other\CSPARSE;..\..\..\src\recorder\response;..\..\..\src\material\section\fiber;..\..\..\src\element\shell;..\..\..\src\material\uniaxial\backbone;..\..\..\src\domain\groundMotion;..\..\..\src\element\brick;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\UWelements;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\src\domain\region;..\..\..\src\element\fourNodeQuad;..\..\..\src\reliability\analysis\telm;..\..\..\src\element\forceBeamColumn;..\..\..\src\api;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\material\uniaxial\py;..\..\..\src\damage;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files\tcl\include;c:\Program Files\Python38\include;%(AdditionalIncludeDirectories) _DEBUG;_WGL;_RELIABILITY;_WIN32;_WIN64;_FORTRAN;WIN32;WIN64;_CONSOLE;BUILD_tcl;_TCL85;_NO_NEW_RESTREPO;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -120,10 +120,10 @@ /FORCE:MULTIPLE %(AdditionalOptions) - actor.lib;analysis.lib;arpack.lib;blas.lib;cblas.lib;convergence.lib;cssparse.lib;damage.lib;database.lib;DoddRestrepo.lib;domain.lib;drain.lib;element.lib;feap.lib;fedeas.lib;glu32.lib;graph.lib;handler.lib;ifconsol.lib;lapack.lib;libifcoremt.lib;libmmt.lib;material.lib;matrix.lib;modelbuilder.lib;opengl32.lib;optimization.lib;python37_d.lib;recorder.lib;reliability.lib;renderer.lib;sdmuc.lib;superLU.lib;system.lib;tagged.lib;tcl.lib;tcl86t.lib;tk86t.lib;umfpackC.lib;utility.lib;wsock32.lib;%(AdditionalDependencies) + actor.lib;analysis.lib;arpack.lib;blas.lib;cblas.lib;convergence.lib;cssparse.lib;damage.lib;database.lib;DoddRestrepo.lib;domain.lib;drain.lib;element.lib;feap.lib;fedeas.lib;glu32.lib;graph.lib;handler.lib;ifconsol.lib;lapack.lib;libifcoremt.lib;libmmt.lib;material.lib;matrix.lib;modelbuilder.lib;opengl32.lib;optimization.lib;python38_d.lib;recorder.lib;reliability.lib;renderer.lib;sdmuc.lib;superLU.lib;system.lib;tagged.lib;tcl.lib;tcl86t.lib;tk86t.lib;umfpackC.lib;utility.lib;wsock32.lib;%(AdditionalDependencies) .\..\..\bin\opensees.pyd true - c:\Program Files\tcl\lib;c:\Program Files\Python37\libs;..\..\lib;..\..\lib\debug;%(AdditionalLibraryDirectories) + c:\Program Files\tcl\lib;c:\Program Files\Python38\libs;..\..\lib;..\..\lib\debug;%(AdditionalLibraryDirectories) libcmt.lib;%(IgnoreSpecificDefaultLibraries) true .\..\..\bin\OpenSeesPy.pdb @@ -239,7 +239,7 @@ - + diff --git a/Win64/proj/openSeesPy37/resource.h b/Win64/proj/openSeesPy38/resource.h similarity index 100% rename from Win64/proj/openSeesPy37/resource.h rename to Win64/proj/openSeesPy38/resource.h diff --git a/Win64/proj/recorder/recorder.vcxproj b/Win64/proj/recorder/recorder.vcxproj index d412e2c2b2..f83a7bcf99 100644 --- a/Win64/proj/recorder/recorder.vcxproj +++ b/Win64/proj/recorder/recorder.vcxproj @@ -192,6 +192,7 @@ + @@ -201,6 +202,7 @@ + @@ -217,9 +219,11 @@ + + diff --git a/Win64/proj/recorder/recorder.vcxproj.filters b/Win64/proj/recorder/recorder.vcxproj.filters index 7fc6fb393c..fb7a0f41d0 100644 --- a/Win64/proj/recorder/recorder.vcxproj.filters +++ b/Win64/proj/recorder/recorder.vcxproj.filters @@ -95,6 +95,12 @@ Source Files + + Source Files + + + Source Files + @@ -175,5 +181,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/Win64/proj/tcl/tcl.vcxproj b/Win64/proj/tcl/tcl.vcxproj index 6b50af30ab..ffd3999553 100644 --- a/Win64/proj/tcl/tcl.vcxproj +++ b/Win64/proj/tcl/tcl.vcxproj @@ -76,7 +76,7 @@ OnlyExplicitInline ..\..\..\src\material\uniaxial\unloading;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\element\forceBeamColumn;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\other\CSPARSE;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\optimization\tcl;..\..\..\src\optimization\domain\component;..\..\..\src\optimization\domain;..\..\..\src\actor\machineBroker;..\..\..\src\optimization;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\api;..\..\..\src\material\uniaxial\backbone;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\recorder\response;..\..\..\src\reliability\optimization;..\..\..\src\reliability\analysis\telm;..\..\..\src\package;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\damage;..\..\..\src\material\uniaxial\py;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\tcl;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) - ..\..\..\src\element\forceBeamColumn;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\other\CSPARSE;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\optimization\tcl;..\..\..\src\optimization\domain\component;..\..\..\src\optimization\domain;..\..\..\src\actor\machineBroker;..\..\..\src\optimization;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\api;..\..\..\src\material\uniaxial\backbone;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\recorder\response;..\..\..\src\reliability\optimization;..\..\..\src\package;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\damage;..\..\..\src\material\uniaxial\py;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\tcl;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files\tcl;c:\Program Files\tcl\include;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;%(AdditionalIncludeDirectories) + ..\..\..\src\element\forceBeamColumn;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\other\CSPARSE;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\optimization\tcl;..\..\..\src\optimization\domain\component;..\..\..\src\optimization\domain;..\..\..\src\actor\machineBroker;..\..\..\src\optimization;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\api;..\..\..\src\material\uniaxial\backbone;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\recorder\response;..\..\..\src\reliability\optimization;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\damage;..\..\..\src\material\uniaxial\py;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\tcl;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files\tcl;c:\Program Files\tcl\include;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;%(AdditionalIncludeDirectories) _LIMITSTATEMATERIAL;WIN32;NDEBUG;_LIB;_TCL85;_WGL;_RELIABILITY;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreaded @@ -133,7 +133,7 @@ Disabled - ..\..\..\src\element\forceBeamColumn;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\other\CSPARSE;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\optimization\tcl;..\..\..\src\optimization\domain\component;..\..\..\src\optimization\domain;..\..\..\src\actor\machineBroker;..\..\..\src\optimization;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\api;..\..\..\src\material\uniaxial\backbone;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\recorder\response;..\..\..\src\reliability\optimization;..\..\..\src\package;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\damage;..\..\..\src\material\uniaxial\py;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\tcl;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files\tcl;c:\Program Files\tcl\include;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;%(AdditionalIncludeDirectories) + ..\..\..\src\element\forceBeamColumn;..\..\..\src\material\uniaxial\limitState\limitCurve;..\..\..\other\CSPARSE;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\optimization\tcl;..\..\..\src\optimization\domain\component;..\..\..\src\optimization\domain;..\..\..\src\actor\machineBroker;..\..\..\src\optimization;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\api;..\..\..\src\material\uniaxial\backbone;..\..\..\src\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\recorder\response;..\..\..\src\reliability\optimization;..\..\..\src\system_of_eqn\linearSOE\diagonal;..\..\..\src\damage;..\..\..\src\material\uniaxial\py;..\..\..\src\reliability\fesensitivity;..\..\..\src\reliability\tcl;..\..\..\src\coordTransformation;..\..\..\src\material\section\repres\section;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\material\nD;..\..\..\src\material\uniaxial;..\..\..\src\handler;..\..\..\src\tcl;..\..\..\src\actor\objectBroker;..\..\..\src\system_of_eqn\linearSOE\umfGEN;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\system_of_eqn\linearSOE\sparseGEN;..\..\..\src\system_of_eqn\linearSOE\bandSPD;..\..\..\src\system_of_eqn\linearSOE\bandGEN;..\..\..\src\element\nonlinearBeamColumn\tcl\repres\section;..\..\..\src\matrix;..\..\..\src\recorder;..\..\..\src\graph\numberer;..\..\..\src\material\section;..\..\..\src\graph\graph;..\..\..\src\element\beam2d;..\..\..\src\element\beam3d;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\profileSPD;..\..\..\src\system_of_eqn\linearSOE\sparseSYM;..\..\..\src\domain\pattern;..\..\..\src\analysis\analysis;..\..\..\src\analysis\dof_grp;..\..\..\src\analysis\integrator;..\..\..\src\analysis\numberer;..\..\..\src\analysis\handler;..\..\..\src\renderer;..\..\..\src\material;..\..\..\src\analysis\algorithm;..\..\..\src\convergenceTest;..\..\..\src\analysis\model\simple;..\..\..\src\domain\load;..\..\..\src\analysis\model;..\..\..\src\element\truss;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\actor\actor;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\domain;..\..\..\src\tagged\storage;..\..\..\src;..\..\..\src\tagged;..\..\..\src\reliability\domain;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\distributions;..\..\..\src\reliability\analysis;..\..\..\src\reliability\analysis\analysis;..\..\..\src\reliability\analysis\curvature;..\..\..\src\reliability\analysis\designPoint;..\..\..\src\reliability\analysis\direction;..\..\..\src\reliability\analysis\gFunction;..\..\..\src\reliability\analysis\misc;..\..\..\src\reliability\analysis\randomNumber;..\..\..\src\reliability\analysis\sensitivity;..\..\..\src\reliability\analysis\stepSize;..\..\..\src\reliability\analysis\transformation;..\..\..\src\nDarray;..\..\..\src\system_of_eqn\linearSOE\cg;..\..\..\src\system_of_eqn\linearSOE\itpack;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\database;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\material\yieldSurface\plasticHardeningMaterial;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\analysis\hessianApproximation;..\..\..\src\reliability\analysis\convergenceCheck;..\..\..\src\reliability\analysis\meritFunction;..\..\..\src\reliability\analysis\rootFinding;c:\Program Files\tcl;c:\Program Files\tcl\include;..\..\..\src\material\uniaxial\stiffness;..\..\..\src\material\uniaxial\strength;..\..\..\src\material\uniaxial\unloading;%(AdditionalIncludeDirectories) _LIMITSTATEMATERIAL;WIN32;_DEBUG;_LIB;_TCL85;_WGL;_RELIABILITY;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug diff --git a/Workshops/OpenSeesDays/j1.tcl b/Workshops/OpenSeesDays/j1.tcl new file mode 100644 index 0000000000..dc4c091a43 --- /dev/null +++ b/Workshops/OpenSeesDays/j1.tcl @@ -0,0 +1,76 @@ +foreach record {el_centro IELC180 ALH360} { + + wipe + + # set some variables + set Tn 1.0 + set K 4.0 + set dampRatio 0.02 + + #set some constants + set g 386.4 + set PI [expr 2.0 * asin(1.0)] + + #derived quantaties + set Wn [expr 2.0 * $PI / $Tn] + set M [expr $K / ($Wn * $Wn)] + set c [expr 2.0*$M*$Wn*$dampRatio] + + # create the model + wipe + model basic -ndm 1 -ndf 1 + + node 1 0.0 + node 2 1.0 -mass $M + + fix 1 1 + + uniaxialMaterial Elastic 1 $K 0.0 + uniaxialMaterial Elastic 2 0.0 $c + uniaxialMaterial Parallel 3 1 2 + + element truss 1 1 2 1.0 3 + + set dT 0.0; + set nPts 0; + set factor $g + + source ReadRecord.tcl + ReadRecord $record.AT2 $record.dat dT nPts + + timeSeries Path 1 -filePath $record.dat -dt $dT -factor $g + pattern UniformExcitation 1 1 -accel 1 + + # create the analysis + constraints Plain + integrator Newmark 0.5 [expr 1.0/6.0] + system ProfileSPD + test NormUnbalance 1.0e-12 6 0 + algorithm Newton + numberer RCM + analysis Transient + + set t 0.0 + set maxT [expr (1+$nPts)*$dT]; + set ok 0.0 + set maxD 0.0 + + recorder Node -file accel$record.out -timeSeries 1 -node 2 -dof 1 accel + recorder EnvelopeNode -file disp$record.out -timeSeries 1 -node 2 -dof 1 disp + + + while {$ok == 0 && $t < $maxT} { + set ok [analyze 1 $dT] + if {$ok != 0} { + test NormDispIncr 1.0e-12 100 0 + algorithm ModifiedNewton -initial + set ok [analyze 1 .01] + test NormDispIncr 1.0e-12 10 + algorithm Newton + } + + set time [getTime] + + set t [expr $t + $dT] + } +}