diff --git a/DEVELOPER/core/classTags.h b/DEVELOPER/core/classTags.h index 3127735b5..50ce42de1 100644 --- a/DEVELOPER/core/classTags.h +++ b/DEVELOPER/core/classTags.h @@ -218,11 +218,12 @@ #define MAT_TAG_QzSimple1 207 #define MAT_TAG_PyLiq1 208 #define MAT_TAG_TzLiq1 209 -#define MAT_TAG_PySimple2 210 -#define MAT_TAG_TzSimple2 211 -#define MAT_TAG_QzSimple2 212 -#define MAT_TAG_SteelBRB 213 -#define MAT_TAG_PySimple3 214 +#define MAT_TAG_QzLiq1 210 +#define MAT_TAG_PySimple2 211 +#define MAT_TAG_TzSimple2 212 +#define MAT_TAG_QzSimple2 213 +#define MAT_TAG_SteelBRB 214 +#define MAT_TAG_PySimple3 215 @@ -722,6 +723,8 @@ #define ELE_TAG_EightNodeQuad 208 #define ELE_TAG_SixNodeTri 209 +#define ELE_TAG_ASDEmbeddedNodeElement 217 // Massimo Petracca (ASDEA) + #define FRN_TAG_Coulomb 1 #define FRN_TAG_VelDependent 2 #define FRN_TAG_VelPressureDep 3 diff --git a/EXAMPLES/ExamplePython/Example1.1.py b/EXAMPLES/ExamplePython/Example1.1.py index 5b075e389..5c9728e02 100644 --- a/EXAMPLES/ExamplePython/Example1.1.py +++ b/EXAMPLES/ExamplePython/Example1.1.py @@ -29,11 +29,7 @@ # create ModelBuilder (with two-dimensions and 2 DOF/node) model("BasicBuilder", "-ndm",2, "-ndf",2) -# set default units -defaultUnits("-force", "kip", "-length", "in", "-time", "sec", "-temp", "F") - # create nodes & add to Domain - command: node nodeId xCrd yCrd -#node(1, 0.0, 0.0, "-disp",0.0,0.0, "-vel", 0.0,0.0, "-mass", 0.0,0.0) node(1, 0.0, 0.0) node(2, 144.0, 0.0) node(3, 168.0, 0.0) diff --git a/EXAMPLES/ExampleScripts/Example1.1.tcl b/EXAMPLES/ExampleScripts/Example1.1.tcl index 64cdd7aff..ed41d5e80 100644 --- a/EXAMPLES/ExampleScripts/Example1.1.tcl +++ b/EXAMPLES/ExampleScripts/Example1.1.tcl @@ -23,10 +23,11 @@ # ------------------------------ foreach eleType {truss corotTruss} { - + # Create ModelBuilder (with two-dimensions and 2 DOF/node) - model BasicBuilder -ndm 2 -ndf 2 wipe + model BasicBuilder -ndm 2 -ndf 2 + # Create nodes # ------------ diff --git a/MAKES/Makefile.def.Ubuntu20.04 b/MAKES/Makefile.def.Ubuntu20.04 index 4dee0b607..5e1851d45 100644 --- a/MAKES/Makefile.def.Ubuntu20.04 +++ b/MAKES/Makefile.def.Ubuntu20.04 @@ -15,7 +15,7 @@ # Instructuction for building OpenSees on Ubuntu 20.04 -# NOTE: if you plan to contribue code, fork your own github reo in the browser +# NOTE: if you plan to contribue code, fork your own github repo 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. @@ -23,21 +23,14 @@ # 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 --prefix=$HOME/tcl8.6 --enable-static --disable-shared --enable-64bit +# sudo apt-get install -y git emacs build-essential gfortran tcl8.6 tcl8.6-dev # make # make install # cd $HOME # git clone https://github.com/OpenSees/OpenSees.git # cd OpenSees # cp ./MAKES/Makefile.def.Ubuntu20.04 ./Makefile.def -# make +# make ## For faster compilation, add -j $(numberOfCores) #INTERPRETER_LANGUAGE = PYTHON @@ -115,8 +108,7 @@ 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 - +TCL_LIBRARY = /usr/lib/x86_64-linux-gnu/libtcl8.6.so BLITZ_LIBRARY = $(HOME)/blitz/lib/libblitz.a GRAPHIC_LIBRARY = @@ -267,8 +259,7 @@ MACHINE_INCLUDES = -I/usr/include \ # 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 +TCL_INCLUDES = -I/usr/include/tcl8.6 PYTHON_INCLUDES = -I/usr/include/python3.5 INCLUDES = $(TCL_INCLUDES) $(FE_INCLUDES) $(MACHINE_INCLUDES) $(PYTHON_INCLUDES) diff --git a/SRC/Makefile b/SRC/Makefile index 17c9bd5b3..2e9ecc8a5 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -240,6 +240,7 @@ REMO_LIBS = $(FE)/element/nonlinearBeamColumn/matrixutil/MatrixUtil.o \ $(FE)/element/forceBeamColumn/TrapezoidalBeamIntegration.o \ $(FE)/element/forceBeamColumn/FixedLocationBeamIntegration.o \ $(FE)/element/forceBeamColumn/LowOrderBeamIntegration.o \ + $(FE)/element/forceBeamColumn/ChebyshevBeamIntegration.o \ $(FE)/coordTransformation/CrdTransf.o \ $(FE)/coordTransformation/LinearCrdTransf2d.o \ $(FE)/coordTransformation/PDeltaCrdTransf2d.o \ @@ -343,6 +344,7 @@ PY_SJB_RWB_BJ_LIBS = $(FE)/material/uniaxial/PY/PySimple1.o \ $(FE)/material/uniaxial/PY/ShallowFoundationGen.o \ $(FE)/material/uniaxial/PY/PyLiq1.o \ $(FE)/material/uniaxial/PY/TzLiq1.o \ + $(FE)/material/uniaxial/PY/QzLiq1.o \ $(FE)/material/uniaxial/PY/PySimple1Gen.o \ $(FE)/material/uniaxial/PY/TzSimple1Gen.o @@ -511,7 +513,9 @@ ELE_LIBS = $(FE)/element/Element.o \ $(FE)/element/dispBeamColumn/DispBeamColumnNL2d.o \ $(FE)/element/dispBeamColumn/DispBeamColumn2dThermal.o \ $(FE)/element/dispBeamColumn/DispBeamColumn3d.o \ + $(FE)/element/dispBeamColumn/DispBeamColumnNL3d.o \ $(FE)/element/dispBeamColumn/DispBeamColumnWarping3d.o \ + $(FE)/element/dispBeamColumn/DispBeamColumnAsym3d.o \ $(FE)/element/dispBeamColumn/DispBeamColumn3dThermal.o \ $(FE)/element/dispBeamColumn/DispBeamColumn2dWithSensitivity.o \ $(FE)/element/dispBeamColumn/DispBeamColumn3dWithSensitivity.o \ @@ -532,6 +536,7 @@ ELE_LIBS = $(FE)/element/Element.o \ $(FE)/element/gradientInelasticBeamColumn/TclGradientInelasticBeamColumnCommand.o \ $(FE)/element/mixedBeamColumn/MixedBeamColumn2d.o \ $(FE)/element/mixedBeamColumn/MixedBeamColumn3d.o \ + $(FE)/element/mixedBeamColumn/MixedBeamColumnAsym3d.o \ $(FE)/element/fourNodeQuad/FourNodeQuad.o \ $(FE)/element/fourNodeQuad/FourNodeQuad3d.o \ $(FE)/element/fourNodeQuad/FourNodeQuadWithSensitivity.o \ @@ -625,6 +630,8 @@ ELE_LIBS = $(FE)/element/Element.o \ $(FE)/element/PFEMElement/HigherOrder.o \ $(FE)/element/PFEMElement/Mesh.o \ $(FE)/element/PFEMElement/PFEMContact2D.o \ + $(FE)/element/PFEMElement/BNode.o \ + $(FE)/element/PFEMElement/BCell.o \ $(FE)/element/UWelements/SSPquad.o \ $(FE)/element/UWelements/SSPquadUP.o \ $(FE)/element/UWelements/SSPbrick.o \ @@ -647,7 +654,11 @@ ELE_LIBS = $(FE)/element/Element.o \ $(FE)/element/PML/PML3D.o \ $(FE)/element/PML/pml_2d.o \ $(FE)/element/PML/PML2D.o \ - $(FE)/element/RockingBC/RockingBC.o + $(FE)/element/RockingBC/RockingBC.o \ + $(FE)/element/masonry/MasonPan12.o \ + $(FE)/element/masonry/MasonPan3D.o \ + $(FE)/element/masonry/BeamGT.o \ + $(FE)/element/CEqElement/ASDEmbeddedNodeElement.o # $(FE)/material/nD/Damage2p.o \ # $(FE)/material/nD/Damage2p3D.o \ @@ -808,6 +819,7 @@ MATERIAL_LIBS = $(FE)/material/Material.o \ $(FE)/material/uniaxial/ImpactMaterial.o \ $(FE)/material/uniaxial/SteelBRB.o \ $(FE)/material/uniaxial/GNGMaterial.o \ + $(FE)/material/uniaxial/SMAMaterial.o \ $(FE)/material/uniaxial/SelfCenteringMaterial.o \ $(FE)/material/uniaxial/SPSW02.o \ $(FE)/material/uniaxial/TDConcrete.o \ @@ -845,6 +857,12 @@ MATERIAL_LIBS = $(FE)/material/Material.o \ $(FE)/material/uniaxial/unloading/TakedaUnloadingRule.o \ $(FE)/material/uniaxial/unloading/EnergyUnloadingRule.o \ $(FE)/material/uniaxial/unloading/KarsanUnloadingRule.o \ + $(FE)/material/uniaxial/Masonry.o \ + $(FE)/material/uniaxial/Masonryt.o \ + $(FE)/material/uniaxial/Trilinwpd.o \ + $(FE)/material/uniaxial/Trilinwp.o \ + $(FE)/material/uniaxial/Trilinwp2.o \ + $(FE)/material/uniaxial/SteelFractureDI.o \ $(FE)/material/nD/NDMaterial.o \ $(FE)/material/nD/PlaneStressLayeredMaterial.o \ $(FE)/material/nD/PlaneStressRebarMaterial.o \ @@ -896,6 +914,8 @@ MATERIAL_LIBS = $(FE)/material/Material.o \ $(FE)/material/nD/UWmaterials/ManzariDafaliasPlaneStrainRO.o \ $(FE)/material/nD/UWmaterials/InitialStateAnalysisWrapper.o \ $(FE)/material/nD/UWmaterials/J2CyclicBoundingSurface.o \ + $(FE)/material/nD/UWmaterials/J2CyclicBoundingSurface3D.o \ + $(FE)/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.o \ $(FE)/material/nD/UWmaterials/PM4Sand.o \ $(FE)/material/nD/UWmaterials/PM4Silt.o \ $(FE)/material/nD/LinearCap.o \ @@ -1015,9 +1035,9 @@ SECTION_LIBS = $(FE)/material/section/SectionForceDeformation.o \ $(FE)/material/section/LayeredShellFiberSectionThermal.o \ $(FE)/material/section/FiberSection3dThermal.o \ $(FE)/material/section/MembranePlateFiberSectionThermal.o \ - $(FE)/material/section/FiberSectionGJThermal.o \ $(FE)/material/section/FiberSection3d.o \ $(FE)/material/section/FiberSectionWarping3d.o \ + $(FE)/material/section/FiberSectionAsym3d.o \ $(FE)/material/section/NDFiberSection3d.o \ $(FE)/material/section/SectionAggregator.o \ $(FE)/material/section/ParallelSection.o \ @@ -1057,6 +1077,13 @@ SECTION_LIBS = $(FE)/material/section/SectionForceDeformation.o \ SUPER_LU_OBJ = $(FE)/system_of_eqn/linearSOE/sparseGEN/SuperLU.o +PETSC_SOE_OBJ = +ifeq ($(HAVEPETSC), YES) + PETSC_SOE_OBJ = $(FE)/system_of_eqn/linearSOE/petsc/PetscSOE.o \ + $(FE)/system_of_eqn/linearSOE/petsc/PetscSolver.o \ + $(FE)/system_of_eqn/linearSOE/petsc/PetscSparseSeqSolver.o +endif + ifeq ($(PROGRAMMING_MODE), THREADS) SUPER_LU_OBJ = $(FE)/system_of_eqn/linearSOE/sparseGEN/ThreadedSuperLU.o endif @@ -1068,7 +1095,8 @@ SUPER_LU_OBJ = $(FE)/system_of_eqn/linearSOE/sparseGEN/SuperLU.o \ $(FE)/system_of_eqn/linearSOE/mumps/MumpsParallelSOE.o \ $(FE)/system_of_eqn/linearSOE/mumps/MumpsParallelSolver.o \ $(FE)/system_of_eqn/linearSOE/mumps/MumpsSOE.o \ - $(FE)/system_of_eqn/linearSOE/mumps/MumpsSolver.o + $(FE)/system_of_eqn/linearSOE/mumps/MumpsSolver.o \ + $(PETSC_SOE_OBJ) endif ifeq ($(PROGRAMMING_MODE), PARALLEL_INTERPRETERS) @@ -1081,6 +1109,8 @@ SUPER_LU_OBJ = $(FE)/system_of_eqn/linearSOE/sparseGEN/SuperLU.o \ $(FE)/system_of_eqn/linearSOE/mumps/MumpsSolver.o endif + + CUDA_CLASSES = SequentialSysOfEqn_LIBS = $(FE)/system_of_eqn/linearSOE/LinearSOE.o \ diff --git a/SRC/Makefile.incl b/SRC/Makefile.incl index a5538c0fa..83b7260dd 100644 --- a/SRC/Makefile.incl +++ b/SRC/Makefile.incl @@ -113,6 +113,7 @@ FE_INCLUDES = -I$(FE)/matrix \ -I$(FE)/element/twoNodeLink \ -I$(FE)/element/updatedLagrangianBeamColumn \ -I$(FE)/element/RockingBC \ + -I$(FE)/element/CEqElement \ -I$(FE)/element/UWelements \ -I$(FE)/element/HUelements \ -I$(FE)/analysis \ diff --git a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp index a048df2bf..dfbef56bd 100644 --- a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp +++ b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp @@ -107,6 +107,7 @@ #include "PY/QzSimple2.h" #include "PY/PyLiq1.h" #include "PY/TzLiq1.h" +#include "PY/QzLiq1.h" #include "fedeas/FedeasBond1Material.h" #include "fedeas/FedeasBond2Material.h" @@ -138,6 +139,7 @@ //#include "FiberSection.h" #include "FiberSection2d.h" #include "FiberSection3d.h" +#include "FiberSectionAsym3d.h" //Xinlong Du #include "ElasticPlateSection.h" #include "ElasticMembranePlateSection.h" #include "MembranePlateFiberSection.h" @@ -190,6 +192,9 @@ #include "UWmaterials/ManzariDafaliasPlaneStrainRO.h" #include "UWmaterials/PM4Sand.h" #include "UWmaterials/PM4Silt.h" +#include "J2CyclicBoundingSurface.h" +#include "J2CyclicBoundingSurface3D.h" +#include "J2CyclicBoundingSurfacePlaneStrain.h" #include "UWmaterials/InitialStateAnalysisWrapper.h" #include "stressDensityModel/stressDensity.h" #include "InitStressNDMaterial.h" @@ -259,6 +264,8 @@ #include "dispBeamColumn/DispBeamColumn2d.h" #include "dispBeamColumn/DispBeamColumn3d.h" +#include "dispBeamColumn/DispBeamColumnAsym3d.h" //Xinlong Du +#include "mixedBeamColumn/MixedBeamColumnAsym3d.h" //Xinlong Du #include "shell/ShellMITC4.h" #include "shell/ShellMITC9.h" #include "shell/ShellDKGQ.h" //Added by Lisha Wang, Xinzheng Lu, Linlin Xie, Song Cen & Quan Gu @@ -297,6 +304,8 @@ #include "PFEMElement/PFEMElement2D.h" #include "RockingBC/RockingBC.h" +#include "CEqElement/ASDEmbeddedNodeElement.h" + #include "LinearCrdTransf2d.h" #include "LinearCrdTransf3d.h" #include "PDeltaCrdTransf2d.h" @@ -713,6 +722,12 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_DispBeamColumn3d: return new DispBeamColumn3d(); + + case ELE_TAG_DispBeamColumnAsym3d: + return new DispBeamColumnAsym3d(); //Xinlong Du + + case ELE_TAG_MixedBeamColumnAsym3d: + return new MixedBeamColumnAsym3d(); //Xinlong Du case ELE_TAG_EnhancedQuad: return new EnhancedQuad(); @@ -882,6 +897,9 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_RockingBC: return new RockingBC(); + case ELE_TAG_ASDEmbeddedNodeElement: + return new ASDEmbeddedNodeElement(); + default: opserr << "FEM_ObjectBrokerAllClasses::getNewElement - "; opserr << " - no Element type exists for class tag " ; @@ -1197,7 +1215,7 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_Fatigue: return new FatigueMaterial(); - case MAT_TAG_TzLiq1: + case MAT_TAG_TzLiq1: return new TzLiq1(); case MAT_TAG_QzSimple1: @@ -1206,6 +1224,9 @@ FEM_ObjectBrokerAllClasses::getNewUniaxialMaterial(int classTag) case MAT_TAG_QzSimple2: return new QzSimple2(); + case MAT_TAG_QzLiq1: + return new QzLiq1(); + case MAT_TAG_Hysteretic: return new HystereticMaterial(); @@ -1367,6 +1388,9 @@ FEM_ObjectBrokerAllClasses::getNewSection(int classTag) case SEC_TAG_FiberSection3d: return new FiberSection3d(); + case SEC_TAG_FiberSectionAsym3d: + return new FiberSectionAsym3d(); //Xinlong Du + case SEC_TAG_ElasticPlateSection: return new ElasticPlateSection(); @@ -1507,6 +1531,15 @@ FEM_ObjectBrokerAllClasses::getNewNDMaterial(int classTag) case ND_TAG_PM4Silt: return new PM4Silt(); + case ND_TAG_J2CyclicBoundingSurface: + return new J2CyclicBoundingSurface(); + + case ND_TAG_J2CyclicBoundingSurface3D: + return new J2CyclicBoundingSurface3D(); + + case ND_TAG_J2CyclicBoundingSurfacePlaneStrain: + return new J2CyclicBoundingSurfacePlaneStrain(); + case ND_TAG_InitialStateAnalysisWrapper: return new InitialStateAnalysisWrapper(); @@ -2254,8 +2287,7 @@ FEM_ObjectBrokerAllClasses::getNewLinearSOE(int classTagSOE) #ifdef _PETSC case LinSOE_TAGS_PetscSOE: - thePetscSolver = new PetscSolver(); - theSOE = new PetscSOE(*thePetscSolver); + theSOE = new PetscSOE(*( new PetscSolver())); return theSOE; #endif diff --git a/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp b/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp index 01cd27c6e..d187e4441 100644 --- a/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp +++ b/SRC/analysis/algorithm/equiSolnAlgo/ExpressNewton.cpp @@ -54,6 +54,35 @@ #include #include +void *OPS_ExpressNewton() +{ + int nIter = 2, factorOnce = 0, formTangent = CURRENT_TANGENT; + double kMultiplier = 1.0; + + int nArgs = OPS_GetNumRemainingInputArgs(); + int numData = 1; + if (nArgs > 0 && OPS_GetIntInput(&numData,&nIter) < 0) { + opserr << "WARNING ExpressNewton -- error reading nIter\n"; + return 0; + } + if (nArgs > 1 && OPS_GetDoubleInput(&numData,&kMultiplier) < 0) { + opserr << "WARNING ExpressNewton -- error reading kMultiplier\n"; + return 0; + } + while (OPS_GetNumRemainingInputArgs() > 0) { + const char *type = OPS_GetString(); + if ((strcmp(type,"-initialTangent") == 0) || (strcmp(type,"-InitialTangent") == 0)) { + formTangent = INITIAL_TANGENT; + } else if ((strcmp(type,"-currentTangent") == 0) || (strcmp(type,"-CurrentTangent") ==0 )) { + formTangent = CURRENT_TANGENT; + } else if ((strcmp(type,"-factorOnce") == 0) || (strcmp(type,"-FactorOnce") ==0 )) { + factorOnce = 1; + } + } + + return new ExpressNewton(nIter,kMultiplier,formTangent,factorOnce); +} + // Constructor ExpressNewton::ExpressNewton(int ni, double km, int tg, int fo) :EquiSolnAlgo(EquiALGORITHM_TAGS_ExpressNewton), nIter(ni), factorOnce(fo) diff --git a/SRC/analysis/integrator/ExplicitDifference.cpp b/SRC/analysis/integrator/ExplicitDifference.cpp index 272f4c72b..80fb21271 100644 --- a/SRC/analysis/integrator/ExplicitDifference.cpp +++ b/SRC/analysis/integrator/ExplicitDifference.cpp @@ -13,19 +13,19 @@ #define OPS_Export -void* OPS_Explicitdifference(void) +void* OPS_ExplicitDifference(void) { TransientIntegrator *theIntegrator = 0; - theIntegrator = new Explicitdifference(); + theIntegrator = new ExplicitDifference(); if (theIntegrator == 0) - opserr << "WARNING - out of memory creating Explicitdifference integrator\n"; + opserr << "WARNING - out of memory creating ExplicitDifference integrator\n"; return theIntegrator; } -Explicitdifference::Explicitdifference() +ExplicitDifference::ExplicitDifference() : TransientIntegrator(INTEGRATOR_TAGS_ExplicitDifference), deltaT(0.0), alphaM(0.0), betaK(0.0), betaKi(0.0), betaKc(0.0), @@ -37,7 +37,7 @@ Explicitdifference::Explicitdifference() } -Explicitdifference::Explicitdifference( +ExplicitDifference::ExplicitDifference( double _alphaM, double _betaK, double _betaKi, double _betaKc) : TransientIntegrator(INTEGRATOR_TAGS_ExplicitDifference), deltaT(0.0), @@ -50,7 +50,7 @@ Explicitdifference::Explicitdifference( } -Explicitdifference::~Explicitdifference() +ExplicitDifference::~ExplicitDifference() { // clean up the memory created @@ -72,14 +72,14 @@ Explicitdifference::~Explicitdifference() } -int Explicitdifference::newStep(double _deltaT) +int ExplicitDifference::newStep(double _deltaT) { updateCount = 0; deltaT = _deltaT; if (deltaT <= 0.0) { - opserr << "Explicitdifference::newStep() - error in variable\n"; + opserr << "ExplicitDifference::newStep() - error in variable\n"; opserr << "dT = " << deltaT << endln; return -1; } @@ -94,7 +94,7 @@ int Explicitdifference::newStep(double _deltaT) int size = Utdotdot->Size(); if (Ut == 0) { - opserr << "Explicitdifference::newStep() - domainChange() failed or hasn't been called\n"; + opserr << "ExplicitDifference::newStep() - domainChange() failed or hasn't been called\n"; return -2; } @@ -109,7 +109,7 @@ int Explicitdifference::newStep(double _deltaT) // increment the time to t and apply the load double time = theModel->getCurrentDomainTime(); if (theModel->updateDomain(time, deltaT) < 0) { - opserr << "Explicitdifference::newStep() - failed to update the domain\n"; + opserr << "ExplicitDifference::newStep() - failed to update the domain\n"; return -3; } @@ -120,7 +120,7 @@ int Explicitdifference::newStep(double _deltaT) } -int Explicitdifference::formEleTangent(FE_Element *theEle) +int ExplicitDifference::formEleTangent(FE_Element *theEle) { theEle->zeroTangent(); @@ -130,7 +130,7 @@ int Explicitdifference::formEleTangent(FE_Element *theEle) } -int Explicitdifference::formNodTangent(DOF_Group *theDof) +int ExplicitDifference::formNodTangent(DOF_Group *theDof) { theDof->zeroTangent(); @@ -140,7 +140,7 @@ int Explicitdifference::formNodTangent(DOF_Group *theDof) } -int Explicitdifference::domainChanged() +int ExplicitDifference::domainChanged() { AnalysisModel *theModel = this->getAnalysisModel(); @@ -195,7 +195,7 @@ int Explicitdifference::domainChanged() Utdot1 == 0 || Utdot1->Size() != size ) { - opserr << "Explicitdifference::domainChanged - ran out of memory\n"; + opserr << "ExplicitDifference::domainChanged - ran out of memory\n"; // delete the old @@ -261,36 +261,36 @@ int Explicitdifference::domainChanged() } } - opserr << "WARNING: Explicitdifference::domainChanged() - assuming Ut-1 = Ut\n"; + opserr << "WARNING: ExplicitDifference::domainChanged() - assuming Ut-1 = Ut\n"; return 0; } -int Explicitdifference::update(const Vector &Udotdot) +int ExplicitDifference::update(const Vector &Udotdot) { updateCount++; if (updateCount > 2) { - opserr << "WARNING Explicitdifference::update() - called more than once -"; - opserr << " Explicitdifference integration scheme requires a LINEAR solution algorithm\n"; + opserr << "WARNING ExplicitDifference::update() - called more than once -"; + opserr << " ExplicitDifference integration scheme requires a LINEAR solution algorithm\n"; return -1; } AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { - opserr << "WARNING Explicitdifference::update() - no souAnalysisModel set\n"; + opserr << "WARNING ExplicitDifference::update() - no souAnalysisModel set\n"; return -2; } // check domainChanged() has been called, i.e. Ut will not be zero if (Ut == 0) { - opserr << "WARNING Explicitdifference::update() - domainChange() failed or not called\n"; + opserr << "WARNING ExplicitDifference::update() - domainChange() failed or not called\n"; return -3; } // check Udotdot is of correct size if (Udotdot.Size() != Utdotdot->Size()) { - opserr << "WARNING Explicitdifference::update() - Vectors of incompatible size "; + opserr << "WARNING ExplicitDifference::update() - Vectors of incompatible size "; opserr << " expecting " << Utdotdot->Size() << " obtained " << Udotdot.Size() << endln; return -4; } @@ -312,7 +312,7 @@ int Explicitdifference::update(const Vector &Udotdot) theModel->setResponse(*Ut, *Utdot1, Udotdot); if (theModel->updateDomain() < 0) { - opserr << "Explicitdifference::update() - failed to update the domain\n"; + opserr << "ExplicitDifference::update() - failed to update the domain\n"; return -5; } @@ -330,11 +330,11 @@ int Explicitdifference::update(const Vector &Udotdot) } -int Explicitdifference::commit(void) +int ExplicitDifference::commit(void) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { - opserr << "WARNING Explicitdifference::commit() - no AnalysisModel set\n"; + opserr << "WARNING ExplicitDifference::commit() - no AnalysisModel set\n"; return -1; } @@ -347,7 +347,7 @@ int Explicitdifference::commit(void) } -int Explicitdifference::sendSelf(int cTag, Channel &theChannel) +int ExplicitDifference::sendSelf(int cTag, Channel &theChannel) { Vector data(4); data(0) = alphaM; @@ -356,7 +356,7 @@ int Explicitdifference::sendSelf(int cTag, Channel &theChannel) data(3) = betaKc; if (theChannel.sendVector(this->getDbTag(), cTag, data) < 0) { - opserr << "WARNING Explicitdifference::sendSelf() - could not send data\n"; + opserr << "WARNING ExplicitDifference::sendSelf() - could not send data\n"; return -1; } @@ -364,11 +364,11 @@ int Explicitdifference::sendSelf(int cTag, Channel &theChannel) } -int Explicitdifference::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +int ExplicitDifference::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker) { Vector data(4); if (theChannel.recvVector(this->getDbTag(), cTag, data) < 0) { - opserr << "WARNING Explicitdifference::recvSelf() - could not receive data\n"; + opserr << "WARNING ExplicitDifference::recvSelf() - could not receive data\n"; return -1; } @@ -381,24 +381,24 @@ int Explicitdifference::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker } -void Explicitdifference::Print(OPS_Stream &s, int flag) +void ExplicitDifference::Print(OPS_Stream &s, int flag) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel != 0) { double currentTime = theModel->getCurrentDomainTime(); - s << "Explicitdifference - currentTime: " << currentTime << endln; + s << "ExplicitDifference - currentTime: " << currentTime << endln; s << " Rayleigh Damping - alphaM: " << alphaM << " betaK: " << betaK; s << " betaKi: " << betaKi << " betaKc: " << betaKc << endln; } else - s << "Explicitdifference - no associated AnalysisModel\n"; + s << "ExplicitDifference - no associated AnalysisModel\n"; } //a interface to get velosity for modal damping const Vector & -Explicitdifference::getVel() +ExplicitDifference::getVel() { return *Utdot; } diff --git a/SRC/analysis/integrator/ExplicitDifference.h b/SRC/analysis/integrator/ExplicitDifference.h index 05b0ae006..822d47022 100644 --- a/SRC/analysis/integrator/ExplicitDifference.h +++ b/SRC/analysis/integrator/ExplicitDifference.h @@ -1,6 +1,6 @@ -#ifndef Explicitdifference_h -#define Explicitdifference_h +#ifndef ExplicitDifference_h +#define ExplicitDifference_h #include @@ -9,12 +9,12 @@ class DOF_Group; class FE_Element; class Vector; -class Explicitdifference : public TransientIntegrator +class ExplicitDifference : public TransientIntegrator { public: - Explicitdifference(); - Explicitdifference(double alphaM, double betaK, double betaKi, double betaKc); - ~Explicitdifference(); //constructors and unconstructor + ExplicitDifference(); + ExplicitDifference(double alphaM, double betaK, double betaKi, double betaKc); + ~ExplicitDifference(); //constructors and unconstructor diff --git a/SRC/analysis/integrator/Newmark.cpp b/SRC/analysis/integrator/Newmark.cpp index 873188b89..d66f64ca5 100644 --- a/SRC/analysis/integrator/Newmark.cpp +++ b/SRC/analysis/integrator/Newmark.cpp @@ -411,6 +411,11 @@ int Newmark::domainChanged() } } + // The remaining get**Sensitivity methods cause seg faults with Lagrange constraint + // handler in dynamic (transient) analysis even when there is no sensitivity algorithm. + // However, I don't think these methods need to be called in domainChanged -- MHS + continue; + const Vector &dispSens = dofPtr->getDispSensitivity(gradNumber); for (i=0; i < idSize; i++) { int loc = id(i); diff --git a/SRC/analysis/integrator/PFEMIntegrator.cpp b/SRC/analysis/integrator/PFEMIntegrator.cpp index cac69ebf9..971257766 100644 --- a/SRC/analysis/integrator/PFEMIntegrator.cpp +++ b/SRC/analysis/integrator/PFEMIntegrator.cpp @@ -60,7 +60,7 @@ OPS_PFEMIntegrator(void) TransientIntegrator *theIntegrator = 0; int dispFlag = 2; - int init = 1; + int init = 2; double dData[2] = {-1.0, -1.0}; int numData = 2; if (OPS_GetNumRemainingInputArgs() > 1) { @@ -262,10 +262,10 @@ int PFEMIntegrator::newStep(double deltaT) *U = *Ut; *Udotdot = *Utdotdot; if (gamma>0 && beta>0) { - U->addVector(1.0, *Utdot, deltaT*(1-beta/gamma)); + U->addVector(1.0, *Utdot, deltaT*(1.0-beta/gamma)); U->addVector(1.0, *Udot, deltaT*beta/gamma); U->addVector(1.0, *Utdotdot, deltaT*deltaT*(0.5-beta/gamma)); - Udotdot->addVector((1-1.0/gamma), *Udot, 1.0/(gamma*deltaT)); + Udotdot->addVector((1.0-1.0/gamma), *Udot, 1.0/(gamma*deltaT)); Udotdot->addVector(1.0, *Utdot, -1.0/(gamma*deltaT)); } else { U->addVector(1.0, *Udot, deltaT); @@ -369,13 +369,6 @@ PFEMIntegrator::formTangent(int statFlag) DOF_Group *dofPtr; while ((dofPtr = theDOFs()) != 0) { - PFEMLinSOE* soe = dynamic_cast(getLinearSOE()); - if (soe != 0) { - if (soe->skipFluid() && soe->isFluidID(dofPtr->getID())) { - continue; - } - } - if (theLinSOE->addA(dofPtr->getTangent(this),dofPtr->getID()) <0) { opserr << "TransientIntegrator::formTangent() - failed to addA:dof\n"; result = -1; @@ -386,12 +379,6 @@ PFEMIntegrator::formTangent(int statFlag) FE_EleIter &theEles2 = theModel->getFEs(); FE_Element *elePtr; while((elePtr = theEles2()) != 0) { - PFEMLinSOE* soe = dynamic_cast(getLinearSOE()); - if (soe != 0) { - if (soe->skipFluid() && soe->isFluidID(elePtr->getID())) { - continue; - } - } if (theLinSOE->addA(elePtr->getTangent(this),elePtr->getID()) < 0) { opserr << "TransientIntegrator::formTangent() - failed to addA:ele\n"; result = -2; diff --git a/SRC/classTags.h b/SRC/classTags.h index a492f930a..58c2f7a05 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -223,14 +223,20 @@ #define MAT_TAG_QzSimple1 207 #define MAT_TAG_PyLiq1 208 #define MAT_TAG_TzLiq1 209 -#define MAT_TAG_PySimple2 210 -#define MAT_TAG_TzSimple2 211 -#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_QzLiq1 210 +#define MAT_TAG_PySimple2 211 +#define MAT_TAG_TzSimple2 212 +#define MAT_TAG_QzSimple2 213 +#define MAT_TAG_SteelBRB 214 +#define MAT_TAG_PySimple3 215 +#define MAT_TAG_PlateBearingConnectionThermal 216 +#define MAT_TAG_ASD_SMA_3K 217 +#define MAT_TAG_SteelFractureDI 218 // galvisf +#define MAT_TAG_Masonry 219 +#define MAT_TAG_Masonryt 220 +#define MAT_TAG_Trilinwp 221 +#define MAT_TAG_Trilinwp2 222 +#define MAT_TAG_Trilinwpd 223 #define MAT_TAG_FedeasMaterial 1000 #define MAT_TAG_FedeasBond1 1001 @@ -292,6 +298,7 @@ #define SEC_TAG_NDFiberSection2d 900 #define SEC_TAG_FiberSection3d 10 #define SEC_TAG_FiberSectionWarping3d 1010 +#define SEC_TAG_FiberSectionAsym3d 1011 #define SEC_TAG_NDFiberSection3d 1000 #define SEC_TAG_FiberSectionGJ 11 #define SEC_TAG_BeamFiberSection 12 @@ -458,7 +465,7 @@ #define ND_TAG_PM4Sand 14021 // PM4Silt material - L.Chen #define ND_TAG_PM4Silt 14022 -// J2CyclicBoundingSurface material - D.Turello +// J2CyclicBoundingSurface material - P. Arduino, D.Turello #define ND_TAG_J2CyclicBoundingSurface 14023 #define ND_TAG_J2CyclicBoundingSurface3D 14024 #define ND_TAG_J2CyclicBoundingSurfacePlaneStrain 14025 @@ -622,7 +629,9 @@ #define ELE_TAG_DispBeamColumnNL2d 621 #define ELE_TAG_TimoshenkoBeamColumn2d 63 #define ELE_TAG_DispBeamColumn3d 64 +#define ELE_TAG_DispBeamColumnNL3d 640 #define ELE_TAG_DispBeamColumnWarping3d 641 +#define ELE_TAG_DispBeamColumnAsym3d 642 #define ELE_TAG_HingedBeam2d 65 #define ELE_TAG_HingedBeam3d 66 #define ELE_TAG_TwoPointHingedBeam2d 67 @@ -641,6 +650,7 @@ #define ELE_TAG_ForceBeamColumnCBDI3d 78 #define ELE_TAG_MixedBeamColumn2d 30766 #define ELE_TAG_MixedBeamColumn3d 30765 +#define ELE_TAG_MixedBeamColumnAsym3d 30767 #define ELE_TAG_DispBeamColumn2dInt 79 #define ELE_TAG_InternalSpring 80 #define ELE_TAG_SimpleJoint2D 81 @@ -776,6 +786,10 @@ #define ELE_TAG_BeamColumn2DwLHNMYS_Damage 211 #define ELE_TAG_MVLEM_3D 212 // Kristijan Kolozvari #define ELE_TAG_SFI_MVLEM_3D 213 // Kristijan Kolozvari +#define ELE_TAG_BeamGT 214 +#define ELE_TAG_MasonPan12 215 +#define ELE_TAG_MasonPan3D 216 +#define ELE_TAG_ASDEmbeddedNodeElement 217 // Massimo Petracca (ASDEA) #define ELE_TAG_ExternalElement 99990 diff --git a/SRC/convergenceTest/CTestPFEM.cpp b/SRC/convergenceTest/CTestPFEM.cpp index e6d1bda29..0b8273c01 100644 --- a/SRC/convergenceTest/CTestPFEM.cpp +++ b/SRC/convergenceTest/CTestPFEM.cpp @@ -153,7 +153,6 @@ int CTestPFEM::test(void) const Vector &x = theSOE->getX(); const Vector &B = theSOE->getB(); const ID& dofType = theSOE->getDofType(); - int stage = theSOE->getStage(); if(dofType.Size() != x.Size()) { opserr << "WARNING: x and dofType have different size -- CTestPFEM::test()\n"; return -2; @@ -227,18 +226,6 @@ int CTestPFEM::test(void) normprel = 0.0; } - if (stage==1 || stage==3) { - normp = 0; - normresp = 0; - normprel = 0; - normpi = 0; - normrespi = 0; - } else if (stage == 2) { - normv = 0; - normresv = 0; - normvrel = 0; - } - // record norms if(currentIter <= maxNumIter) { normsv.push_back(normv); @@ -248,7 +235,7 @@ int CTestPFEM::test(void) } // check for norm increase - if(stage==0 && currentIter > 1 && maxIncr > 0) { + if(currentIter > 1 && maxIncr > 0) { if(normv>10*normsv[currentIter-2] || normp>10*normsp[currentIter-2] || normresv>10*normsresv[currentIter-2] || normresp>10*normsresp[currentIter-2]) { numIncr++; @@ -258,13 +245,6 @@ int CTestPFEM::test(void) // print the data if required if(printFlag == 1) { opserr << "PFEM: " << currentIter; - if (stage == 1) { - opserr << " -- Predictor Stage\n"; - } else if (stage == 2) { - opserr << " -- Pressure Stage\n"; - } else if (stage == 3) { - opserr << " -- Corrector Stage\n"; - } opserr << " dV(" << normv << "," << normvrel; opserr << "), dP(" << normp << "," << normprel; opserr << "), dPi(" << normpi; @@ -303,13 +283,8 @@ int CTestPFEM::test(void) } } - if (stage == 1) { - theSOE->setStage(2); - } else if (stage == 0 || stage == 3) { - - // return the number of times test has been called - return currentIter; - } + // return the number of times test has been called + return currentIter; } // algo failed to converged after specified number of iterations - but RETURN OK @@ -342,9 +317,6 @@ int CTestPFEM::test(void) } // algorithm not yet converged - increment counter and return -1 - if (stage == 2) { - theSOE->setStage(3); - } currentIter++; return -1; } diff --git a/SRC/domain/domain/Domain.cpp b/SRC/domain/domain/Domain.cpp index 6d9f59813..b1377abb1 100644 --- a/SRC/domain/domain/Domain.cpp +++ b/SRC/domain/domain/Domain.cpp @@ -98,7 +98,7 @@ Domain::Domain() dbEle(0), dbNod(0), dbSPs(0), dbPCs(0), dbMPs(0), dbLPs(0), dbParam(0), eleGraphBuiltFlag(false), nodeGraphBuiltFlag(false), theNodeGraph(0), theElementGraph(0), - theRegions(0), numRegions(0), commitTag(0), + theRegions(0), numRegions(0), commitTag(0), initBounds(true), resetBounds(false), theBounds(6), theEigenvalues(0), theEigenvalueSetTime(0), theModalProperties(0), theModalDampingFactors(0), inclModalMatrix(false), @@ -154,7 +154,7 @@ Domain::Domain(int numNodes, int numElements, int numSPs, int numMPs, dbEle(0), dbNod(0), dbSPs(0), dbPCs(0), dbMPs(0), dbLPs(0), dbParam(0), eleGraphBuiltFlag(false), nodeGraphBuiltFlag(false), theNodeGraph(0), theElementGraph(0), - theRegions(0), numRegions(0), commitTag(0), + theRegions(0), numRegions(0), commitTag(0), initBounds(true), resetBounds(false), theBounds(6), theEigenvalues(0), theEigenvalueSetTime(0), theModalProperties(0), theModalDampingFactors(0), inclModalMatrix(false), @@ -215,7 +215,7 @@ Domain::Domain(TaggedObjectStorage &theNodesStorage, theSPs(&theSPsStorage), theMPs(&theMPsStorage), theLoadPatterns(&theLoadPatternsStorage), - theRegions(0), numRegions(0), commitTag(0), + theRegions(0), numRegions(0), commitTag(0), initBounds(true), resetBounds(false), theBounds(6), theEigenvalues(0), theEigenvalueSetTime(0), theModalProperties(0), theModalDampingFactors(0), inclModalMatrix(false), @@ -274,7 +274,7 @@ Domain::Domain(TaggedObjectStorage &theStorage) dbEle(0), dbNod(0), dbSPs(0), dbPCs(0), dbMPs(0), dbLPs(0), dbParam(0), eleGraphBuiltFlag(false), nodeGraphBuiltFlag(false), theNodeGraph(0), theElementGraph(0), - theRegions(0), numRegions(0), commitTag(0), + theRegions(0), numRegions(0), commitTag(0),initBounds(true), resetBounds(false), theBounds(6), theEigenvalues(0), theEigenvalueSetTime(0), theModalProperties(0), theModalDampingFactors(0), inclModalMatrix(false), @@ -488,27 +488,48 @@ Domain::addNode(Node * node) if (result == true) { node->setDomain(this); this->domainChange(); - - // see if the physical bounds are changed - // note this assumes 0,0,0,0,0,0 as startup min,max values - const Vector &crds = node->getCrds(); - int dim = crds.Size(); - if (dim >= 1) { - double x = crds(0); - if (x < theBounds(0)) theBounds(0) = x; - if (x > theBounds(3)) theBounds(3) = x; - } - if (dim >= 2) { - double y = crds(1); - if (y < theBounds(1)) theBounds(1) = y; - if (y > theBounds(4)) theBounds(4) = y; - } - if (dim == 3) { - double z = crds(2); - if (z < theBounds(2)) theBounds(2) = z; - if (z > theBounds(5)) theBounds(5) = z; + + if (!resetBounds) { + // see if the physical bounds are changed + // note this assumes 0,0,0,0,0,0 as startup min,max values + const Vector& crds = node->getCrds(); + int dim = crds.Size(); + if (initBounds) { + if (dim >= 1) { + double x = crds(0); + theBounds(0) = x; + theBounds(3) = x; + } + if (dim >= 2) { + double y = crds(1); + theBounds(1) = y; + theBounds(4) = y; + } + if (dim == 3) { + double z = crds(2); + theBounds(2) = z; + theBounds(5) = z; + } + initBounds = false; + } + else { + if (dim >= 1) { + double x = crds(0); + if (x < theBounds(0)) theBounds(0) = x; + if (x > theBounds(3)) theBounds(3) = x; + } + if (dim >= 2) { + double y = crds(1); + if (y < theBounds(1)) theBounds(1) = y; + if (y > theBounds(4)) theBounds(4) = y; + } + if (dim == 3) { + double z = crds(2); + if (z < theBounds(2)) theBounds(2) = z; + if (z > theBounds(5)) theBounds(5) = z; + } + } } - } else opserr << "Domain::addNode - node with tag " << nodTag << "could not be added to container\n"; @@ -987,12 +1008,13 @@ Domain::clearAll(void) { this->setModalDampingFactors(0); // set the bounds around the origin + initBounds = true; theBounds(0) = 0; theBounds(1) = 0; theBounds(2) = 0; theBounds(3) = 0; - theBounds(4) = 0; - theBounds(5) = 0; + theBounds(4) = 0; + theBounds(5) = 0; currentGeoTag = 0; lastGeoSendTag = -1; @@ -1057,11 +1079,16 @@ Domain::removeNode(int tag) // mark the domain has having changed this->domainChange(); + + // adjust node bounds + resetBounds = true; // perform a downward cast to a Node (safe as only Node added to // this container and return the result of the cast Node *result = (Node *)mc; // result->setDomain(0); + + return result; } @@ -1596,6 +1623,63 @@ Domain::getNumParameters(void) const const Vector & Domain::getPhysicalBounds(void) { + // reset bounds if nodes were deleted + if (resetBounds) { + initBounds = true; + theBounds(0) = 0; + theBounds(1) = 0; + theBounds(2) = 0; + theBounds(3) = 0; + theBounds(4) = 0; + theBounds(5) = 0; + if (theNodes->getNumComponents() != 0) { + initBounds = false; + Node* nodePtr; + NodeIter& theNodeIter = this->getNodes(); + // initialize with first node + nodePtr = theNodeIter(); + const Vector& crds = nodePtr->getCrds(); + int dim = crds.Size(); + double x, y, z; + if (dim >= 1) { + x = crds(0); + theBounds(0) = x; + theBounds(3) = x; + } + if (dim >= 2) { + y = crds(1); + theBounds(1) = y; + theBounds(4) = y; + } + if (dim == 3) { + z = crds(2); + theBounds(2) = z; + theBounds(5) = z; + } + // adjust for other nodes + while ((nodePtr = theNodeIter()) != 0) { + const Vector& crds = nodePtr->getCrds(); + dim = crds.Size(); + if (dim >= 1) { + x = crds(0); + if (x < theBounds(0)) theBounds(0) = x; + if (x > theBounds(3)) theBounds(3) = x; + } + if (dim >= 2) { + y = crds(1); + if (y < theBounds(1)) theBounds(1) = y; + if (y > theBounds(4)) theBounds(4) = y; + } + if (dim == 3) { + z = crds(2); + if (z < theBounds(2)) theBounds(2) = z; + if (z > theBounds(5)) theBounds(5) = z; + } + } + } + resetBounds = false; + } + return theBounds; } diff --git a/SRC/domain/domain/Domain.h b/SRC/domain/domain/Domain.h index 1a1378e8d..c8e53c66b 100644 --- a/SRC/domain/domain/Domain.h +++ b/SRC/domain/domain/Domain.h @@ -289,6 +289,8 @@ class Domain int commitTag; Vector theBounds; + bool initBounds; // added to fix bug when all nodes are positive or negative - ambaker1 + bool resetBounds; // added to optimize bound resetting for when nodes are removed. Vector *theEigenvalues; double theEigenvalueSetTime; diff --git a/SRC/domain/domain/partitioned/PartitionedDomain.cpp b/SRC/domain/domain/partitioned/PartitionedDomain.cpp index b9f44a168..7081b79c4 100644 --- a/SRC/domain/domain/partitioned/PartitionedDomain.cpp +++ b/SRC/domain/domain/partitioned/PartitionedDomain.cpp @@ -1346,6 +1346,10 @@ PartitionedDomain::revertToStart(void) return res; } } + +#ifdef _PARALLEL_PROCESSING + this->barrierCheck(result); +#endif } return 0; @@ -1402,8 +1406,9 @@ PartitionedDomain::removeRecorders(void) if (this->Domain::removeRecorders() < 0) return -1; +#ifdef _PARALLEL_PROCESSING this->barrierCheck(1.0); - +#endif return 0; } diff --git a/SRC/domain/pattern/drm/H5DRM.cpp b/SRC/domain/pattern/drm/H5DRM.cpp index 33b7ad223..00bc8863c 100644 --- a/SRC/domain/pattern/drm/H5DRM.cpp +++ b/SRC/domain/pattern/drm/H5DRM.cpp @@ -1078,17 +1078,11 @@ bool H5DRM::drm_differentiate_displacements(double t) bool nanfound = false; for (int i = 0; i < 3; ++i) { -<<<<<<< HEAD - if ( isnan(d1[i]) || - isnan(a1[i]) || - isnan(d2[i]) || - isnan(a2[i]) ) -======= + if ( isnan(d1[i]) || isnan(a1[i]) || isnan(d2[i]) || isnan(a2[i]) ) ->>>>>>> 732044f5b1846fa0047e4516e0717dc0d22bffc3 { nanfound = true; } @@ -1150,283 +1144,283 @@ bool H5DRM::drm_integrate_velocity(double next_integration_time) exit(-1); return false; - FILE * fptr = 0; - if (DEBUG_DRM_INTEGRATION) - { - char debugfilename[100]; - sprintf(debugfilename, "drmintegration.%d.txt", myrank); - fptr = fopen(debugfilename, "w"); - } - - - if (Nodes.Size() == 0) - return false; - - if (next_integration_time < tstart || next_integration_time > tend) - { - DRMDisplacements.Zero(); - DRMAccelerations.Zero(); - return false; - } - - int dir = 1; - double t1 = last_integration_time; - double t2 = next_integration_time; - if (t1 > t2) - { - // Integrating backwards - t1 = next_integration_time; - t2 = last_integration_time; - dir = -1; - } - hsize_t i1 = (hsize_t) (t1 - tstart) / dt; - hsize_t i2 = (hsize_t) (t2 - tstart) / dt + 1; - hsize_t Nt = i2 - i1; - - hsize_t motions_dims[2]; - id_velocity_dataspace = H5Dget_space(id_velocity); - - hsize_t imax_t = motions_dims[1] - 1; - - - i1 = i1 < 0 ? 0 : i1 ; - i1 = i1 > imax_t ? imax_t : i1; - i2 = i2 < 0 ? 0 : i2 ; - i2 = i2 > imax_t ? imax_t : i2; - Nt = i1 == i2 ? 1 : Nt; - - for (int n = 0; n < Nodes.Size(); ++n) - { - int nodeTag = Nodes(n); - int station_id = nodetag2station_id[nodeTag]; - int data_pos = station_id2data_pos[station_id]; - int local_pos = nodetag2local_pos[nodeTag]; - - double v[3][Nt]; - - hsize_t start[2] = {(hsize_t) data_pos , (hsize_t)i1}; - hsize_t stride[2] = {1 , 1}; - hsize_t count[2] = {1 , 1}; - hsize_t block[2] = {3 , (hsize_t) Nt}; - - //Selection in dataspace - H5Sselect_hyperslab( - id_velocity_dataspace, - H5S_SELECT_SET, start, stride, count, block ); - - //Selection in memspace - hsize_t rank_two_array = 2; - hsize_t one_node_data_dims[2] = {3, Nt}; - hsize_t one_node_data_maxdims[2] = {3, Nt}; - hid_t memspace = H5Screate_simple(rank_two_array, one_node_data_dims, one_node_data_maxdims); // create dataspace of memory - - - hsize_t mem_start[2] = {0 , 0}; - H5Sselect_hyperslab( - memspace, - H5S_SELECT_SET, mem_start, stride, count, block ); - - //Read data - herr_t errorflag = H5Dread( id_velocity, H5T_NATIVE_DOUBLE, memspace, - id_velocity_dataspace, id_xfer_plist, v ); - - H5Sclose(memspace); - - if (errorflag < 0) - { - H5DRMerror << "Failed to read velocity array!!\n" << - " n = " << n << endln << - " nodeTag = " << nodeTag << endln << - " station_id = " << station_id << endln << - " i1 = " << i1 << endln << - " data_pos = " << data_pos << endln << - " local_pos = " << local_pos << endln << - " Nt = " << Nt << endln << - " last_integration_time = " << last_integration_time << endln << - " start = [" << start[0] << ", " << start[1] << "]" << endln << - " mem_start = [" << mem_start[0] << ", " << mem_start[1] << "]" << endln << - " stride = [" << stride[0] << ", " << stride[1] << "]" << endln << - " count = [" << count[0] << ", " << count[1] << "]" << endln << - " block = [" << block[0] << ", " << block[1] << "]" << endln; - exit(-1); - } - - 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]; - } - - -<<<<<<< HEAD - 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 (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); - /* 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); - } - - } ->>>>>>> 732044f5b1846fa0047e4516e0717dc0d22bffc3 - - int eval_i = (int) (t2 - t1) / dt; - - - 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 + 2) = (v[2][eval_i] - v[2][eval_i + 1]) / dt; - - if (DEBUG_DRM_INTEGRATION) - { - 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, " 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) ); - - } - } - - - - last_integration_time = t2; - - return true; +// FILE * fptr = 0; +// if (DEBUG_DRM_INTEGRATION) +// { +// char debugfilename[100]; +// sprintf(debugfilename, "drmintegration.%d.txt", myrank); +// fptr = fopen(debugfilename, "w"); +// } + + +// if (Nodes.Size() == 0) +// return false; + +// if (next_integration_time < tstart || next_integration_time > tend) +// { +// DRMDisplacements.Zero(); +// DRMAccelerations.Zero(); +// return false; +// } + +// int dir = 1; +// double t1 = last_integration_time; +// double t2 = next_integration_time; +// if (t1 > t2) +// { +// // Integrating backwards +// t1 = next_integration_time; +// t2 = last_integration_time; +// dir = -1; +// } +// hsize_t i1 = (hsize_t) (t1 - tstart) / dt; +// hsize_t i2 = (hsize_t) (t2 - tstart) / dt + 1; +// hsize_t Nt = i2 - i1; + +// hsize_t motions_dims[2]; +// id_velocity_dataspace = H5Dget_space(id_velocity); + +// hsize_t imax_t = motions_dims[1] - 1; + + +// i1 = i1 < 0 ? 0 : i1 ; +// i1 = i1 > imax_t ? imax_t : i1; +// i2 = i2 < 0 ? 0 : i2 ; +// i2 = i2 > imax_t ? imax_t : i2; +// Nt = i1 == i2 ? 1 : Nt; + +// for (int n = 0; n < Nodes.Size(); ++n) +// { +// int nodeTag = Nodes(n); +// int station_id = nodetag2station_id[nodeTag]; +// int data_pos = station_id2data_pos[station_id]; +// int local_pos = nodetag2local_pos[nodeTag]; + +// double v[3][Nt]; + +// hsize_t start[2] = {(hsize_t) data_pos , (hsize_t)i1}; +// hsize_t stride[2] = {1 , 1}; +// hsize_t count[2] = {1 , 1}; +// hsize_t block[2] = {3 , (hsize_t) Nt}; + +// //Selection in dataspace +// H5Sselect_hyperslab( +// id_velocity_dataspace, +// H5S_SELECT_SET, start, stride, count, block ); + +// //Selection in memspace +// hsize_t rank_two_array = 2; +// hsize_t one_node_data_dims[2] = {3, Nt}; +// hsize_t one_node_data_maxdims[2] = {3, Nt}; +// hid_t memspace = H5Screate_simple(rank_two_array, one_node_data_dims, one_node_data_maxdims); // create dataspace of memory + + +// hsize_t mem_start[2] = {0 , 0}; +// H5Sselect_hyperslab( +// memspace, +// H5S_SELECT_SET, mem_start, stride, count, block ); + +// //Read data +// herr_t errorflag = H5Dread( id_velocity, H5T_NATIVE_DOUBLE, memspace, +// id_velocity_dataspace, id_xfer_plist, v ); + +// H5Sclose(memspace); + +// if (errorflag < 0) +// { +// H5DRMerror << "Failed to read velocity array!!\n" << +// " n = " << n << endln << +// " nodeTag = " << nodeTag << endln << +// " station_id = " << station_id << endln << +// " i1 = " << i1 << endln << +// " data_pos = " << data_pos << endln << +// " local_pos = " << local_pos << endln << +// " Nt = " << Nt << endln << +// " last_integration_time = " << last_integration_time << endln << +// " start = [" << start[0] << ", " << start[1] << "]" << endln << +// " mem_start = [" << mem_start[0] << ", " << mem_start[1] << "]" << endln << +// " stride = [" << stride[0] << ", " << stride[1] << "]" << endln << +// " count = [" << count[0] << ", " << count[1] << "]" << endln << +// " block = [" << block[0] << ", " << block[1] << "]" << endln; +// exit(-1); +// } + +// 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]; +// } + + +// <<<<<<< HEAD +// 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 (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); +// /* 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); +// } + +// } +// >>>>>>> 732044f5b1846fa0047e4516e0717dc0d22bffc3 + +// int eval_i = (int) (t2 - t1) / dt; + + +// 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 + 2) = (v[2][eval_i] - v[2][eval_i + 1]) / dt; + +// if (DEBUG_DRM_INTEGRATION) +// { +// 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, " 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) ); + +// } +// } + + + +// last_integration_time = t2; + +// return true; } diff --git a/SRC/domain/subdomain/ActorSubdomain.cpp b/SRC/domain/subdomain/ActorSubdomain.cpp index 69f594501..949117474 100644 --- a/SRC/domain/subdomain/ActorSubdomain.cpp +++ b/SRC/domain/subdomain/ActorSubdomain.cpp @@ -665,7 +665,9 @@ opserr << "ActorSubdomain::addSP_AXIS :: DONE\n"; case ShadowActorSubdomain_revertToStart: this->revertToStart(); this->sendID(msgData); - + #ifdef _PARALLEL_PROCESSING + this->barrierCheck(0); + #endif break; case ShadowActorSubdomain_addRecorder: diff --git a/SRC/domain/subdomain/ShadowSubdomain.cpp b/SRC/domain/subdomain/ShadowSubdomain.cpp index 860a6059a..1b7f97e42 100644 --- a/SRC/domain/subdomain/ShadowSubdomain.cpp +++ b/SRC/domain/subdomain/ShadowSubdomain.cpp @@ -1093,6 +1093,15 @@ ShadowSubdomain::revertToStart(void) { msgData(0) = ShadowActorSubdomain_revertToStart; this->sendID(msgData); + +#ifdef _PARALLEL_PROCESSING + // CYPE Software: revertToStart() invokes update on ActorSubdomain which asks for barrierCheck. + { + int res = this->barrierCheckIN(); + this->barrierCheckOUT(res); + } +#endif + if (this->recvID(msgData) != 0) { opserr << "ShadowSubdomain::revertToStart ERROR ERROR\n"; } diff --git a/SRC/element/CEqElement/ASDEmbeddedNodeElement.cpp b/SRC/element/CEqElement/ASDEmbeddedNodeElement.cpp new file mode 100644 index 000000000..4d963ccce --- /dev/null +++ b/SRC/element/CEqElement/ASDEmbeddedNodeElement.cpp @@ -0,0 +1,1132 @@ +/* ****************************************************************** ** +** 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: 2021/04/28 22:51:21 $ + +// Original implementation: Massimo Petracca (ASDEA) +// +// + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +// anonymous namespace for utilities +namespace +{ + + double det2(const Matrix& J) { + return J(0, 0) * J(1, 1) - J(0, 1) * J(1, 0); + } + + double det3(const Matrix& J) { + return J(0, 0) * J(1, 1) * J(2, 2) - J(0, 0) * J(1, 2) * J(2, 1) - J(0, 1) * J(1, 0) * J(2, 2) + + J(0, 1) * J(1, 2) * J(2, 0) + J(0, 2) * J(1, 0) * J(2, 1) - J(0, 2) * J(1, 1) * J(2, 0); + } + + void cross(const Vector& a, const Vector& b, Vector& c) { + c(0) = a(1) * b(2) - a(2) * b(1); + c(1) = a(2) * b(0) - a(0) * b(2); + c(2) = a(0) * b(1) - a(1) * b(0); + } + + namespace tri { + + double shapeFun(double x, double y, int i) { + if (i == 0) + return 1.0 - x - y; + else if (i == 1) + return x; + else if (i == 2) + return y; + return 0.0; + } + + void shapeFunDer(Matrix& dN) { + dN(0, 0) = -1.0; dN(0, 1) = -1.0; + dN(1, 0) = 1.0; dN(1, 1) = 0.0; + dN(2, 0) = 0.0; dN(2, 1) = 1.0; + } + + void globalCoord(const Matrix& X, double lx, double ly, double& gx, double& gy) { + gx = gy = 0.0; + for (int i = 0; i < 3; i++) { + double N = shapeFun(lx, ly, i); + gx += N * X(0, i); + gy += N * X(1, i); + } + } + + void globalCoord(const Matrix& X, double lx, double ly, double& gx, double& gy, double& gz) { + gx = gy = gz = 0.0; + for (int i = 0; i < 3; i++) { + double N = shapeFun(lx, ly, i); + gx += N * X(0, i); + gy += N * X(1, i); + gz += N * X(2, i); + } + } + + void localCoord(const Matrix& X, const Matrix& invJ, double gx, double gy, double& lx, double& ly) { + lx = ly = 0.0; + double px, py; + globalCoord(X, lx, ly, px, py); + Vector D(2); + Vector DL(2); + D(0) = gx - px; + D(1) = gy - py; + DL.addMatrixVector(0.0, invJ, D, 1.0); + lx = DL(0); + ly = DL(1); + } + + void localCoord(const Matrix& X, const Matrix& invJ, double gx, double gy, double gz, double& lx, double& ly) { + lx = ly = 0.0; + double px, py, pz; + globalCoord(X, lx, ly, px, py, pz); + Vector D(3); + Vector DL(3); + D(0) = gx - px; + D(1) = gy - py; + D(2) = gz - pz; + DL.addMatrixVector(0.0, invJ, D, 1.0); + lx = DL(0); + ly = DL(1); + } + + void fillVzInJacobian(Matrix& J) { + double nx = J(1, 0) * J(2, 1) - J(1, 1) * J(2, 0); + double ny = J(0, 1) * J(2, 0) - J(0, 0) * J(2, 1); + double nz = J(0, 0) * J(1, 1) - J(0, 1) * J(1, 0); + double norm = std::sqrt(nx * nx + ny * ny + nz * nz); + if (norm > std::numeric_limits::epsilon()) { + J(0, 2) = nx / norm; + J(1, 2) = ny / norm; + J(2, 2) = nz / norm; + } + } + + } + + namespace tet { + + double shapeFun(double x, double y, double z, int i) { + if (i == 0) + return 1.0 - (x + y + z); + else if (i == 1) + return x; + else if (i == 2) + return y; + else if (i == 3) + return z; + return 0.0; + } + + void shapeFunDer(Matrix& dN) { + dN(0, 0) = -1.0; dN(0, 1) = -1.0; dN(0, 2) = -1.0; + dN(1, 0) = 1.0; dN(1, 1) = 0.0; dN(1, 2) = 0.0; + dN(2, 0) = 0.0; dN(2, 1) = 1.0; dN(2, 2) = 0.0; + dN(3, 0) = 0.0; dN(3, 1) = 0.0; dN(3, 2) = 1.0; + } + + void globalCoord(const Matrix& X, double lx, double ly, double lz, double& gx, double& gy, double& gz) { + gx = gy = gz = 0.0; + for (int i = 0; i < 4; i++) { + double N = shapeFun(lx, ly, lz, i); + gx += N * X(0, i); + gy += N * X(1, i); + gz += N * X(2, i); + } + } + + void localCoord(const Matrix& X, const Matrix& invJ, double gx, double gy, double gz, double& lx, double& ly, double& lz) { + lx = ly = lz = 0.0; + double px, py, pz; + globalCoord(X, lx, ly, lz, px, py, pz); + Vector D(3); + Vector DL(3); + D(0) = gx - px; + D(1) = gy - py; + D(2) = gz - pz; + DL.addMatrixVector(0.0, invJ, D, 1.0); + lx = DL(0); + ly = DL(1); + lz = DL(2); + } + + } + +} + +void * +OPS_ASDEmbeddedNodeElement(void) +{ + static bool first_done = false; + if (!first_done) { + opserr << "Using ASDEmbeddedNodeElement - Developed by: Massimo Petracca, Guido Camata, ASDEA Software Technology\n"; + first_done = true; + } + + const char* descr = "Want: element ASDEmbeddedNodeElement $tag $Cnode $Rnode1 $Rnode2 $Rnode3 <$Rnode4> <-rot> <-K $K>\n"; + + int numArgs = OPS_GetNumRemainingInputArgs(); + if (numArgs < 5) { + opserr << "ASDEmbeddedNodeElement ERROR : Few arguments:\n" << descr; + return 0; + } + + // mandatory parameters + int iData[5]; + int numData = 5; + if (OPS_GetInt(&numData, iData) != 0) { + opserr << "ASDEmbeddedNodeElement ERROR: Invalid integer mandatory values: element ASDEmbeddedNodeElement wants at least 5 integer parameters\n" << descr; + return 0; + } + + // parse optional parameters + bool rot = false; + int N4 = 0; + bool has_N4 = false; + double K = 1.0e18; + for (int i = 5; i < numArgs; i++) { + const char* what = OPS_GetString(); + if (strcmp(what, "-rot") == 0) { + rot = true; + } + else if (strcmp(what, "-K") == 0) { + if (i == numArgs - 1) { + opserr << "ASDEmbeddedNodeElement ERROR: The -K keyword should be followed by a floating point number.\n" << descr; + return 0; + } + ++i; + numData = 1; + if (OPS_GetDouble(&numData, &K) != 0) { + opserr << "ASDEmbeddedNodeElement ERROR invalid floating point number for -K keyword.\n"; + return 0; + } + } + else { + // should be an integer for the only if i == 6 + if (i == 5) { + try { + N4 = std::stoi(std::string(what)); + has_N4 = true; + } + catch (...) { + N4 = -1; + has_N4 = false; + } + } + } + } + + // done + if (has_N4) + return new ASDEmbeddedNodeElement(iData[0], iData[1], iData[2], iData[3], iData[4], N4, rot, K); + else + return new ASDEmbeddedNodeElement(iData[0], iData[1], iData[2], iData[3], iData[4], rot, K); +} + +ASDEmbeddedNodeElement::ASDEmbeddedNodeElement() + : Element(0, ELE_TAG_ASDEmbeddedNodeElement) +{ +} + +ASDEmbeddedNodeElement::ASDEmbeddedNodeElement(int tag, int cNode, int rNode1, int rNode2, int rNode3, bool rot_flag, double K) + : Element(tag, ELE_TAG_ASDEmbeddedNodeElement) + , m_rot_c_flag(rot_flag) + , m_K(K) +{ + m_node_ids.resize(4); + m_node_ids(0) = cNode; + m_node_ids(1) = rNode1; + m_node_ids(2) = rNode2; + m_node_ids(3) = rNode3; + m_nodes.resize(4, nullptr); +} + +ASDEmbeddedNodeElement::ASDEmbeddedNodeElement(int tag, int cNode, int rNode1, int rNode2, int rNode3, int rNode4, bool rot_flag, double K) + : Element(tag, ELE_TAG_ASDEmbeddedNodeElement) + , m_rot_c_flag(rot_flag) + , m_K(K) +{ + m_node_ids.resize(5); + m_node_ids(0) = cNode; + m_node_ids(1) = rNode1; + m_node_ids(2) = rNode2; + m_node_ids(3) = rNode3; + m_node_ids(4) = rNode4; + m_nodes.resize(5, nullptr); +} + +ASDEmbeddedNodeElement::~ASDEmbeddedNodeElement( ) +{ +} + +const char* ASDEmbeddedNodeElement::getClassType(void) const +{ + return "ASDEmbeddedNodeElement"; +} + +void ASDEmbeddedNodeElement::setDomain(Domain* theDomain) +{ + // check nodes + m_num_dofs = 0; + int local_dof_counter = 0; + int local_pos = 0; + std::vector aux_mapping(m_nodes.size()); + for (std::size_t i = 0; i < m_nodes.size(); ++i) { + + // check node + int node_id = m_node_ids(static_cast(i)); + Node* node = theDomain->getNode(node_id); + if (node == nullptr) { + opserr << "ASDEmbeddedNodeElement Error in setDomain: node " << node_id << " does not exit in the domain\n"; + exit(-1); + } + + // store node + m_nodes[i] = node; + + // check NDM + int ndm = node->getCrds().Size(); + if (ndm != 2 && ndm != 3) { + opserr << "ASDEmbeddedNodeElement Error in setDomain: Nodes should have either 2 or 3 dimensions, not " << ndm << "\n"; + exit(-1); + } + if (i == 0) { + // save ndm at first node + m_ndm = ndm; + } + else { + if (m_ndm != ndm) { + opserr << "ASDEmbeddedNodeElement Error in setDomain: Nodes should have the same dimension (2 or 3)\n"; + exit(-1); + } + } + + // check NDF + int ndf = node->getNumberDOF(); + if (m_ndm == 2) { + if (ndf != 2 && ndf != 3) { + opserr << "ASDEmbeddedNodeElement Error in setDomain: In 2D only 2 or 3 DOFs are allowed, not " << ndf << "\n"; + exit(-1); + } + if (i == 0) { + m_rot_c = (m_rot_c_flag && ndf == 3); + } + } + else { + if (ndf != 3 && ndf != 4 && ndf != 6) { + opserr << "ASDEmbeddedNodeElement Error in setDomain: In 3D only 3, 4 or 6 DOFs are allowed, not " << ndf << "\n"; + exit(-1); + } + if (i == 0) { + m_rot_c = (m_rot_c_flag && ndf == 6); + } + } + + // set up mapping + ID& imap = aux_mapping[i]; + imap.resize(m_ndm + ((i == 0 && m_rot_c) ? (m_ndm == 2 ? 1 : 3) : 0)); + imap(0) = local_pos; // Ux + imap(1) = local_pos + 1; // Uy + if (m_ndm == 3) { + imap(2) = local_pos + 2; // Uz + if (i == 0 && m_rot_c) { + imap(3) = local_pos + 3; // Rx + imap(4) = local_pos + 4; // Rx + imap(5) = local_pos + 5; // Rx + } + } + else { + if (i == 0 && m_rot_c) { + imap(2) = local_pos + 2; // Rz + } + } + local_pos += ndf; + + // update total dof counter + m_num_dofs += ndf; + // update local dof counter + local_dof_counter += imap.Size(); + } + + // flatten mapping + m_mapping.resize(local_dof_counter); + local_pos = 0; + for (const ID& imap : aux_mapping) { + for (int i = 0; i < imap.Size(); ++i) { + m_mapping(local_pos++) = imap(i); + } + } + + // compute initial displacement vector + if (!m_U0_computed) { + m_U0.resize(m_num_dofs); + m_U0 = getGlobalDisplacements(); + m_U0_computed = true; + } + + // call base class implementation + DomainComponent::setDomain(theDomain); +} + +void ASDEmbeddedNodeElement::Print(OPS_Stream& s, int flag) +{ + if (flag == -1) { + int eleTag = this->getTag(); + s << "EL_ASDEmbeddedNodeElement\t" << eleTag << " :"; + for (int i = 0; i < m_node_ids.Size(); ++i) + s << "\t" << m_node_ids(i); + s << endln; + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << "\t\t\t{"; + s << "\"name\": " << this->getTag() << ", "; + s << "\"type\": \"ASDEmbeddedNodeElement\", "; + s << "\"nodes\": ["; + for (int i = 0; i < m_node_ids.Size(); ++i) { + if (i > 0) + s << ", "; + s << m_node_ids(i); + } + s << "]}"; + } +} + +int ASDEmbeddedNodeElement::getNumExternalNodes() const +{ + return m_node_ids.Size(); +} + +const ID& ASDEmbeddedNodeElement::getExternalNodes() +{ + return m_node_ids; +} + +Node** +ASDEmbeddedNodeElement::getNodePtrs(void) +{ + return m_nodes.data(); +} + +int ASDEmbeddedNodeElement::getNumDOF() +{ + return m_num_dofs; +} + +int ASDEmbeddedNodeElement::update() +{ + return 0; +} + +int ASDEmbeddedNodeElement::revertToLastCommit() +{ + return 0; +} + +const Matrix& ASDEmbeddedNodeElement::getTangentStiff() +{ + // compute stiffness matrix in reduced local dofset + auto compute_local = [this]() -> const Matrix& { + if (m_nodes.size() == 4) { + // support shape is a triangle ... + if (m_ndm == 2) { + // ... in 2D + if (m_rot_c) { + // ... with rotational dofs + return TRI_2D_UR(); + } + else { + // ... without rotational dofs + return TRI_2D_U(); + } + } + else { + // ... in 3D + if (m_rot_c) { + // ... with rotational dofs + return TRI_3D_UR(); + } + else { + // ... without rotational dofs + return TRI_3D_U(); + } + } + } + else { + // support shape is a tetrahedron ... + if (m_rot_c) { + // ... with rotational dofs + return TET_3D_UR(); + } + else { + // ... without rotational dofs + return TET_3D_U(); + } + } + }; + const Matrix& KL = compute_local(); + + // output matrix + static Matrix K; + K.resize(m_num_dofs, m_num_dofs); + K.Zero(); + + // copy in global dofset + for (int i = 0; i < KL.noRows(); ++i) { + int ig = m_mapping(i); + for (int j = 0; j < KL.noCols(); ++j) { + int jg = m_mapping(j); + K(ig, jg) = KL(i, j); + } + } + + // done + return K; +} + +const Matrix& ASDEmbeddedNodeElement::getInitialStiff() +{ + return getTangentStiff(); +} + +const Matrix& ASDEmbeddedNodeElement::getMass() +{ + static Matrix M; + M.resize(m_num_dofs, m_num_dofs); + M.Zero(); + return M; +} + +int +ASDEmbeddedNodeElement::addInertiaLoadToUnbalance(const Vector& accel) +{ + return 0; +} + +const Vector& ASDEmbeddedNodeElement::getResistingForce() +{ + static Vector F; + F.resize(m_num_dofs); + const Matrix& K = getTangentStiff(); + const Vector& U = getGlobalDisplacements(); + F.addMatrixVector(0.0, K, U, 1.0); + return F; +} + +const Vector& ASDEmbeddedNodeElement::getResistingForceIncInertia() +{ + return getResistingForce(); +} + +int ASDEmbeddedNodeElement::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(); + + // INT data + // tag + // number of nodes + // 5 nodal ids (the last one is 0 if number of nodes = 4) + // ndm + // num_dofs + // rot_c_flag + // rot_c + // U0_computed + // number of local dofs (at most 18) + // mapping of local dofs (if less then 18, the last ones will be set to 0) + static ID idData(31); + idData.Zero(); + idData(0) = getTag(); + idData(1) = m_node_ids.Size(); + idData(2) = m_node_ids(0); + idData(3) = m_node_ids(1); + idData(4) = m_node_ids(2); + idData(5) = m_node_ids(3); + if (m_node_ids.Size() == 5) + idData(6) = m_node_ids(4); + idData(7) = m_ndm; + idData(8) = m_num_dofs; + idData(9) = m_rot_c_flag ? 1 : 0; + idData(10) = m_rot_c ? 1 : 0; + idData(11) = m_U0_computed ? 1 : 0; + idData(12) = m_mapping.Size(); + for (int i = 0; i < m_mapping.Size(); ++i) + idData(12 + i) = m_mapping(i); + res += theChannel.sendID(dataTag, commitTag, idData); + if (res < 0) { + opserr << "WARNING ASDEmbeddedNodeElement::sendSelf() - " << this->getTag() << " failed to send ID\n"; + return res; + } + + // DOUBLE data + // K + // initial displacement (at most we can have 30 dofs) + static Vector vectData(31); + vectData.Zero(); + vectData(0) = m_K; + for (int i = 0; i < m_num_dofs; ++i) + vectData(1 + i) = m_U0(i); + res += theChannel.sendVector(dataTag, commitTag, vectData); + if (res < 0) { + opserr << "WARNING ASDEmbeddedNodeElement::sendSelf() - " << this->getTag() << " failed to send Vector\n"; + return res; + } + + // done + return res; +} + +int ASDEmbeddedNodeElement::recvSelf(int commitTag, Channel& theChannel, FEM_ObjectBroker& theBroker) +{ + int res = 0; + + int dataTag = this->getDbTag(); + + // INT data + // tag + // number of nodes + // 5 nodal ids (the last one is 0 if number of nodes = 4) + // ndm + // num_dofs + // rot_c_flag + // rot_c + // number of local dofs (at most 18) + // mapping of local dofs (if less then 18, the last ones will be set to 0) + static ID idData(31); + res += theChannel.recvID(dataTag, commitTag, idData); + if (res < 0) { + opserr << "WARNING ASDEmbeddedNodeElement::recvSelf() - " << this->getTag() << " failed to receive ID\n"; + return res; + } + + setTag(idData(0)); + int num_nodes = idData(1); + m_node_ids.resize(num_nodes); + m_nodes.resize(static_cast(num_nodes), nullptr); + m_node_ids(0) = idData(2); + m_node_ids(1) = idData(3); + m_node_ids(2) = idData(4); + m_node_ids(3) = idData(5); + if (m_node_ids.Size() == 5) + m_node_ids(4) = idData(6); + m_ndm = idData(7); + m_num_dofs = idData(8); + m_rot_c_flag = idData(9) == 1; + m_rot_c = idData(10) == 1; + m_U0_computed = idData(11) == 1; + int num_local_dofs = idData(12); + m_mapping.resize(num_local_dofs); + for (int i = 0; i < m_mapping.Size(); ++i) + m_mapping(i) = idData(12 + i); + + // DOUBLE data + // K + static Vector vectData(31); + res += theChannel.recvVector(dataTag, commitTag, vectData); + if (res < 0) { + opserr << "WARNING ASDEmbeddedNodeElement::sendSelf() - " << this->getTag() << " failed to receive Vector\n"; + return res; + } + m_K = vectData(0); + m_U0.resize(m_num_dofs); + for (int i = 0; i < m_num_dofs; ++i) + m_U0(i) = vectData(1 + i); + + // done + return res; +} + +const Vector& ASDEmbeddedNodeElement::getGlobalDisplacements() const +{ + static Vector U(m_num_dofs); + int counter = 0; + for (Node* node : m_nodes) { + const Vector& iu = node->getTrialDisp(); + for (int i = 0; i < iu.Size(); ++i) { + U(counter++) = iu(i); + } + } + if (m_U0_computed) { + U.addVector(1.0, m_U0, -1.0); + } + return U; +} + +const Matrix& ASDEmbeddedNodeElement::TRI_2D_U() +{ + // output + static Matrix K(8, 8); + + // collect triangle coordinates + static Matrix X(2, 3); + for (int i = 1; i < 4; i++) { + const Node* node = m_nodes[static_cast(i)]; + X(0, i-1) = node->getCrds()(0); + X(1, i-1) = node->getCrds()(1); + } + + // shape functions natural derivatives + static Matrix dN(3, 2); + tri::shapeFunDer(dN); + + // jacobian + static Matrix J(2, 2); + J.addMatrixProduct(0.0, X, dN, 1.0); + double detJ = det2(J); + double V = detJ / 2.0; + static Matrix invJ(2, 2); + J.Invert(invJ); + + // find local coordinates of constrained node + double lx, ly; + tri::localCoord(X, invJ, m_nodes[0]->getCrds()(0), m_nodes[0]->getCrds()(1), lx, ly); + + // compute shape functions at constrained node + static Vector N(3); + for(int i = 0; i < 3; ++i) + N(i) = tri::shapeFun(lx, ly, i); + + // compute B matrix + // UCx = sum(N*URx) -> sum(N*URx) - UCx = 0 + // UCy = sum(N*URy) -> sum(N*URy) - UCy = 0 + static Matrix B(2, 8); + B.Zero(); + for (int i = 0; i < 2; i++) + B(i, i) = -1.0; + for (int i = 0; i < 3; i++) { + int j = 2 + i * 2; + B(0, j) = N(i); + B(1, j + 1) = N(i); + } + + // Penalty stiffness + double iK = m_K * V; + + // compute stiffness + K.addMatrixTransposeProduct(0.0, B, B, iK); + + // done + return K; +} + +const Matrix& ASDEmbeddedNodeElement::TRI_2D_UR() +{ + // output + static Matrix K(9, 9); + + // collect triangle coordinates + static Matrix X(2, 3); + for (int i = 1; i < 4; i++) { + const Node* node = m_nodes[static_cast(i)]; + X(0, i - 1) = node->getCrds()(0); + X(1, i - 1) = node->getCrds()(1); + } + + // shape functions natural derivatives + static Matrix dN(3, 2); + tri::shapeFunDer(dN); + + // jacobian + static Matrix J(2, 2); + J.addMatrixProduct(0.0, X, dN, 1.0); + double detJ = det2(J); + double V = detJ / 2.0; + static Matrix invJ(2, 2); + J.Invert(invJ); + + // shape functions cartesian derivatives + static Matrix dNdX(3, 2); + dNdX.addMatrixProduct(0.0, dN, invJ, 1.0); + + // find local coordinates of constrained node + double lx, ly; + tri::localCoord(X, invJ, m_nodes[0]->getCrds()(0), m_nodes[0]->getCrds()(1), lx, ly); + + // compute shape functions at constrained node + static Vector N(3); + for (int i = 0; i < 3; ++i) + N(i) = tri::shapeFun(lx, ly, i); + + // compute B matrix + // UCx = sum(N*URx) -> sum(N*URx) - UCx = 0 + // UCy = sum(N*URy) -> sum(N*URy) - UCy = 0 + // RCz = sum(d_URy_dX - d_URx_dY)/2.0 -> sum(d_URy_dX - d_URx_dY)/2.0 - RCz = 0 + static Matrix B(3, 9); + B.Zero(); + for (int i = 0; i < 3; i++) + B(i, i) = -1.0; + for (int i = 0; i < 3; i++) { + int j = 3 + i * 2; + B(0, j) = N(i); + B(1, j + 1) = N(i); + B(2, j) = -dNdX(i, 1)/2.0; B(2, j + 1) = dNdX(i, 0)/2.0; + } + + // Penalty stiffness + double iK = m_K* V; + + // compute stiffness + K.addMatrixTransposeProduct(0.0, B, B, iK); + + // done + return K; +} + +const Matrix& ASDEmbeddedNodeElement::TRI_3D_U() +{ + // output + static Matrix K(12, 12); + + // collect triangle coordinates + static Matrix X(3, 3); + for (int i = 1; i < 4; i++) { + const Node* node = m_nodes[static_cast(i)]; + X(0, i - 1) = node->getCrds()(0); + X(1, i - 1) = node->getCrds()(1); + X(2, i - 1) = node->getCrds()(2); + } + + // shape functions natural derivatives + static Matrix dN(3, 3); + dN.Zero(); // note: the tri::shapeFunDer fills the first 2 columns, the 3rd should be zero! + tri::shapeFunDer(dN); + + // jacobian + static Matrix J(3, 3); + J.addMatrixProduct(0.0, X, dN, 1.0); + tri::fillVzInJacobian(J); // note: the 3rd column will be zero, so fill it with the unit normal vector + double detJ = det3(J); + double V = detJ / 2.0; + static Matrix invJ(3, 3); + J.Invert(invJ); + for (int i = 0; i < 3; ++i) invJ(i, 2) = 0.0; // note: the 3rd column in the inverse should be zero + + // find local coordinates of constrained node + double lx, ly; + tri::localCoord(X, invJ, m_nodes[0]->getCrds()(0), m_nodes[0]->getCrds()(1), m_nodes[0]->getCrds()(2), lx, ly); + + // compute shape functions at constrained node + static Vector N(3); + for (int i = 0; i < 3; ++i) + N(i) = tri::shapeFun(lx, ly, i); + + // compute B matrix + // UCx = sum(N*URx) -> sum(N*URx) - UCx = 0 + // UCy = sum(N*URy) -> sum(N*URy) - UCy = 0 + // UCz = sum(N*URz) -> sum(N*URz) - UCz = 0 + static Matrix B(3, 12); + B.Zero(); + for (int i = 0; i < 3; i++) + B(i, i) = -1.0; + for (int i = 0; i < 3; i++) { + int j = 3 + i * 3; + B(0, j) = N(i); + B(1, j + 1) = N(i); + B(2, j + 2) = N(i); + } + + // Penalty stiffness + double iK = m_K * V; + + // compute stiffness + K.addMatrixTransposeProduct(0.0, B, B, iK); + + // done + return K; +} + +const Matrix& ASDEmbeddedNodeElement::TRI_3D_UR() +{ + // output + static Matrix K(15, 15); + + // collect triangle coordinates + // in global coordinates + static Matrix X(3, 3); + for (int i = 1; i < 4; i++) { + const Node* node = m_nodes[static_cast(i)]; + X(0, i - 1) = node->getCrds()(0); + X(1, i - 1) = node->getCrds()(1); + X(2, i - 1) = node->getCrds()(2); + } + + // compute orientation + static Vector dx(3); + static Vector dy(3); + static Vector dz(3); + for (int i = 0; i < 3; ++i) { + dx(i) = X(i, 1) - X(i, 0); + dy(i) = X(i, 2) - X(i, 0); + } + dx.Normalize(); + dy.Normalize(); + cross(dx, dy, dz); + dz.Normalize(); + cross(dz, dx, dy); + + // assemble orientation matrix (transposed of rotation) + static Matrix R(3, 3); + for (int i = 0; i < 3; ++i) { + R(0, i) = dx(i); + R(1, i) = dy(i); + R(2, i) = dz(i); + } + + // triangle coordinates in local coordinates + static Matrix XL(2, 3); + for (int i = 0; i < 3; ++i) { + XL(0, i) = X(0, i) * dx(0) + X(1, i) * dx(1) + X(2, i) * dx(2); + XL(1, i) = X(0, i) * dy(0) + X(1, i) * dy(1) + X(2, i) * dy(2); + } + + // shape functions natural derivatives + static Matrix dN(3, 2); + tri::shapeFunDer(dN); + + // jacobian + static Matrix J(2, 2); + J.addMatrixProduct(0.0, XL, dN, 1.0); + double detJ = det2(J); + double V = detJ / 2.0; + static Matrix invJ(2, 2); + J.Invert(invJ); + + // shape functions cartesian derivatives + static Matrix dNdX(3, 2); + dNdX.addMatrixProduct(0.0, dN, invJ, 1.0); + + // find local coordinates of constrained node + const Vector CPos = m_nodes[0]->getCrds(); + double CPosX = CPos(0) * dx(0) + CPos(1) * dx(1) + CPos(2) * dx(2); + double CPosY = CPos(0) * dy(0) + CPos(1) * dy(1) + CPos(2) * dy(2); + double lx, ly; + tri::localCoord(XL, invJ, CPosX, CPosY, lx, ly); + + // compute shape functions at constrained node + static Vector N(3); + for (int i = 0; i < 3; ++i) + N(i) = tri::shapeFun(lx, ly, i); + + // compute B matrix (in local coordinates) + // UCx = sum(N*URx) -> sum(N*URx) - UCx = 0 + // UCy = sum(N*URy) -> sum(N*URy) - UCy = 0 + // UCz = sum(N*URz) -> sum(N*URz) - UCz = 0 + // RCx = sum( d_URz_dY) -> sum( d_URz_dY) - RCx = 0 (local) + // RCy = sum(-d_URz_dX) -> sum(-d_URz_dX) - RCy = 0 (local) + // RCz = sum(d_URy_dX - d_URx_dY)/2.0 -> sum(d_URy_dX - d_URx_dY)/2.0 - RCz = 0 (local) + static Matrix B(6, 15); + B.Zero(); + // fill the -identity 6x6 block (transformed to global coordinates) + // for constrained node+ + /*for (int i = 0; i < 6; ++i) + B(i, i) = -1.0;*/ + for (int i = 0; i < 2; ++i) { + int j = i * 3; + for (int row = 0; row < 3; ++row) + for (int col = 0; col < 3; ++col) + B(j + row, j + col) = -R(row, col); + } + // fill the 2 rows of 3 3x3 blocks (transformed to global coordinates) + static Matrix BL(3, 3); + static Matrix BG(3, 3); + for (int i = 0; i < 3; ++i) { + int j = 6 + i * 3; + // U block + BL.Zero(); + BL(0, 0) = N(i); + BL(1, 1) = N(i); + BL(2, 2) = N(i); + BG.addMatrixProduct(0.0, BL, R, 1.0); + for (int row = 0; row < 3; ++row) + for (int col = 0; col < 3; ++col) + B(row, j + col) = BG(row, col); + // R block + BL.Zero(); + BL(0, 2) = dNdX(i, 1); + BL(1, 2) = -dNdX(i, 0); + BL(2, 0) = -dNdX(i, 1) / 2.0; + BL(2, 1) = dNdX(i, 0) / 2.0; + BG.addMatrixProduct(0.0, BL, R, 1.0); + for (int row = 0; row < 3; ++row) + for (int col = 0; col < 3; ++col) + B(3 + row, j + col) = BG(row, col); + } + + // Penalty stiffness + double iK = m_K * V; + + // compute stiffness + K.addMatrixTransposeProduct(0.0, B, B, iK); + + // done + return K; +} + +const Matrix& ASDEmbeddedNodeElement::TET_3D_U() +{ + // output + static Matrix K(15, 15); + + // collect tetrahedron coordinates + static Matrix X(3, 4); + for (int i = 1; i < 5; i++) { + const Node* node = m_nodes[static_cast(i)]; + X(0, i - 1) = node->getCrds()(0); + X(1, i - 1) = node->getCrds()(1); + X(2, i - 1) = node->getCrds()(2); + } + + // shape functions natural derivatives + static Matrix dN(4, 3); + tet::shapeFunDer(dN); + + // jacobian + static Matrix J(3, 3); + J.addMatrixProduct(0.0, X, dN, 1.0); + double detJ = det3(J); + double V = detJ / 6.0; + static Matrix invJ(3, 3); + J.Invert(invJ); + + // find local coordinates of constrained node + double lx, ly, lz; + tet::localCoord(X, invJ, m_nodes[0]->getCrds()(0), m_nodes[0]->getCrds()(1), m_nodes[0]->getCrds()(2), lx, ly, lz); + + // compute shape functions at constrained node + static Vector N(4); + for (int i = 0; i < 4; ++i) + N(i) = tet::shapeFun(lx, ly, lz, i); + + // compute B matrix + // UCx = sum(N*URx) -> sum(N*URx) - UCx = 0 + // UCy = sum(N*URy) -> sum(N*URy) - UCy = 0 + // UCz = sum(N*URz) -> sum(N*URz) - UCz = 0 + static Matrix B(3, 15); + B.Zero(); + for (int i = 0; i < 3; i++) + B(i, i) = -1.0; + for (int i = 0; i < 4; i++) { + int j = 3 + i * 3; + B(0, j) = N(i); + B(1, j + 1) = N(i); + B(2, j + 2) = N(i); + } + + // Penalty stiffness + double iK = m_K * V; + + // compute stiffness + K.addMatrixTransposeProduct(0.0, B, B, iK); + + // done + return K; +} + +const Matrix& ASDEmbeddedNodeElement::TET_3D_UR() +{ + // output + static Matrix K(18, 18); + + // collect tetrahedron coordinates + static Matrix X(3, 4); + for (int i = 1; i < 5; i++) { + const Node* node = m_nodes[static_cast(i)]; + X(0, i - 1) = node->getCrds()(0); + X(1, i - 1) = node->getCrds()(1); + X(2, i - 1) = node->getCrds()(2); + } + + // shape functions natural derivatives + static Matrix dN(4, 3); + tet::shapeFunDer(dN); + + // jacobian + static Matrix J(3, 3); + J.addMatrixProduct(0.0, X, dN, 1.0); + double detJ = det3(J); + double V = detJ / 6.0; + static Matrix invJ(3, 3); + J.Invert(invJ); + + // shape functions cartesian derivatives + static Matrix dNdX(4, 3); + dNdX.addMatrixProduct(0.0, dN, invJ, 1.0); + + // find local coordinates of constrained node + double lx, ly, lz; + tet::localCoord(X, invJ, m_nodes[0]->getCrds()(0), m_nodes[0]->getCrds()(1), m_nodes[0]->getCrds()(2), lx, ly, lz); + + // compute shape functions at constrained node + static Vector N(4); + for (int i = 0; i < 4; ++i) + N(i) = tet::shapeFun(lx, ly, lz, i); + + // compute B matrix + // UCx = sum(N*URx) -> sum(N*URx) - UCx = 0 + // UCy = sum(N*URy) -> sum(N*URy) - UCy = 0 + // UCz = sum(N*URz) -> sum(N*URz) - UCz = 0 + // RCx = sum(d_URz_dY - d_URy_dZ)/2.0 -> sum(d_URz_dY - d_URy_dZ)/2.0 - RCx = 0 + // RCy = sum(d_URx_dZ - d_URz_dX)/2.0 -> sum(d_URx_dZ - d_URz_dX)/2.0 - RCy = 0 + // RCz = sum(d_URy_dX - d_URx_dY)/2.0 -> sum(d_URy_dX - d_URx_dY)/2.0 - RCz = 0 + static Matrix B(6, 18); + B.Zero(); + for (int i = 0; i < 6; i++) + B(i, i) = -1.0; + for (int i = 0; i < 4; i++) { + int j = 6 + i * 3; + B(0, j) = N(i); + B(1, j + 1) = N(i); + B(2, j + 2) = N(i); + B(3, j + 1) = -dNdX(i, 2) / 2.0; B(3, j + 2) = dNdX(i, 1) / 2.0; + B(4, j) = dNdX(i, 2) / 2.0; B(4, j + 2) = -dNdX(i, 0) / 2.0; + B(5, j) = -dNdX(i, 1) / 2.0; B(5, j + 1) = dNdX(i, 0) / 2.0; + } + + // Penalty stiffness + double iK = m_K * V; + + // compute stiffness + K.addMatrixTransposeProduct(0.0, B, B, iK); + + // done + return K; +} diff --git a/SRC/element/CEqElement/ASDEmbeddedNodeElement.h b/SRC/element/CEqElement/ASDEmbeddedNodeElement.h new file mode 100644 index 000000000..45ff1f0bc --- /dev/null +++ b/SRC/element/CEqElement/ASDEmbeddedNodeElement.h @@ -0,0 +1,122 @@ +/* ****************************************************************** ** +** 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: 2021/04/28 22:51:21 $ + +// Original implementation: Massimo Petracca (ASDEA) +// +// +// Notes: +// +// + +#ifndef ASDEmbeddedNodeElement_h +#define ASDEmbeddedNodeElement_h + +#include +#include +#include +#include +#include + +class ASDEmbeddedNodeElement : public Element +{ + +public: + + // life cycle + ASDEmbeddedNodeElement(); + ASDEmbeddedNodeElement(int tag, int cNode, int rNode1, int rNode2, int rNode3, bool rot_flag, double K); + ASDEmbeddedNodeElement(int tag, int cNode, int rNode1, int rNode2, int rNode3, int rNode4, bool rot_flag, double K); + virtual ~ASDEmbeddedNodeElement(); + + // domain + const char* getClassType(void) const; + 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 update(); + int revertToLastCommit(); + + // methods to return the current linearized stiffness, + // damping and mass matrices + const Matrix& getTangentStiff(); + const Matrix& getInitialStiff(); + const Matrix& getMass(); + + // methods for applying loads + 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); + +private: + const Vector& getGlobalDisplacements() const; + const Matrix& TRI_2D_U(); + const Matrix& TRI_2D_UR(); + const Matrix& TRI_3D_U(); + const Matrix& TRI_3D_UR(); + const Matrix& TET_3D_U(); + const Matrix& TET_3D_UR(); + +private: + + // the nodal ids, the first one is the constrained node, + // the other 3 (triangle in 2D or shell triangle in 3D) or 4 (tetrahedron in 3D) + // are the retained nodes + ID m_node_ids; + // the ndoes + std::vector m_nodes; + // store the number of dimensions (2 or 3 are allowed) + int m_ndm = 0; + // total number of dofs + int m_num_dofs = 0; + // user input to constrained, if necessary, the rotation of the constrained node + // if the constrained node has rotational DOFs + bool m_rot_c_flag = false; + // true if the constrained node has rotational DOFs and the user flag is true + bool m_rot_c = false; + // a vector containing the local id mapping for assembling + // into the element matrix and vectors + ID m_mapping; + // stiffness penalty value to impose the constraint + double m_K = 1.0e18; + // initial displacements + Vector m_U0; + bool m_U0_computed = false; + +}; + +#endif // ASDEmbeddedNodeElement_h diff --git a/SRC/element/CEqElement/Makefile b/SRC/element/CEqElement/Makefile new file mode 100644 index 000000000..091191f24 --- /dev/null +++ b/SRC/element/CEqElement/Makefile @@ -0,0 +1,18 @@ +include ../../../Makefile.def + +OBJS = ASDEmbeddedNodeElement.o + +all: $(OBJS) + +# Miscellaneous +tidy: + @$(RM) $(RMFLAGS) Makefile.bak *~ #*# core + +clean: tidy + @$(RM) $(RMFLAGS) $(OBJS) *.o + +spotless: clean + +wipe: spotless + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/SRC/element/Makefile b/SRC/element/Makefile index 1686df35c..0948ea50b 100644 --- a/SRC/element/Makefile +++ b/SRC/element/Makefile @@ -51,6 +51,8 @@ all: $(OBJS) @$(CD) $(FE)/element/absorbentBoundaries; $(MAKE); @$(CD) $(FE)/element/gradientInelasticBeamColumn; $(MAKE); @$(CD) $(FE)/element/RockingBC; $(MAKE); + @$(CD) $(FE)/element/masonry; $(MAKE); + @$(CD) $(FE)/element/CEqElement; $(MAKE); # Miscellaneous tidy: @@ -100,6 +102,8 @@ spotless: clean @$(CD) $(FE)/element/absorbentBoundaries; $(MAKE) wipe; @$(CD) $(FE)/element/gradientInelasticBeamColumn; $(MAKE) wipe; @$(CD) $(FE)/element/RockingBC; $(MAKE) wipe; + @$(CD) $(FE)/element/masonry; $(MAKE) wipe; + @$(CD) $(FE)/element/CEqElement; $(MAKE) wipe; wipe: spotless diff --git a/SRC/element/PFEMElement/BCell.cpp b/SRC/element/PFEMElement/BCell.cpp new file mode 100644 index 000000000..25989d62f --- /dev/null +++ b/SRC/element/PFEMElement/BCell.cpp @@ -0,0 +1,48 @@ +/* ****************************************************************** ** +** 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: Minjie Zhu +// +// + +#include "BCell.h" + +#include "BNode.h" + +BCell::BCell() : pts(), type(BACKGROUND_FLUID), bnodes(), bindices() {} + +void BCell::add(Particle* pt) { pts.push_back(pt); } + +void BCell::setType(BackgroundType t) { type = t; } + +BackgroundType BCell::getType() const { return type; } + +VParticle& BCell::getPts() { return pts; } + +std::vector& BCell::getNodes() { return bnodes; } + +std::vector& BCell::getIndices() { return bindices; } + +void BCell::addNode(BNode* bnode, const VInt& index) { + bnodes.push_back(bnode); + bindices.push_back(index); +} + +void BCell::clearParticles() { pts.clear(); } \ No newline at end of file diff --git a/SRC/element/PFEMElement/BCell.h b/SRC/element/PFEMElement/BCell.h new file mode 100644 index 000000000..61d900ff5 --- /dev/null +++ b/SRC/element/PFEMElement/BCell.h @@ -0,0 +1,55 @@ +/* ****************************************************************** ** +** 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: Minjie Zhu +// +// + +#ifndef BCell_h +#define BCell_h + +#include "BackgroundDef.h" + +class BNode; + +// BACKGROUND_FLUID - a grid fluid cell +// BACKGROUND_STRUCTURE - a structural cell, which should have no particles +class BCell { + private: + VParticle pts; + BackgroundType type; + std::vector bnodes; + std::vector bindices; + + public: + BCell(); + void add(Particle* pt); + void setType(BackgroundType t); + BackgroundType getType() const; + VParticle& getPts(); + std::vector& getNodes(); + std::vector& getIndices(); + + void addNode(BNode* bnode, const VInt& index); + + void clearParticles(); +}; + +#endif \ No newline at end of file diff --git a/SRC/element/PFEMElement/BNode.cpp b/SRC/element/PFEMElement/BNode.cpp new file mode 100644 index 000000000..89a90bc05 --- /dev/null +++ b/SRC/element/PFEMElement/BNode.cpp @@ -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) ** +** ** +** ****************************************************************** */ + +// Written: Minjie Zhu +// +// + +#include "BNode.h" + +BNode::BNode() + : tags(), crdsn(), vn(), dvn(), pn(), dpn(), type(BACKGROUND_FLUID) {} + +void BNode::addNode(int tag, const VDouble& crds, const VDouble& v, + const VDouble& dv, double p, double dp, + BackgroundType tp, int id) { + tags.push_back(tag); + crdsn.push_back(crds); + vn.push_back(v); + dvn.push_back(dv); + pn.push_back(p); + dpn.push_back(dp); + type = tp; + sid.push_back(id); +} + +void BNode::clear() { + tags.clear(); + crdsn.clear(); + vn.clear(); + dvn.clear(); + pn.clear(); + dpn.clear(); + type = BACKGROUND_FLUID; + sid.clear(); +} + +void BNode::setType(BackgroundType t) { type = t; } + +int BNode::size() const { return (int)tags.size(); } + +VInt& BNode::getTags() { return tags; } + +VVDouble& BNode::getCrds() { return crdsn; } + +VVDouble& BNode::getVel() { return vn; } + +VVDouble& BNode::getAccel() { return dvn; } + +VDouble& BNode::getPressure() { return pn; } + +VDouble& BNode::getPdot() { return dpn; } + +BackgroundType BNode::getType() { return type; } + +VInt& BNode::getSid() { return sid; } \ No newline at end of file diff --git a/SRC/element/PFEMElement/BNode.h b/SRC/element/PFEMElement/BNode.h new file mode 100644 index 000000000..b59646d09 --- /dev/null +++ b/SRC/element/PFEMElement/BNode.h @@ -0,0 +1,64 @@ +/* ****************************************************************** ** +** 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: Minjie Zhu +// +// + +#ifndef BNode_h +#define BNode_h + +#include "BackgroundDef.h" + +// BACKGROUND_FLUID - a grid fluid node +// BACKGROUND_STRUCTURE - a structural node +// BACKGROUND_FIXED - a fixed grid fluid node +class BNode { + private: + VInt tags; + VVDouble crdsn; + VVDouble vn; + VVDouble dvn; + VDouble pn; + VDouble dpn; + BackgroundType type; + VInt sid; // structure id, <0:fluid, >0:structure, =0:not in + // contact + + public: + BNode(); + void addNode(int tag, const VDouble& crds, const VDouble& v, + const VDouble& dv, double p, double dp, BackgroundType tp, + int id = -1); + void clear(); + void setType(BackgroundType t); + + int size() const; + VInt& getTags(); + VVDouble& getCrds(); + VVDouble& getVel(); + VVDouble& getAccel(); + VDouble& getPressure(); + VDouble& getPdot(); + BackgroundType getType(); + VInt& getSid(); +}; + +#endif \ No newline at end of file diff --git a/SRC/element/PFEMElement/BackgroundDef.cpp b/SRC/element/PFEMElement/BackgroundDef.cpp index 142cb10fd..30dbc377c 100644 --- a/SRC/element/PFEMElement/BackgroundDef.cpp +++ b/SRC/element/PFEMElement/BackgroundDef.cpp @@ -169,3 +169,33 @@ void crossVDouble(const VDouble& v1, const VDouble& v2, VDouble& res) res[2] = v1[0]*v2[1]-v1[1]*v2[0]; } } + +const VInt& operator+=(VInt& v1, const VInt& v2) { + if (v1.size() > v2.size()) return v1; + for (unsigned int i = 0; i < v1.size(); i++) { + v1[i] += v2[i]; + } + return v1; +} + +const VInt& operator-=(VInt& v1, const VInt& v2) { + if (v1.size() > v2.size()) return v1; + for (unsigned int i = 0; i < v1.size(); i++) { + v1[i] -= v2[i]; + } + return v1; +} + +const VInt& operator*=(VInt& v1, int val) { + for (unsigned int i = 0; i < v1.size(); i++) { + v1[i] *= val; + } + return v1; +} + +const VInt& operator/=(VInt& v1, int val) { + for (unsigned int i = 0; i < v1.size(); i++) { + v1[i] /= val; + } + return v1; +} diff --git a/SRC/element/PFEMElement/BackgroundDef.h b/SRC/element/PFEMElement/BackgroundDef.h index 4edd3f54f..69f5e06aa 100644 --- a/SRC/element/PFEMElement/BackgroundDef.h +++ b/SRC/element/PFEMElement/BackgroundDef.h @@ -57,8 +57,12 @@ const VDouble& operator+=(VDouble& v1, double val); const VDouble& operator-=(VDouble& v1, double val); const VDouble& operator*=(VDouble& v1, double val); const VDouble& operator/=(VDouble& v1, double val); +const VInt& operator+=(VInt& v1, const VInt& v2); +const VInt& operator-=(VInt& v1, const VInt& v2); const VInt& operator+=(VInt& v1, int val); const VInt& operator-=(VInt& v1, int val); +const VInt& operator*=(VInt& v1, int val); +const VInt& operator/=(VInt& v1, int val); std::ostream& operator<<(std::ostream& os, const VDouble& v); std::ostream& operator<<(std::ostream& os, const VInt& v); void toVDouble(const Vector& vec, VDouble& res); @@ -67,4 +71,10 @@ double normVDouble(const VDouble& v); double dotVDouble(const VDouble& v1, const VDouble& v2); void crossVDouble(const VDouble& v1, const VDouble& v2, VDouble& res); +enum BackgroundType { + BACKGROUND_FLUID, + BACKGROUND_STRUCTURE, + BACKGROUND_FIXED +}; + #endif diff --git a/SRC/element/PFEMElement/BackgroundMesh.cpp b/SRC/element/PFEMElement/BackgroundMesh.cpp index 0a43063bb..33741529d 100644 --- a/SRC/element/PFEMElement/BackgroundMesh.cpp +++ b/SRC/element/PFEMElement/BackgroundMesh.cpp @@ -28,62 +28,55 @@ // #include "BackgroundMesh.h" -#include "ParticleGroup.h" -#include "PFEMElement2DBubble.h" -#include "PFEMElement3DBubble.h" -#include "PFEMElement2Dmini.h" -#include "PFEMElement2DCompressible.h" + #include + #include + +#include "PFEMElement2DBubble.h" +#include "PFEMElement2DCompressible.h" +#include "PFEMElement2Dmini.h" +#include "PFEMElement3DBubble.h" +#include "ParticleGroup.h" #ifdef _LINUX #include #endif #ifdef _OPENMP #include #endif -#include +#include +#include +#include +#include #include #include -#include -#include +#include #include -#include +#include #include +#include #include -#include -#include -#include -#include -#include -#include -int BackgroundMesh::FLUID = 1; -int BackgroundMesh::STRUCTURE = 2; -int BackgroundMesh::FIXED = 3; +#include +#include +#include static BackgroundMesh bgmesh; -BackgroundMesh& OPS_getBgMesh() -{ - return bgmesh; -} +BackgroundMesh& OPS_getBgMesh() { return bgmesh; } // OPS_BgMesh -int OPS_BgMesh() -{ +int OPS_BgMesh() { int ndm = OPS_GetNDM(); // check input - if(OPS_GetNumRemainingInputArgs() < 2*ndm+1) { - opserr<<"WARNING: basicsize? lower? upper? <-tol tol? -meshtol tol? " - "-wave wavefilename? numl? locs? -numsub numsub? " - "-structure sid? ?numnodes? structuralNodes?" - "-contact kdoverAd? thk? mu? beta? Dc? alpha? E? rho?" - "-incrVel? -setVel? -freesurface? -fsiSquare? -fsiTri?" - "-pressureOnce? -pressureExact? -kernelClose? -kernelAll?" - "-boundReduceFactor factor? -allAssembly? -fastAssembly?" - "-inlet crds? vel? -inletNum nump?" - "-largeSize? level? lower? upper?>"; + if (OPS_GetNumRemainingInputArgs() < 2 * ndm + 1) { + opserr << "WARNING: basicsize? lower? upper? <-tol tol? " + "-wave wavefilename? numl? locs? -numsub numsub? " + "-dispon? " + "-structure sid? ?numnodes? structuralNodes? " + "-alphaS sid? alphaS?" + "-contact kdoverAd? thk? mu? beta? Dc? alpha? E? rho?>"; return -1; } @@ -116,11 +109,11 @@ int OPS_BgMesh() opserr << "WARNING: failed to get max\n"; return -1; } - bgmesh.setRange(lower,upper); + bgmesh.setRange(lower, upper); + bgmesh.setDispOn(false); // get tolerance - while (OPS_GetNumRemainingInputArgs()>0) { - + while (OPS_GetNumRemainingInputArgs() > 0) { const char* opt = OPS_GetString(); if (strcmp(opt, "-tol") == 0) { @@ -134,17 +127,6 @@ int OPS_BgMesh() return -1; } bgmesh.setTol(tol); - } else if (strcmp(opt, "-meshtol") == 0) { - if (OPS_GetNumRemainingInputArgs() < 1) { - opserr << "WARNING: need tol\n"; - return -1; - } - double tol; - if (OPS_GetDoubleInput(&num, &tol) < 0) { - opserr << "WARNING: failed to read mesh tolerance\n"; - return -1; - } - bgmesh.setMeshTol(tol); } else if (strcmp(opt, "-wave") == 0) { if (OPS_GetNumRemainingInputArgs() < 2) { @@ -153,7 +135,7 @@ int OPS_BgMesh() } const char* wavefilename = OPS_GetString(); - if(bgmesh.setFile(wavefilename) < 0) { + if (bgmesh.setFile(wavefilename) < 0) { return -1; } @@ -164,16 +146,17 @@ int OPS_BgMesh() return -1; } if (numl > 0) { - - num = numl*ndm; + num = numl * ndm; if (OPS_GetNumRemainingInputArgs() < num) { - opserr << "WARNING: insufficient number of locations\n"; + opserr + << "WARNING: insufficient number of locations\n"; return -1; } VDouble locs(num); if (OPS_GetDoubleInput(&num, &locs[0]) < 0) { - opserr << "WARNING: failed to read wave recording locations\n"; + opserr << "WARNING: failed to read wave recording " + "locations\n"; return -1; } bgmesh.setLocs(locs); @@ -209,7 +192,8 @@ int OPS_BgMesh() return -1; } if (OPS_GetNumRemainingInputArgs() < numnodes) { - opserr << "WARNING: insufficient number of structural nodes\n"; + opserr << "WARNING: insufficient number of structural " + "nodes\n"; return -1; } if (numnodes > 0) { @@ -221,107 +205,50 @@ int OPS_BgMesh() bgmesh.addStructuralNodes(snodes, sid); } - } else if (strcmp(opt, "-freesurface") == 0) { - bgmesh.setFreeSurface(); } else if (strcmp(opt, "-contact") == 0) { if (OPS_GetNumRemainingInputArgs() < 8) { - opserr << "WARNING: need kdoverAd, thk, mu, beta, Dc, alpha, E, rho\n"; + opserr << "WARNING: need kdoverAd, thk, mu, beta, Dc, " + "alpha, E, rho\n"; return -1; } num = 8; VDouble data(num); if (OPS_GetDoubleInput(&num, &data[0]) < 0) { - opserr << "WARNING: failed to get kdoverAd, thk, mu, beta, Dc, alpha, E, rho\n"; - return -1; - } bgmesh.setContactData(data); - } else if (strcmp(opt, "-incrVel") == 0) { - bgmesh.setIncrVel(true); - } else if (strcmp(opt, "-setVel") == 0) { - bgmesh.setIncrVel(false); - } else if (strcmp(opt, "-fsiSquare") == 0) { - bgmesh.setFSITri(false); - } else if (strcmp(opt, "-fsiTri") == 0) { - bgmesh.setFSITri(true); - } else if (strcmp(opt, "-pressureOnce") == 0) { - bgmesh.setPressureOnce(true); - } else if (strcmp(opt, "-pressureExact") == 0) { - bgmesh.setPressureOnce(false); - } else if (strcmp(opt, "-boundReduceFactor") == 0) { - - if (OPS_GetNumRemainingInputArgs() < 1) { - opserr << "WARNING: need factor\n"; - return -1; - } - num = 1; - double factor = 0.5; - if (OPS_GetDoubleInput(&num, &factor) < 0) { - opserr << "WARNING: failed to get factor\n"; - return -1; - } - - bgmesh.setBoundReduceFactor(factor); - } else if (strcmp(opt, "-largeSize") == 0) { - int numbasic = 2; - num = 1; - if (OPS_GetIntInput(&num, &numbasic) < 0) { - opserr << "WARNING: failed to get num of basic size\n"; + opserr << "WARNING: failed to get kdoverAd, thk, mu, " + "beta, Dc, alpha, E, rho\n"; return -1; } - if (numbasic < 2) numbasic = 2; + bgmesh.setContactData(data); - VDouble range_low(ndm); - if (OPS_GetDoubleInput(&ndm, &range_low[0]) < 0) { - opserr << "WARNING: failed to get lower\n"; + } else if (strcmp(opt, "-alphaS") == 0) { + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "WARNING: need sid alphaS\n"; return -1; } - - VDouble range_up(ndm); - if (OPS_GetDoubleInput(&ndm, &range_up[0]) < 0) { - opserr << "WARNING: failed to get upper\n"; + num = 1; + int sid; + if (OPS_GetIntInput(&num, &sid) < 0) { + opserr << "WARNING: failed to get sid\n"; return -1; } - bgmesh.addLargeSize(numbasic, range_low, range_up); - } else if (strcmp(opt, "-allAssembly") == 0) { - bgmesh.setFastAssembly(false); - } else if (strcmp(opt, "-fastAssembly") == 0) { - bgmesh.setFastAssembly(true); - } else if (strcmp(opt, "-kernelClose") == 0) { - bgmesh.setKernelClose(true); - } else if (strcmp(opt, "-kernelAll") == 0) { - bgmesh.setKernelClose(false); - } else if (strcmp(opt, "-inlet") == 0) { - VDouble crds(ndm), vel(ndm); - if (OPS_GetNumRemainingInputArgs() < 2 * ndm) { - opserr << "WARNING: need crds and vel\n"; - return -1; - } - if (OPS_GetDoubleInput(&ndm, &crds[0]) < 0) { - opserr << "WARNING: failed to get inlet coordinates\n"; + double alpha = 0.0; + if (OPS_GetDoubleInput(&num, &alpha) < 0) { + opserr << "WARNING: failed to get alphaS\n"; return -1; } - if (OPS_GetDoubleInput(&ndm, &crds[0]) < 0) { - opserr << "WARNING: failed to get inlet velocity\n"; - return -1; + if (alpha <= 0) { + alpha = 0.0; + } else if (alpha > 1) { + alpha = 1.0; } - bgmesh.addInlet(crds, vel); - } else if (strcmp(opt, "-inletNum") == 0) { + bgmesh.setAlphaS(sid, alpha); - VInt nump(ndm); - if (OPS_GetIntInput(&ndm, &nump[0]) < 0) { - opserr << "WARNING: failed to get inlet number of particles\n"; - return -1; - } - bgmesh.setInletNum(nump); + } else if (strcmp(opt, "-dispOn") == 0) { + bgmesh.setDispOn(true); } } - // turn off disp on in PFEM elements - PFEMElement2DBubble::dispon = bgmesh.isDispOn(); - PFEMElement3DBubble::dispon = bgmesh.isDispOn(); - PFEMElement2DCompressible::dispon = bgmesh.isDispOn(); - PFEMElement2Dmini::dispon = bgmesh.isDispOn(); - // bg mesh if (bgmesh.remesh(true) < 0) { opserr << "WARNING: failed to create background mesh\n"; @@ -332,22 +259,26 @@ int OPS_BgMesh() } BackgroundMesh::BackgroundMesh() - :lower(), upper(), bcells(), bnodes(), - tol(1e-10), meshtol(0.1), bsize(-1.0), - numave(2), numsub(4), recorders(),locs(), - currentTime(0.0), theFile(), - structuralNodes(), - freesurface(false), contactData(8), - contactEles(), incrVel(false), fsiTri(false), - boundReduceFactor(0.5), inletLoc(), inletVel(), inletNum(), - largesize(), pressureonce(false), dispon(true), - fastAssembly(true), kernelClose(false) -{ -} - -BackgroundMesh::~BackgroundMesh() -{ - for (int i=0; i<(int)recorders.size(); ++i) { + : lower(), + upper(), + bcells(), + bnodes(), + tol(1e-10), + bsize(-1.0), + numave(2), + numsub(4), + recorders(), + locs(), + currentTime(0.0), + theFile(), + structuralNodes(), + contactData(8), + contactEles(), + dispon(true), + alphaS() {} + +BackgroundMesh::~BackgroundMesh() { + for (int i = 0; i < (int)recorders.size(); ++i) { if (recorders[i] != 0) { delete recorders[i]; } @@ -355,9 +286,7 @@ BackgroundMesh::~BackgroundMesh() recorders.clear(); } -void -BackgroundMesh::addRecorder(Recorder* recorder) -{ +void BackgroundMesh::addRecorder(Recorder* recorder) { Domain* domain = OPS_GetDomain(); if (domain == 0) return; @@ -365,19 +294,15 @@ BackgroundMesh::addRecorder(Recorder* recorder) recorders.push_back(recorder); } -void -BackgroundMesh::setRange(const VDouble& l, const VDouble& u) -{ - nearIndex(l,lower); - nearIndex(u,upper); +void BackgroundMesh::setRange(const VDouble& l, const VDouble& u) { + nearIndex(l, lower); + nearIndex(u, upper); } -int -BackgroundMesh::setFile(const char* name) -{ - theFile.open(name, std::ios::trunc|std::ios::out); - if(theFile.fail()) { - opserr<<"WARNING: Failed to open file "<=up[j]) { - find = false; - break; - } - } - - if (find) { - level = largesize[i][0]; - break; - } - } - - if (level > 1) { - for (int j = 0; j < ndm; ++j) { - index[j] /= level; - index[j] *= level; - } +void BackgroundMesh::addStructuralNodes(VInt& snodes, int sid) { + VInt& curr = structuralNodes[sid]; + for (int i = 0; i < (int)snodes.size(); ++i) { + curr.push_back(snodes[i]); } - - return level; } -void -BackgroundMesh::getIndex(const VDouble& crds, double incr, VInt& index) const -{ +void BackgroundMesh::getIndex(const VDouble& crds, double incr, + VInt& index) const { index.resize(crds.size()); - for (int i=0; i<(int)crds.size(); ++i) { - double crd = crds[i]/bsize + incr; + for (int i = 0; i < (int)crds.size(); ++i) { + double crd = crds[i] / bsize + incr; index[i] = (int)floor(crd); } } -void -BackgroundMesh::lowerIndex(const VDouble& crds, VInt& index) const -{ - getIndex(crds,0.0,index); +void BackgroundMesh::lowerIndex(const VDouble& crds, VInt& index) const { + getIndex(crds, 0.0, index); } -void -BackgroundMesh::upperIndex(const VDouble& crds, VInt& index) const -{ - getIndex(crds,1.0,index); +void BackgroundMesh::upperIndex(const VDouble& crds, VInt& index) const { + getIndex(crds, 1.0, index); } -void -BackgroundMesh::nearIndex(const VDouble& crds, VInt& index) const -{ - getIndex(crds,0.5,index); +void BackgroundMesh::nearIndex(const VDouble& crds, VInt& index) const { + getIndex(crds, 0.5, index); } -void -BackgroundMesh::getCrds(const VInt& index, VDouble& crds) const -{ +void BackgroundMesh::getCrds(const VInt& index, VDouble& crds) const { crds.resize(index.size(), 0.0); - for (int i=0; i<(int)crds.size(); ++i) { - crds[i] = index[i]*bsize; + for (int i = 0; i < (int)crds.size(); ++i) { + crds[i] = index[i] * bsize; } } @@ -521,17 +364,15 @@ BackgroundMesh::getCrds(const VInt& index, VDouble& crds) const // | | // ----- // 0 1 -void -BackgroundMesh::getCorners(const VInt& index, int num, int level, VVInt& indices) const -{ +void BackgroundMesh::getCorners(const VInt& index, int num, + VVInt& indices) const { int ndm = OPS_GetNDM(); int counter = 0; - int tnum = num * level; if (ndm == 2) { - indices.resize((num+1)*(num+1)); - for (int j=index[1]; j<=index[1]+tnum; j+=level) { - for (int i=index[0]; i<=index[0]+tnum; i+=level) { + indices.resize((num + 1) * (num + 1)); + for (int j = index[1]; j <= index[1] + num; j += 1) { + for (int i = index[0]; i <= index[0] + num; i += 1) { indices[counter].resize(ndm); indices[counter][0] = i; indices[counter][1] = j; @@ -539,10 +380,10 @@ BackgroundMesh::getCorners(const VInt& index, int num, int level, VVInt& indices } } } else if (ndm == 3) { - indices.resize((num+1)*(num+1)*(num+1)); - for (int k=index[2]; k<=index[2]+tnum; k+=level) { - for (int j=index[1]; j<=index[1]+tnum; j+=level) { - for (int i=index[0]; i<=index[0]+tnum; i+=level) { + indices.resize((num + 1) * (num + 1) * (num + 1)); + for (int k = index[2]; k <= index[2] + num; k += 1) { + for (int j = index[1]; j <= index[1] + num; j += 1) { + for (int i = index[0]; i <= index[0] + num; i += 1) { indices[counter].resize(ndm); indices[counter][0] = i; indices[counter][1] = j; @@ -552,43 +393,49 @@ BackgroundMesh::getCorners(const VInt& index, int num, int level, VVInt& indices } } } - } // gather particles from minind to maxind (not included) // if checkfsi = true, skip fluid cells -void -BackgroundMesh::gatherParticles(const VInt& minind, const VInt& maxind, - VParticle& pts, bool checkfsi) -{ +void BackgroundMesh::gatherParticles(const VInt& minind, + const VInt& maxind, VParticle& pts, + bool checkfsi) { int ndm = OPS_GetNDM(); pts.clear(); VInt index(ndm); if (ndm == 2) { - for (int i=minind[0]; i::iterator it = bcells.find(index); + std::map::iterator it = bcells.find(index); if (it != bcells.end()) { BCell& cell = it->second; - if (checkfsi && cell.type==FLUID) continue; - pts.insert(pts.end(), cell.pts.begin(), cell.pts.end()); + if (checkfsi && cell.getType() == BACKGROUND_FLUID) { + continue; + } + pts.insert(pts.end(), cell.getPts().begin(), + cell.getPts().end()); } } } } else if (ndm == 3) { - for (int i=minind[0]; i::iterator it = bcells.find(index); + std::map::iterator it = + bcells.find(index); if (it != bcells.end()) { BCell& cell = it->second; - if (checkfsi && cell.type==FLUID) continue; - pts.insert(pts.end(), cell.pts.begin(), cell.pts.end()); + if (checkfsi && + cell.getType() == BACKGROUND_FLUID) { + continue; + } + pts.insert(pts.end(), cell.getPts().begin(), + cell.getPts().end()); } } } @@ -596,59 +443,53 @@ BackgroundMesh::gatherParticles(const VInt& minind, const VInt& maxind, } } -double -BackgroundMesh::QuinticKernel(double q, double h, int ndm) -{ +double BackgroundMesh::QuinticKernel(double q, double h, int ndm) { static double pi = 3.141592653589793; - if (q<0 || q>2) return 0.0; + if (q < 0 || q > 2) return 0.0; double aD = 0.0; if (ndm == 2) { - aD = 7.0/(4*pi*h*h); + aD = 7.0 / (4 * pi * h * h); } else if (ndm == 3) { - aD = 7.0/(8*pi*h*h*h); + aD = 7.0 / (8 * pi * h * h * h); } - double a = 1.0-q/2.0; + double a = 1.0 - q / 2.0; - return aD*a*a*a*a*(2*q+1); + return aD * a * a * a * a * (2 * q + 1); } -int -BackgroundMesh::preNForTri(double x1, double y1, double x2, double y2, - double x3, double y3, VDouble& coeff) -{ - coeff.resize(9,0.0); +int BackgroundMesh::preNForTri(double x1, double y1, double x2, double y2, + double x3, double y3, VDouble& coeff) { + coeff.resize(9, 0.0); - coeff[0] = x2*y3-x3*y2; - coeff[1] = x3*y1-x1*y3; - coeff[2] = x1*y2-x2*y1; + coeff[0] = x2 * y3 - x3 * y2; + coeff[1] = x3 * y1 - x1 * y3; + coeff[2] = x1 * y2 - x2 * y1; - coeff[3] = y2-y3; - coeff[4] = y3-y1; - coeff[5] = y1-y2; + coeff[3] = y2 - y3; + coeff[4] = y3 - y1; + coeff[5] = y1 - y2; - coeff[6] = x3-x2; - coeff[7] = x1-x3; - coeff[8] = x2-x1; + coeff[6] = x3 - x2; + coeff[7] = x1 - x3; + coeff[8] = x2 - x1; - double A = coeff[0]+coeff[1]+coeff[2]; + double A = coeff[0] + coeff[1] + coeff[2]; - if (A<0 || fabs(A) < 1e-15) { - //opserr << "A <= 0\n"; + if (A < 0 || fabs(A) < 1e-15) { + // opserr << "A <= 0\n"; return -1; } - for (int i=0; i<(int)coeff.size(); ++i) { + for (int i = 0; i < (int)coeff.size(); ++i) { coeff[i] /= A; } return 0; } -int -BackgroundMesh::preNForTet(const VDouble& crds1, const VDouble& crds2, - const VDouble& crds3, const VDouble& crds4, - VVDouble& coeff) -{ +int BackgroundMesh::preNForTet(const VDouble& crds1, const VDouble& crds2, + const VDouble& crds3, const VDouble& crds4, + VVDouble& coeff) { int ndm = OPS_GetNDM(); if (ndm != 3) { return 0; @@ -665,34 +506,37 @@ BackgroundMesh::preNForTet(const VDouble& crds1, const VDouble& crds2, if ((int)crds4.size() < ndm) { return 0; } - Matrix Jmat(4,4), Jfact(4,4); - Jmat(0,0) = 1.0; Jmat(0,1) = 1.0; Jmat(0,2) = 1.0; Jmat(0,3) = 1.0; - for (int j=0; jclearEles(); } - } -void -BackgroundMesh::clearGrid() -{ +void BackgroundMesh::clearGrid() { Domain* domain = OPS_GetDomain(); if (domain == 0) return; // remove cells - for (std::map::iterator it=bnodes.begin(); it!=bnodes.end(); ++it) { + for (std::map::iterator it = bnodes.begin(); + it != bnodes.end(); ++it) { BNode& bnode = it->second; - const VInt& tags = bnode.tags; - int type = bnode.type; + const VInt& tags = bnode.getTags(); + int type = bnode.getType(); - for (int i=0; i<(int)tags.size(); ++i) { - if (type == FLUID) { + for (int i = 0; i < (int)tags.size(); ++i) { + if (type == BACKGROUND_FLUID) { // remove node Node* nd = domain->removeNode(tags[i]); if (nd != 0) { @@ -883,7 +703,8 @@ BackgroundMesh::clearGrid() } // remove pc - Pressure_Constraint* pc = domain->removePressure_Constraint(tags[i]); + Pressure_Constraint* pc = + domain->removePressure_Constraint(tags[i]); if (pc != 0) { delete pc; } @@ -895,13 +716,10 @@ BackgroundMesh::clearGrid() bcells.clear(); } -bool -BackgroundMesh::inEle(const VDouble& N) -{ +bool BackgroundMesh::inEle(const VDouble& N) { // out - for (int j=0; j<(int)N.size(); ++j) { - - if (N[j]<0) { + for (int j = 0; j < (int)N.size(); ++j) { + if (N[j] < 0) { // j+1 return false; } @@ -910,16 +728,15 @@ BackgroundMesh::inEle(const VDouble& N) return true; } -int -BackgroundMesh::solveLine(const VDouble& p1, const VDouble& dir, - int dim, double crd, double& k) -{ +int BackgroundMesh::solveLine(const VDouble& p1, const VDouble& dir, + int dim, double crd, double& k) { // check - if (p1.size()!=dir.size()) { - opserr << "WARNING: sizes are not compatible -- BgMesh::solveLine\n"; + if (p1.size() != dir.size()) { + opserr + << "WARNING: sizes are not compatible -- BgMesh::solveLine\n"; return -1; } - if (dim<0 || dim>=(int)dir.size()) { + if (dim < 0 || dim >= (int)dir.size()) { opserr << "WARNING: dim is out of range -- BgMesh::solveLine\n"; return -1; } @@ -928,18 +745,17 @@ BackgroundMesh::solveLine(const VDouble& p1, const VDouble& dir, if (dir[dim] == 0.0) { k = -1.0; } else { - k = (crd-p1[dim])/dir[dim]; + k = (crd - p1[dim]) / dir[dim]; } return 0; } -int -BackgroundMesh::remesh(bool init) -{ +int BackgroundMesh::remesh(bool init) { // clear and check if (bsize <= 0.0) { - opserr << "WARNING: basic mesh size has not been set -- BgMesh::addParticles\n"; + opserr << "WARNING: basic mesh size has not been set -- " + "BgMesh::addParticles\n"; return -1; } @@ -971,7 +787,7 @@ BackgroundMesh::remesh(bool init) #ifdef _LINUX timer.pause(); - opserr<<"time for add structure = "< allnodes; - for (std::map::iterator it=structuralNodes.begin(); - it!=structuralNodes.end(); ++it) { - + for (std::map::iterator it = structuralNodes.begin(); + it != structuralNodes.end(); ++it) { int sid = it->first; const VInt& snodes = it->second; - for (int k = 0; k < (int) snodes.size(); ++k) { - + for (int k = 0; k < (int)snodes.size(); ++k) { // check if already there - std::pair::iterator,bool> res= - allnodes.insert(snodes[k]); + std::pair::iterator, bool> res = + allnodes.insert(snodes[k]); if (res.second == false) { continue; } // get node - Node *nd = domain->getNode(snodes[k]); + Node* nd = domain->getNode(snodes[k]); if (nd == 0) continue; // nodal data - const Vector &crds = nd->getCrds(); - const Vector &disp = nd->getTrialDisp(); - const Vector &vel = nd->getTrialVel(); - const Vector &accel = nd->getTrialAccel(); + const Vector& crds = nd->getCrds(); + const Vector& disp = nd->getTrialDisp(); + const Vector& vel = nd->getTrialVel(); + const Vector& accel = nd->getTrialAccel(); if (crds.Size() != ndm || disp.Size() < ndm) { continue; } // create pressure constraint - Pressure_Constraint *pc = domain->getPressure_Constraint(nd->getTag()); + Pressure_Constraint* pc = + domain->getPressure_Constraint(nd->getTag()); if (pc != 0) { pc->setDomain(domain); } else { - // create pressure node - Node *pnode = 0; + Node* pnode = 0; if (ndm == 2) { pnode = new Node(ndtag++, 1, crds[0], crds[1]); } else if (ndm == 3) { - pnode = new Node(ndtag++, 1, crds[0], crds[1], crds[2]); + pnode = + new Node(ndtag++, 1, crds[0], crds[1], crds[2]); } if (pnode == 0) { - opserr << "WARNING: run out of memory -- BgMesh::gridNodes\n"; + opserr << "WARNING: run out of memory -- " + "BgMesh::gridNodes\n"; return -1; } if (domain->addNode(pnode) == false) { - opserr << "WARNING: failed to add node to domain -- BgMesh::gridNodes\n"; + opserr << "WARNING: failed to add node to domain -- " + "BgMesh::gridNodes\n"; delete pnode; return -1; } - pc = new Pressure_Constraint(nd->getTag(), pnode->getTag()); + pc = + new Pressure_Constraint(nd->getTag(), pnode->getTag()); if (pc == 0) { - opserr << "WARNING: no enough memory for Pressure_Constraint\n"; + opserr << "WARNING: no enough memory for " + "Pressure_Constraint\n"; return -1; } if (domain->addPressure_Constraint(pc) == false) { - opserr << "WARNING: failed to add PC to domain -- BgMesh::gridNodes\n"; + opserr << "WARNING: failed to add PC to domain -- " + "BgMesh::gridNodes\n"; delete pc; return -1; } @@ -1165,41 +968,39 @@ BackgroundMesh::addStructure() nearIndex(crdsn, index); // add structural node to the bnode - BNode &bnode = bnodes[index]; - bnode.addNode(nd->getTag(), crdsn, vn, dvn, pressure, pdot, STRUCTURE, sid); + BNode& bnode = bnodes[index]; + bnode.addNode(nd->getTag(), crdsn, vn, dvn, pressure, pdot, + BACKGROUND_STRUCTURE, sid); // set fixed bnodes VInt ind = index; ind -= 1; VVInt indices; - getCorners(ind, 2, 1, indices); - for (int i = 0; i < (int) indices.size(); ++i) { - BNode &bnd = bnodes[indices[i]]; + getCorners(ind, 2, indices); + for (int i = 0; i < (int)indices.size(); ++i) { + BNode& bnd = bnodes[indices[i]]; if (bnd.size() == 0) { - bnd.type = FIXED; + bnd.setType(BACKGROUND_FIXED); } } // set STRUCTURE cells - getCorners(ind, 1, 1, indices); - for (int i = 0; i < (int) indices.size(); ++i) { - BCell &bcell = bcells[indices[i]]; - bcell.type = STRUCTURE; + getCorners(ind, 1, indices); + for (int i = 0; i < (int)indices.size(); ++i) { + BCell& bcell = bcells[indices[i]]; + bcell.setType(BACKGROUND_STRUCTURE); // set corners - if (bcell.bnodes.empty()) { - + if (bcell.getNodes().empty()) { VVInt corners; - getCorners(indices[i], 1, 1, corners); + getCorners(indices[i], 1, corners); - for (int j = 0; j < (int) corners.size(); ++j) { - BNode &bnd = bnodes[corners[j]]; - bcell.bnodes.push_back(&bnd); - bcell.bindex.push_back(corners[j]); + for (int j = 0; j < (int)corners.size(); ++j) { + BNode& bnd = bnodes[corners[j]]; + bcell.addNode(&bnd, corners[j]); } } } - } } @@ -1213,13 +1014,11 @@ BackgroundMesh::addStructure() // set bnodes of the cell // add the particle to the cell // add bnodes to the cell -int -BackgroundMesh::addParticles() -{ +int BackgroundMesh::addParticles() { // for all particles TaggedObjectIter& meshes = OPS_getAllMesh(); Mesh* mesh = 0; - while((mesh = dynamic_cast(meshes())) != 0) { + while ((mesh = dynamic_cast(meshes())) != 0) { ParticleGroup* group = dynamic_cast(mesh); if (group == 0) { continue; @@ -1228,7 +1027,8 @@ BackgroundMesh::addParticles() // check group tag if (group->getTag() == contact_tag) { opserr << "WARNING: the particle group tag " << contact_tag; - opserr << " is reserved for internal use. Please select a different one\n"; + opserr << " is reserved for internal use. Please select a " + "different one\n"; return -1; } @@ -1236,8 +1036,7 @@ BackgroundMesh::addParticles() VInt rm(group->numParticles(), 0); // for all particles - for (int j=0; jnumParticles(); j++) { - + for (int j = 0; j < group->numParticles(); j++) { // get particle Particle* p = group->getParticle(j); if (p == 0) continue; @@ -1250,58 +1049,40 @@ BackgroundMesh::addParticles() lowerIndex(crds, index); // if out of range - for (int i=0; i<(int)index.size(); ++i) { - if (index[i]=upper[i]) { + for (int i = 0; i < (int)index.size(); ++i) { + if (index[i] < lower[i] || index[i] >= upper[i]) { rm[j] = 1; break; } } if (rm[j] == 1) continue; - // get size level - int level = getSizeLevel(index); - // get bcell BCell& bcell = bcells[index]; - // check size level - if (bcell.sizeLevel != 0 && bcell.sizeLevel!=level) { - opserr << "WARNING: regions with different mesh sizes" - "are overlapping\n"; - return -1; - } - bcell.sizeLevel = level; - // add particles bcell.add(p); // if initial check structure cell - if (bcell.type == STRUCTURE) { - if (level > 1) { - opserr << "WARNING: structural cell should have finest mesh\n"; - return -1; - } - if (!fsiTri) continue; + if (bcell.getType() == BACKGROUND_STRUCTURE) { + continue; } // add bnodes of the cell - if (bcell.bnodes.empty()) { - + if (bcell.getNodes().empty()) { // get corners VVInt indices; - getCorners(index,1,level,indices); + getCorners(index, 1, indices); // set corners - for (int i=0; i<(int)indices.size(); ++i) { + for (int i = 0; i < (int)indices.size(); ++i) { BNode& bnode = bnodes[indices[i]]; if (bnode.size() == 0) { - bnode.type = FLUID; + bnode.setType(BACKGROUND_FLUID); } - bcell.bnodes.push_back(&bnode); - bcell.bindex.push_back(indices[i]); + bcell.addNode(&bnode, indices[i]); } } - } // remove out of range particles @@ -1311,183 +1092,56 @@ BackgroundMesh::addParticles() return 0; } -int -BackgroundMesh::inlet() -{ - // check nump - if (inletNum.empty()) { - return 0; - } - int nump = 1; - for (int i = 0; i < (int) inletNum.size(); ++i) { - nump *= inletNum[i]; - } - if (nump <= 0) { - opserr << "WARNING: inlet number of particles for one cell is not correctly set\n"; - return -1; - } - - // get group - ParticleGroup* group = 0; - TaggedObjectIter& meshes = OPS_getAllMesh(); - Mesh* mesh = 0; - while((mesh = dynamic_cast(meshes())) != 0) { - group = dynamic_cast(mesh); - if (group != 0) { - break; - } - } - if (group == 0) { - opserr << "WARNING: no particle group is defined\n"; - return -1; - } - - // for each inlet location - for (int i = 0; i < (int) inletLoc.size(); ++i) { - - // get bcell - BCell& bcell = bcells[inletLoc[i]]; - - // get size level - int level = getSizeLevel(inletLoc[i]); - if (bcell.sizeLevel != 0 && bcell.sizeLevel!=level) { - opserr << "WARNING: regions with different mesh sizes" - "are overlapping\n"; - return -1; - } - bcell.sizeLevel = level; - - if (bcell.type == STRUCTURE) { - opserr << "WARNING: inlet boundary overlapps with structure\n"; - return -1; - } - - // add bnodes of the cell - if (bcell.bnodes.empty()) { - - // get corners - VVInt indices; - getCorners(inletLoc[i],1,level,indices); - - // set corners - for (int j=0; j<(int)indices.size(); ++j) { - BNode& bnode = bnodes[indices[j]]; - if (bnode.size() == 0) { - bnode.type = FLUID; - } - bcell.bnodes.push_back(&bnode); - bcell.bindex.push_back(indices[j]); - } - } - - // create and add particles - int numneed = nump - bcell.pts.size(); - int count = 0; - VDouble crds(inletNum.size()); - - Particle* particle = 0; - if (inletNum.size() == 2) { - int sizex = bsize / (inletNum[0]+1); - int sizey = bsize / (inletNum[1]+1); - for (int j = 0; j < inletNum[0]; ++j) { - for (int k = 0; k < inletNum[1]; ++k) { - if (count >= numneed) break; - getCrds(inletLoc[i], crds); - crds[0] += sizex / 2.0 + j * sizex; - crds[1] += sizey / 2.0 + k * sizey; - - group->addParticle(crds, inletVel[i], 0.0); - particle = group->getParticle(group->numParticles()-1); - } - } - } else if (inletNum.size() == 3) { - int sizex = bsize / (inletNum[0]+1); - int sizey = bsize / (inletNum[1]+1); - int sizez = bsize / (inletNum[2]+1); - for (int j = 0; j < inletNum[0]; ++j) { - for (int k = 0; k < inletNum[1]; ++k) { - for (int l = 0; l < inletNum[2]; ++l) { - if (count >= numneed) break; - getCrds(inletLoc[i], crds); - crds[0] += sizex / 2.0 + j * sizex; - crds[1] += sizey / 2.0 + k * sizey; - crds[2] += sizez / 2.0 + l * sizez; - - group->addParticle(crds, inletVel[i], 0.0); - particle = group->getParticle(group->numParticles() - 1); - } - } - } - } - bcell.add(particle); - } - return 0; -} - -int -BackgroundMesh::gridNodes() -{ +int BackgroundMesh::gridNodes() { // get domain int ndm = OPS_GetNDM(); Domain* domain = OPS_GetDomain(); if (domain == 0) return 0; // vector of iterators - std::vector::iterator> iters; + std::vector::iterator> iters; iters.reserve(bnodes.size()); - for (std::map::iterator it=bnodes.begin(); it!=bnodes.end(); ++it) { + for (std::map::iterator it = bnodes.begin(); + it != bnodes.end(); ++it) { iters.push_back(it); } - // each cell + // vector of new objects int ndtag = Mesh::nextNodeTag(); - std::vector newnodes(iters.size(),0), newpnodes(iters.size(), 0); + std::vector newnodes(iters.size(), 0), + newpnodes(iters.size(), 0); std::vector newpcs(iters.size(), 0); int res = 0; #pragma omp parallel for - for (int j=0; j<(int)iters.size(); ++j) { - + for (int j = 0; j < (int)iters.size(); ++j) { // get iterator - std::map::iterator it = iters[j]; + std::map::iterator it = iters[j]; // get cell const VInt& index = it->first; BNode& bnode = it->second; - if (bnode.type == FIXED) { + if (bnode.getType() == BACKGROUND_FIXED) { continue; } -// if (bnode.type[0] == STRUCTURE) {continue;} // coordinates VDouble crds; - getCrds(index,crds); - - // get surrounding cells and highest level - VInt ind = index; - ind -= 1; - VVInt indices; - getCorners(index, 1, 1, indices); - int level = 0; - for (int k = 0; k < (int) indices.size(); ++k) { - int lv = getSizeLevel(indices[k]); - if (level < lv) level = lv; - } + getCrds(index, crds); // get particles VParticle pts; VInt minind = index; VInt maxind = index; - minind -= numave * level; - maxind += numave * level; - gatherParticles(minind,maxind,pts); - - // find closest particle - VDouble wts(pts.size()); - VDouble closeVel(ndm); - double minDist = -1; - for (int i=0; i<(int)pts.size(); ++i) { + minind -= numave; + maxind += numave; + gatherParticles(minind, maxind, pts); + + // get information + double wt = 0.0, pre = 0.0, pdot = 0.0; + VDouble vel(ndm), accel(ndm); + for (int i = 0; i < (int)pts.size(); ++i) { // get particle if (pts[i] == 0) { continue; @@ -1499,56 +1153,30 @@ BackgroundMesh::gridNodes() // distance from particle to current location VDouble dist = pcrds; dist -= crds; - double q = normVDouble(dist) / (bsize * level); + double q = normVDouble(dist) / (bsize * numave); // weight for the particle - wts[i] = QuinticKernel(q, bsize * level, ndm); - - // check minimum distance - if (minDist < 0 || q < minDist) { - minDist = q; - closeVel = pts[i]->getVel(); - } - } - - // get information - double wt = 0.0, pre = 0.0, pdot = 0.0; - VDouble crdsn(ndm), vel(ndm), accel(ndm); - for (int i=0; i<(int)pts.size(); ++i) { - - // get particle - if (pts[i] == 0 || wts[i] <= 0) { - continue; - } + double w = QuinticKernel(q, bsize, ndm); // check velocity - const VDouble &pvel = pts[i]->getVel(); - if (kernelClose && dotVDouble(closeVel, pvel) < 0) { - continue; - } + const VDouble& pvel = pts[i]->getVel(); // add pressure - pre += pts[i]->getPressure() * wts[i]; - pdot += pts[i]->getPdot() * wts[i]; + pre += pts[i]->getPressure() * w; + pdot += pts[i]->getPdot() * w; // add velocity for (int k = 0; k < ndm; k++) { - vel[k] += wts[i] * pvel[k]; + vel[k] += w * pvel[k]; } // add acceleration - const VDouble &paccel = pts[i]->getAccel(); - for (int k = 0; k < ndm; k++) { - accel[k] += wts[i] * paccel[k]; - } - - // add displacement of last time step - const VDouble &pcrdsn = pts[i]->getCrdsn(); + const VDouble& paccel = pts[i]->getAccel(); for (int k = 0; k < ndm; k++) { - crdsn[k] += wts[i] * pcrdsn[k]; + accel[k] += w * paccel[k]; } - wt += wts[i]; + wt += w; } // get nodal states @@ -1557,15 +1185,16 @@ BackgroundMesh::gridNodes() pdot /= wt; vel /= wt; accel /= wt; - crdsn /= wt; } // update pressure for structural nodes - if (bnode.type == STRUCTURE) { + if (bnode.getType() == BACKGROUND_STRUCTURE) { + auto& tags = bnode.getTags(); for (int i = 0; i < (int)bnode.size(); ++i) { - Pressure_Constraint* pc = domain->getPressure_Constraint(bnode.tags[i]); + Pressure_Constraint* pc = + domain->getPressure_Constraint(tags[i]); if (pc == 0) { - opserr << "WARNING: structural node "< 0) { Vector vec; - toVector(crdsn, vec); - node->setTrialDisp(vec); toVector(vel, vec); node->setTrialVel(vec); toVector(accel, vec); node->setTrialAccel(vec); node->commitState(); - toVector(crds, vec); - node->setTrialDisp(vec); - } else { - Vector vec; - toVector(crds, vec); - node->setTrialDisp(vec); - node->commitState(); } // add to newnodes newnodes[j] = node; // set the bnode - bnode.addNode(node->getTag(),crds,vel,accel,pre,pdot,FLUID); + bnode.addNode(node->getTag(), crds, vel, accel, pre, pdot, + BACKGROUND_FLUID); // set pressure - Pressure_Constraint* thePC = domain->getPressure_Constraint(node->getTag()); + Pressure_Constraint* thePC = + domain->getPressure_Constraint(node->getTag()); Node* pnode = 0; - if(thePC != 0) { + if (thePC != 0) { thePC->setDomain(domain); pnode = thePC->getPressureNode(); if (pnode == 0) { - opserr << "WARNING: pressure does not exist -- BgMesh::gridNodes\n"; + opserr << "WARNING: pressure does not exist -- " + "BgMesh::gridNodes\n"; res = -1; continue; } } else { - // create pressure node if (ndm == 2) { - pnode = new Node(ndtag+2*j+1, 1, crds[0], crds[1]); + pnode = new Node(ndtag + 2 * j + 1, 1, crds[0], crds[1]); } else if (ndm == 3) { - pnode = new Node(ndtag+2*j+1, 1, crds[0], crds[1], crds[2]); + pnode = new Node(ndtag + 2 * j + 1, 1, crds[0], crds[1], + crds[2]); } if (pnode == 0) { - opserr << "WARNING: run out of memory -- BgMesh::gridNodes\n"; + opserr + << "WARNING: run out of memory -- BgMesh::gridNodes\n"; res = -1; continue; } newpnodes[j] = pnode; - thePC = new Pressure_Constraint(node->getTag(), pnode->getTag()); - if(thePC == 0) { - opserr<<"WARNING: no enough memory for Pressure_Constraint\n"; + thePC = + new Pressure_Constraint(node->getTag(), pnode->getTag()); + if (thePC == 0) { + opserr << "WARNING: no enough memory for " + "Pressure_Constraint\n"; res = -1; continue; } newpcs[j] = thePC; - } if (wt > 0) { Vector newvel = pnode->getVel(); @@ -1666,32 +1291,35 @@ BackgroundMesh::gridNodes() } // add nodes and pcs to domain - for (int i=0; i<(int)newnodes.size(); ++i) { + for (int i = 0; i < (int)newnodes.size(); ++i) { if (newnodes[i] == 0) continue; // add to domain if (domain->addNode(newnodes[i]) == false) { - opserr<<"WARNING: failed to add node to domain -- BgMesh::gridNodes\n"; + opserr << "WARNING: failed to add node to domain -- " + "BgMesh::gridNodes\n"; delete newnodes[i]; return -1; } } - for (int i=0; i<(int)newpnodes.size(); ++i) { + for (int i = 0; i < (int)newpnodes.size(); ++i) { if (newpnodes[i] == 0) continue; // add to domain if (domain->addNode(newpnodes[i]) == false) { - opserr<<"WARNING: failed to add node to domain -- BgMesh::gridNodes\n"; + opserr << "WARNING: failed to add node to domain -- " + "BgMesh::gridNodes\n"; delete newpnodes[i]; return -1; } } - for (int i=0; i<(int)newpcs.size(); ++i) { + for (int i = 0; i < (int)newpcs.size(); ++i) { if (newpcs[i] == 0) continue; // add to domain - if(domain->addPressure_Constraint(newpcs[i]) == false) { - opserr<<"WARNING: failed to add PC to domain -- BgMesh::gridNodes\n"; + if (domain->addPressure_Constraint(newpcs[i]) == false) { + opserr << "WARNING: failed to add PC to domain -- " + "BgMesh::gridNodes\n"; delete newpcs[i]; return -1; } @@ -1700,25 +1328,23 @@ BackgroundMesh::gridNodes() return 0; } -int -BackgroundMesh::moveFixedParticles() -{ +int BackgroundMesh::moveFixedParticles() { int ndm = OPS_GetNDM(); // check each cell - for (std::map::iterator it = bcells.begin(); it != bcells.end(); ++it) { - + for (std::map::iterator it = bcells.begin(); + it != bcells.end(); ++it) { // get cell const VInt& index = it->first; BCell& cell = it->second; // empty cell - if (cell.pts.empty()) { + if (cell.getPts().empty()) { continue; } - // check if STRUCTURE cell - if (cell.type != STRUCTURE) { + // check if BACKGROUND_STRUCTURE cell + if (cell.getType() != BACKGROUND_STRUCTURE) { continue; } @@ -1726,18 +1352,19 @@ BackgroundMesh::moveFixedParticles() VInt ind = index; VVInt indices; ind -= 1; - getCorners(ind, 2, 1, indices); + getCorners(ind, 2, indices); // give each cell a score VInt scores(indices.size()); - for (int i=0; i<(int)indices.size(); ++i) { - std::map::iterator cellit = bcells.find(indices[i]); + for (int i = 0; i < (int)indices.size(); ++i) { + std::map::iterator cellit = + bcells.find(indices[i]); if (cellit == bcells.end()) { // empty cell scores[i] = 2; continue; } - if (cellit->second.type == STRUCTURE) { + if (cellit->second.getType() == BACKGROUND_STRUCTURE) { scores[i] = -1; } else { scores[i] = 1; @@ -1746,109 +1373,117 @@ BackgroundMesh::moveFixedParticles() VVInt cellmap; if (ndm == 2) { cellmap.resize(9); - for (int i=0; i<(int)cellmap.size(); ++i) { + for (int i = 0; i < (int)cellmap.size(); ++i) { cellmap[i].resize(3); cellmap[i][0] = i; } - cellmap[0][1] = 1; cellmap[0][2] = 3; - cellmap[1][1] = 0; cellmap[1][2] = 2; - cellmap[2][1] = 1; cellmap[2][2] = 5; - cellmap[3][1] = 0; cellmap[3][2] = 6; - cellmap[4][1] = 4; cellmap[4][2] = 4; - cellmap[5][1] = 2; cellmap[5][2] = 8; - cellmap[6][1] = 3; cellmap[6][2] = 7; - cellmap[7][1] = 6; cellmap[7][2] = 8; - cellmap[8][1] = 5; cellmap[8][2] = 7; + cellmap[0][1] = 1; + cellmap[0][2] = 3; + cellmap[1][1] = 0; + cellmap[1][2] = 2; + cellmap[2][1] = 1; + cellmap[2][2] = 5; + cellmap[3][1] = 0; + cellmap[3][2] = 6; + cellmap[4][1] = 4; + cellmap[4][2] = 4; + cellmap[5][1] = 2; + cellmap[5][2] = 8; + cellmap[6][1] = 3; + cellmap[6][2] = 7; + cellmap[7][1] = 6; + cellmap[7][2] = 8; + cellmap[8][1] = 5; + cellmap[8][2] = 7; } else if (ndm == 3) { cellmap.resize(27); - int cm0[] = {0,1,3,9}; - cellmap[0].assign(cm0,cm0+4); + int cm0[] = {0, 1, 3, 9}; + cellmap[0].assign(cm0, cm0 + 4); - int cm1[] = {0,1,2,10}; - cellmap[1].assign(cm1,cm1+4); + int cm1[] = {0, 1, 2, 10}; + cellmap[1].assign(cm1, cm1 + 4); - int cm2[] = {1,2,5,11}; - cellmap[2].assign(cm2,cm2+4); + int cm2[] = {1, 2, 5, 11}; + cellmap[2].assign(cm2, cm2 + 4); - int cm3[] = {0,3,6,12}; - cellmap[3].assign(cm3,cm3+4); + int cm3[] = {0, 3, 6, 12}; + cellmap[3].assign(cm3, cm3 + 4); - int cm4[] = {0,1,2,3,4,5,6,7,8}; - cellmap[4].assign(cm4,cm4+9); + int cm4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; + cellmap[4].assign(cm4, cm4 + 9); - int cm5[] = {2,5,8,14}; - cellmap[5].assign(cm5,cm5+4); + int cm5[] = {2, 5, 8, 14}; + cellmap[5].assign(cm5, cm5 + 4); - int cm6[] = {3,6,7,15}; - cellmap[6].assign(cm6,cm6+4); + int cm6[] = {3, 6, 7, 15}; + cellmap[6].assign(cm6, cm6 + 4); - int cm7[] = {6,7,8,16}; - cellmap[7].assign(cm7,cm7+4); + int cm7[] = {6, 7, 8, 16}; + cellmap[7].assign(cm7, cm7 + 4); - int cm8[] = {5,8,7,17}; - cellmap[8].assign(cm8,cm8+4); + int cm8[] = {5, 8, 7, 17}; + cellmap[8].assign(cm8, cm8 + 4); - int cm9[] = {9,10,12,0,18}; - cellmap[9].assign(cm9,cm9+5); + int cm9[] = {9, 10, 12, 0, 18}; + cellmap[9].assign(cm9, cm9 + 5); - int cm10[] = {9,10,11,0,1,2,18,19,20}; - cellmap[10].assign(cm10,cm10+9); + int cm10[] = {9, 10, 11, 0, 1, 2, 18, 19, 20}; + cellmap[10].assign(cm10, cm10 + 9); - int cm11[] = {10,11,14,2,20}; - cellmap[11].assign(cm11,cm11+5); + int cm11[] = {10, 11, 14, 2, 20}; + cellmap[11].assign(cm11, cm11 + 5); - int cm12[] = {9,12,15,0,3,6,18,21,24}; - cellmap[12].assign(cm12,cm12+9); + int cm12[] = {9, 12, 15, 0, 3, 6, 18, 21, 24}; + cellmap[12].assign(cm12, cm12 + 9); - int cm13[] = {13,13,13,13}; - cellmap[13].assign(cm13,cm13+4); + int cm13[] = {13, 13, 13, 13}; + cellmap[13].assign(cm13, cm13 + 4); - int cm14[] = {11,14,17,2,5,8,20,23,26}; - cellmap[14].assign(cm14,cm14+9); + int cm14[] = {11, 14, 17, 2, 5, 8, 20, 23, 26}; + cellmap[14].assign(cm14, cm14 + 9); - int cm15[] = {12,15,16,6,24}; - cellmap[15].assign(cm15,cm15+5); + int cm15[] = {12, 15, 16, 6, 24}; + cellmap[15].assign(cm15, cm15 + 5); - int cm16[] = {15,16,17,6,7,8,24,25,26}; - cellmap[16].assign(cm16,cm16+9); + int cm16[] = {15, 16, 17, 6, 7, 8, 24, 25, 26}; + cellmap[16].assign(cm16, cm16 + 9); - int cm17[] = {14,17,16,8,26}; - cellmap[17].assign(cm17,cm17+5); + int cm17[] = {14, 17, 16, 8, 26}; + cellmap[17].assign(cm17, cm17 + 5); - int cm18[] = {18,19,21,9}; - cellmap[18].assign(cm18,cm18+4); + int cm18[] = {18, 19, 21, 9}; + cellmap[18].assign(cm18, cm18 + 4); - int cm19[] = {18,19,20,10}; - cellmap[19].assign(cm19,cm19+4); + int cm19[] = {18, 19, 20, 10}; + cellmap[19].assign(cm19, cm19 + 4); - int cm20[] = {19,20,23,11}; - cellmap[20].assign(cm20,cm20+4); + int cm20[] = {19, 20, 23, 11}; + cellmap[20].assign(cm20, cm20 + 4); - int cm21[] = {18,21,24,12}; - cellmap[21].assign(cm21,cm21+4); + int cm21[] = {18, 21, 24, 12}; + cellmap[21].assign(cm21, cm21 + 4); - int cm22[] = {18,19,20,21,22,23,24,25,26}; - cellmap[22].assign(cm22,cm22+9); + int cm22[] = {18, 19, 20, 21, 22, 23, 24, 25, 26}; + cellmap[22].assign(cm22, cm22 + 9); - int cm23[] = {20,23,26,14}; - cellmap[23].assign(cm23,cm23+4); + int cm23[] = {20, 23, 26, 14}; + cellmap[23].assign(cm23, cm23 + 4); - int cm24[] = {21,24,25,15}; - cellmap[24].assign(cm24,cm24+4); + int cm24[] = {21, 24, 25, 15}; + cellmap[24].assign(cm24, cm24 + 4); - int cm25[] = {24,25,26,16}; - cellmap[25].assign(cm25,cm25+4); + int cm25[] = {24, 25, 26, 16}; + cellmap[25].assign(cm25, cm25 + 4); - int cm26[] = {23,25,26,17}; - cellmap[26].assign(cm26,cm26+4); + int cm26[] = {23, 25, 26, 17}; + cellmap[26].assign(cm26, cm26 + 4); } // get final scores - VInt finalscores(scores.size(),0); + VInt finalscores(scores.size(), 0); for (int j = 0; j < (int)finalscores.size(); ++j) { - // calculate score for (int k = 0; k < (int)cellmap[j].size(); ++k) { finalscores[j] += scores[cellmap[j][k]]; @@ -1865,22 +1500,11 @@ BackgroundMesh::moveFixedParticles() } } } -// int order[] = {10,12,14,16,4,22,9,11,15,17, -// 0,1,2,3,5,6,7,8,18,19,20,21, -// 23,24,25,26,13}; -// for (int i=0; i<27; ++i) { -// int j = order[i]; -// if (scores[j] > 0) { -// for (int k=0; k<(int)cellmap[j].size(); ++k) { -// finalscores[j] += scores[cellmap[j][k]]; -// } -// } -// } // find the cell with highest score int high = -100; ind = index; - for (int i=0; i<(int)finalscores.size(); ++i) { + for (int i = 0; i < (int)finalscores.size(); ++i) { if (high < finalscores[i]) { high = finalscores[i]; ind = indices[i]; @@ -1888,56 +1512,73 @@ BackgroundMesh::moveFixedParticles() } if (ind == index) continue; + // get new cell + auto& new_cell = bcells[ind]; + if (new_cell.getType() == BACKGROUND_STRUCTURE) { + continue; + } + + // if an new empty cell + if (new_cell.getNodes().empty()) { + // get corners + indices.clear(); + getCorners(ind, 1, indices); + + // set corners + for (int k = 0; k < (int)indices.size(); ++k) { + BNode& bnode = bnodes[indices[k]]; + if (bnode.size() == 0) { + bnode.setType(BACKGROUND_FLUID); + } + new_cell.addNode(&bnode, indices[k]); + } + } + + // get averate structural velocity + VDouble svel(ndm); + int numv = 0; + for (auto* bnode : cell.getNodes()) { + if (bnode->getType() != BACKGROUND_STRUCTURE) { + continue; + } + auto& vel = bnode->getVel(); + for (int i = 0; i < bnode->size(); ++i) { + svel += vel[i]; + ++numv; + } + } + svel /= numv; + double mag_svel = normVDouble(svel); + // move the particles VDouble crds; - getCrds(index,crds); - for (int i = 0; i < (int)cell.pts.size(); ++i) { - Particle* pt = cell.pts[i]; - const VDouble& pcrds = pt->getCrds(); + getCrds(index, crds); + auto& pts = cell.getPts(); + for (int i = 0; i < (int)pts.size(); ++i) { + Particle* pt = pts[i]; + auto pcrds = pt->getCrds(); // move the particle VDouble newcrds; - getCrds(ind,newcrds); - VDouble disp = pcrds; - disp -= crds; - newcrds += disp; - pt->moveTo(newcrds,0.0); - - // add particles to the new cell - // BCell& bcell = bcells[ind]; - // bcell.add(pt); - // if (bcell.type == STRUCTURE) { - // // still a structure!! - // continue; - // } - - // // if an empty cell - // if (bcell.bnodes.empty()) { - - // // get corners - // indices.clear(); - // getCorners(ind,1,1,indices); - - // // set corners - // for (int k=0; k<(int)indices.size(); ++k) { - // BNode& bnode = bnodes[indices[k]]; - // if (bnode.size() == 0) { - // bnode.addNode(FLUID); - // } - // bcell.bnodes.push_back(&bnode); - // bcell.bindex.push_back(indices[k]); - // } - // } - } - - cell.pts.clear(); + getCrds(ind, newcrds); + pcrds -= crds; + pcrds += newcrds; + pt->moveTo(pcrds, 0.0); + auto& pvel = pt->getVel(); + double mag_pvel = normVDouble(pvel); + if (mag_svel > mag_pvel) { + pt->setVelOnly(svel); + } + + new_cell.add(pt); + } + + cell.clearParticles(); } return 0; } -int -BackgroundMesh::gridFluid() -{ +int BackgroundMesh::gridFluid() { Domain* domain = OPS_GetDomain(); if (domain == 0) return 0; int ndm = OPS_GetNDM(); @@ -1947,7 +1588,8 @@ BackgroundMesh::gridFluid() VVInt indices; cells.reserve(bcells.size()); indices.reserve(bcells.size()); - for (std::map::iterator it=bcells.begin(); it!=bcells.end(); ++it) { + for (std::map::iterator it = bcells.begin(); + it != bcells.end(); ++it) { indices.push_back(it->first); cells.push_back(&(it->second)); } @@ -1962,112 +1604,117 @@ BackgroundMesh::gridFluid() numele = 6; numelenodes = 4; } - VVInt elends(numele*cells.size()); - VInt gtags(numele*cells.size()); + VVInt elends(numele * cells.size()); + VInt gtags(numele * cells.size()); #pragma omp parallel for - for (int j=0; j<(int)cells.size(); ++j) { - + for (int j = 0; j < (int)cells.size(); ++j) { // structural cell - if (cells[j]->type == STRUCTURE) continue; + if (cells[j]->getType() == BACKGROUND_STRUCTURE) continue; // find the group of this mesh - std::map numpts; - for (int i=0; i<(int)cells[j]->pts.size(); ++i) { - numpts[cells[j]->pts[i]->getGroupTag()] += 1; - } - int num=0; - int gtag=0; - for (std::map::iterator it=numpts.begin(); it!=numpts.end(); ++it) { + std::map numpts; + auto& pts = cells[j]->getPts(); + for (int i = 0; i < (int)pts.size(); ++i) { + numpts[pts[i]->getGroupTag()] += 1; + } + int num = 0; + int gtag = 0; + for (std::map::iterator it = numpts.begin(); + it != numpts.end(); ++it) { if (num < it->second) { num = it->second; gtag = it->first; } } - for (int i=0; ibnodes.size()); - for (int i=0; i<(int)cnodes.size(); ++i) { - if (cells[j]->bnodes[i]->tags.empty()) { - opserr << "WARNING: failed to be fluid node -- gridFluid\n"; + auto& bnodes = cells[j]->getNodes(); + VInt cnodes(bnodes.size()); + for (int i = 0; i < (int)cnodes.size(); ++i) { + if (bnodes[i]->getTags().empty()) { + opserr + << "WARNING: failed to be fluid node -- gridFluid\n"; continue; } - cnodes[i] = cells[j]->bnodes[i]->tags[0]; + auto& tags = bnodes[i]->getTags(); + cnodes[i] = tags[0]; } - for (int i=0; i elenodes; - for (int i=0; i<(int)elends.size(); ++i) { - + std::map elenodes; + for (int i = 0; i < (int)elends.size(); ++i) { // no elenodes, no element if (elends[i].empty()) continue; // if all nodes are fluid and fixed nodes ID& nds = elenodes[gtags[i]]; - for (int j=0; j<(int)elends[i].size(); ++j) { + for (int j = 0; j < (int)elends[i].size(); ++j) { nds[nds.Size()] = elends[i][j]; } } // create elements - for (std::map::iterator it=elenodes.begin(); it!=elenodes.end(); ++it) { - ParticleGroup* group = dynamic_cast(OPS_getMesh(it->first)); + for (std::map::iterator it = elenodes.begin(); + it != elenodes.end(); ++it) { + ParticleGroup* group = + dynamic_cast(OPS_getMesh(it->first)); if (group == 0) { - opserr << "WARNING: failed to get particle group -- BgMesh::gridFluid\n"; + opserr << "WARNING: failed to get particle group -- " + "BgMesh::gridFluid\n"; return -1; } group->setEleNodes(it->second); if (group->newElements(it->second) < 0) { opserr << "WARNING: failed to create elements for mesh "; - opserr << group->getTag()<<" -- BgMesh::gridFluid\n"; + opserr << group->getTag() << " -- BgMesh::gridFluid\n"; return -1; } } @@ -2075,53 +1722,482 @@ BackgroundMesh::gridFluid() return 0; } -int -BackgroundMesh::gridFSI(ID& freenodes) -{ +int BackgroundMesh::gridFSInoDT() { Domain* domain = OPS_GetDomain(); if (domain == 0) return 0; int ndm = OPS_GetNDM(); - TriangleMeshGenerator gen; - TetMeshGenerator tetgen; - - // gather bnodes - std::map fsibnodes; - for (std::map::iterator it=bcells.begin(); it!=bcells.end(); ++it) { - - // only for structural cells - BCell& bcell = it->second; - if (bcell.type == FLUID) continue; - - // get bnode - for (int j=0; j<(int)bcell.bnodes.size(); ++j) { - BNode* bnode = bcell.bnodes[j]; - VInt bindex = bcell.bindex[j]; - if (bnode == 0) { - opserr << "WARNING: failed to get bnode -- gridFSI\n"; - return -1; - } - fsibnodes[bindex] = bnode; + // store cells in a vector + std::vector cells; + for (auto& item : bcells) { + auto& cell = item.second; + if (cell.getType() == BACKGROUND_STRUCTURE) { + cells.push_back(&cell); } } - // add points - VInt ndtags, ndtypes, ndsids; - VVInt ndindex; - VDouble min, max; - for (std::map::iterator it=fsibnodes.begin(); it!=fsibnodes.end(); ++it) { - + // create elements in each cell + int numele = 0; + if (ndm == 2) { + numele = 2; + } else if (ndm == 3) { + numele = 6; + } + VVInt elends(numele * cells.size()); + VInt gtags(numele * cells.size()); +#pragma omp parallel for + for (int j = 0; j < (int)cells.size(); ++j) { + // get indices + auto& cindices = cells[j]->getIndices(); + + // get bnodes + auto& cbnodes = cells[j]->getNodes(); + + // node tags and sids + VInt tags(cbnodes.size(), -1), sids(cbnodes.size()), + types(cbnodes.size()); + VVDouble ndcrds(cbnodes.size()); + for (int i = 0; i < (int)tags.size(); ++i) { + types[i] = cbnodes[i]->getType(); + if (types[i] != BACKGROUND_FIXED) { + auto& ctags = cbnodes[i]->getTags(); + tags[i] = ctags[0]; + auto& ids = cbnodes[i]->getSid(); + sids[i] = ids[0]; + auto& crdsn = cbnodes[i]->getCrds(); + ndcrds[i] = crdsn[0]; + } + } + + // get fluid and structural local indices + VInt flocal, slocal, fixlocal; + for (int i = 0; i < (int)types.size(); ++i) { + int type = types[i]; + if (type == BACKGROUND_STRUCTURE) { + slocal.push_back(i); + } else if (type == BACKGROUND_FLUID) { + flocal.push_back(i); + } else { + fixlocal.push_back(i); + } + } + + // contact cell: must fully engaged + if (ndm == 2 && slocal.size() == 4) { + VInt csnds(3), csids(3); + if (slocal.size() == 4) { + // two contact elements + csnds[0] = tags[0]; + csnds[1] = tags[3]; + csnds[2] = tags[2]; + csids[0] = sids[0]; + csids[1] = sids[3]; + csids[2] = sids[2]; + if (createContact(csnds, csids, elends[numele * j])) { + gtags[numele * j] = contact_tag; + } + + csnds[0] = tags[0]; + csnds[1] = tags[1]; + csnds[2] = tags[3]; + csids[0] = sids[0]; + csids[1] = sids[1]; + csids[2] = sids[3]; + if (createContact(csnds, csids, elends[numele * j + 1])) { + gtags[numele * j + 1] = contact_tag; + } + continue; + } + } else if (ndm == 3 && slocal.size() == 8) { + // 3D contact element: TODO + continue; + } + + // get surrounding cells + VInt min = cindices[0]; + min -= 1; + VInt max = cindices[0]; + max += 2; + + // gather particles + VParticle pts; + gatherParticles(min, max, pts); + if (pts.empty()) { + continue; + } + + // find the group of this mesh + std::map numpts; + for (int i = 0; i < (int)pts.size(); ++i) { + numpts[pts[i]->getGroupTag()] += 1; + } + int num = 0; + int gtag = 0; + for (std::map::iterator it = numpts.begin(); + it != numpts.end(); ++it) { + if (num < it->second) { + num = it->second; + gtag = it->first; + } + } + for (int i = 0; i < numele; ++i) { + gtags[numele * j + i] = gtag; + } + + // add to elenodes + if (ndm == 2) { + if (types[1] == BACKGROUND_STRUCTURE && + types[2] == BACKGROUND_STRUCTURE) { + if (types[0] != BACKGROUND_FIXED) { + if (!check_area(ndcrds[0], ndcrds[1], ndcrds[2])) { + elends[numele * j].push_back(tags[0]); + elends[numele * j].push_back(tags[1]); + elends[numele * j].push_back(tags[2]); + } + } + if (types[3] != BACKGROUND_FIXED) { + if (!check_area(ndcrds[1], ndcrds[3], ndcrds[2])) { + elends[numele * j + 1].push_back(tags[1]); + elends[numele * j + 1].push_back(tags[3]); + elends[numele * j + 1].push_back(tags[2]); + } + } + + } else if (types[0] == BACKGROUND_STRUCTURE && + types[3] == BACKGROUND_STRUCTURE) { + if (types[1] != BACKGROUND_FIXED) { + if (!check_area(ndcrds[0], ndcrds[1], ndcrds[3])) { + elends[numele * j].push_back(tags[0]); + elends[numele * j].push_back(tags[1]); + elends[numele * j].push_back(tags[3]); + } + } + if (types[2] != BACKGROUND_FIXED) { + if (!check_area(ndcrds[0], ndcrds[3], ndcrds[2])) { + elends[numele * j + 1].push_back(tags[0]); + elends[numele * j + 1].push_back(tags[3]); + elends[numele * j + 1].push_back(tags[2]); + } + } + + } else if (types[1] != BACKGROUND_FIXED && + types[2] != BACKGROUND_FIXED) { + if (types[0] != BACKGROUND_FIXED) { + if (!check_area(ndcrds[0], ndcrds[1], ndcrds[2])) { + elends[numele * j].push_back(tags[0]); + elends[numele * j].push_back(tags[1]); + elends[numele * j].push_back(tags[2]); + } + } + if (types[3] != BACKGROUND_FIXED) { + if (!check_area(ndcrds[1], ndcrds[3], ndcrds[2])) { + elends[numele * j + 1].push_back(tags[1]); + elends[numele * j + 1].push_back(tags[3]); + elends[numele * j + 1].push_back(tags[2]); + } + } + + } else if (types[0] != BACKGROUND_FIXED && + types[3] != BACKGROUND_FIXED) { + if (types[1] != BACKGROUND_FIXED) { + if (!check_area(ndcrds[0], ndcrds[1], ndcrds[3])) { + elends[numele * j].push_back(tags[0]); + elends[numele * j].push_back(tags[1]); + elends[numele * j].push_back(tags[3]); + } + } + if (types[2] != BACKGROUND_FIXED) { + if (!check_area(ndcrds[0], ndcrds[3], ndcrds[2])) { + elends[numele * j + 1].push_back(tags[0]); + elends[numele * j + 1].push_back(tags[3]); + elends[numele * j + 1].push_back(tags[2]); + } + } + } + + } else if (ndm == 3) { + VInt prism(6); + VVInt tets; + bool incl1, incl4; + + int face[6][4] = {{1, 2, 5, 6}, {0, 3, 4, 7}, {1, 3, 4, 6}, + {0, 2, 5, 7}, {2, 3, 4, 5}, {0, 1, 6, 7}}; + int prisms[12][6] = {{5, 4, 6, 1, 0, 2}, {6, 7, 5, 2, 3, 1}, + {4, 6, 7, 0, 2, 3}, {7, 5, 4, 3, 1, 0}, + {4, 5, 1, 6, 7, 3}, {1, 0, 4, 3, 2, 6}, + {0, 4, 5, 2, 6, 7}, {5, 1, 0, 7, 3, 2}, + {3, 1, 5, 2, 0, 4}, {5, 7, 3, 4, 6, 2}, + {1, 5, 7, 0, 4, 6}, {7, 3, 1, 6, 2, 0}}; + + // if find a splitting + bool find = false; + + // check which face is structure + for (int i = 0; i < 6; ++i) { + find = true; + for (int k = 0; k < 4; ++k) { + if (types[face[i][k]] != BACKGROUND_STRUCTURE) { + find = false; + } + } + + // if it's structure + if (find) { + // set prism + for (int k = 0; k < 2; ++k) { + for (int m = 0; m < 6; ++m) { + prism[m] = prisms[2 * i + k][m]; + } + + // check if include corner 1 + incl1 = false; + if (types[prism[1]] != BACKGROUND_FIXED) { + incl1 = true; + } + + // check if include corner 4 + incl4 = false; + if (types[prism[4]] != BACKGROUND_FIXED) { + incl4 = true; + } + + // split the prism + splitPrism(prism, tets, incl1, incl4); + + // add ele nodes + for (int m = 0; m < (int)tets.size(); ++m) { + if (!check_vol(ndcrds[tets[m][0]], + ndcrds[tets[m][1]], + ndcrds[tets[m][2]], + ndcrds[tets[m][3]])) { + for (int p : tets[m]) { + elends[numele * j + m].push_back( + tags[p]); + } + } + } + } + break; + } + } + + // check which face is not fixed + if (!find) { + for (int i = 0; i < 6; ++i) { + find = true; + for (int k = 0; k < 4; ++k) { + if (types[face[i][k]] == BACKGROUND_FIXED) { + find = false; + } + } + + // if it's not fixed + if (find) { + // set prism + for (int k = 0; k < 2; ++k) { + for (int m = 0; m < 6; ++m) { + prism[m] = prisms[2 * i + k][m]; + } + + // check if include corner 1 + incl1 = false; + if (types[prism[1]] != BACKGROUND_FIXED) { + incl1 = true; + } + + // check if include corner 4 + incl4 = false; + if (types[prism[4]] != BACKGROUND_FIXED) { + incl4 = true; + } + + // split the prism + splitPrism(prism, tets, incl1, incl4); + + // add ele nodes + for (int m = 0; m < (int)tets.size(); ++m) { + if (!check_vol(ndcrds[tets[m][0]], + ndcrds[tets[m][1]], + ndcrds[tets[m][2]], + ndcrds[tets[m][3]])) { + for (int p : tets[m]) { + elends[numele * j + m].push_back( + tags[p]); + } + } + } + } + break; + } + } + } + } + } + + // get particle group tags + std::map elenodes; + int nextEletag = Mesh::nextEleTag(); + VInt oldContactEles = contactEles; + VInt removedEles(oldContactEles.size(), 1); + contactEles.clear(); + for (int i = 0; i < (int)elends.size(); ++i) { + // no elenodes, no element + if (elends[i].empty()) continue; + + // contact element + if (gtags[i] == contact_tag) { + if (ndm == 2) { + if (elends[i].size() != 3) { + opserr << "WARNING: 2D contact should have 3 " + "nodes\n"; + return -1; + } + + // check if exists + bool created = false; + for (int j = 0; j < (int)oldContactEles.size(); ++j) { + if (removedEles[j] == 0) continue; + Element* ele = domain->getElement(oldContactEles[j]); + if (ele == 0) continue; + const ID& contactNodes = ele->getExternalNodes(); + if (contactNodes(0) == elends[i][0] && + contactNodes(1) == elends[i][1] && + contactNodes(2) == elends[i][2]) { + created = true; + removedEles[j] = 0; + contactEles.push_back(oldContactEles[j]); + break; + } + } + if (created) continue; + + if (contactData[0] <= 0 || contactData[1] <= 0 || + contactData[2] < 0 || contactData[3] < 0 || + contactData[4] <= 0 || contactData[6] <= 0 || + contactData[7] <= 0) { + opserr << "WARNING: contact data is not " + "correctly " + "set\n"; + return -1; + } + Element* ele = new PFEMContact2D( + nextEletag, elends[i][0], elends[i][1], elends[i][2], + contactData[0], contactData[1], contactData[2], + contactData[3], contactData[4], contactData[5], + contactData[6], contactData[7]); + if (ele == 0) { + opserr << "WARNING: failed to create contact " + "element\n"; + return -1; + } + if (domain->addElement(ele) == false) { + opserr << "WARNING: failed to add element " + << nextEletag << "\n"; + delete ele; + return -1; + } + contactEles.push_back(nextEletag); + nextEletag += 1; + + } else if (ndm == 3) { + if (elends[i].size() != 4) { + opserr << "WARNING: 3D contact should have 4 " + "nodes\n"; + return -1; + } + opserr << "WARNING: 3D contact element hasn't been " + "developed\n"; + } + continue; + } + + // if all nodes are fluid nodes + ID& nds = elenodes[gtags[i]]; + for (int j = 0; j < (int)elends[i].size(); ++j) { + nds[nds.Size()] = elends[i][j]; + } + } + + // remove old contact elements + for (int i = 0; i < (int)oldContactEles.size(); ++i) { + if (removedEles[i] == 1) { + opserr << "old contact element " << oldContactEles[i] << ": "; + Element* ele = domain->removeElement(oldContactEles[i]); + opserr << ele->getExternalNodes() << " is removed\n"; + if (ele != 0) { + delete ele; + } + } + } + + // create elements + for (auto& item : elenodes) { + ParticleGroup* group = + dynamic_cast(OPS_getMesh(item.first)); + if (group == 0) { + opserr << "WARNING: failed to get particle group -- " + "BgMesh::gridFluid\n"; + return -1; + } + group->setEleNodes(item.second); + + if (group->newElements(item.second) < 0) { + opserr << "WARNING: failed to create elements for mesh "; + opserr << group->getTag() << " -- BgMesh::gridFluid\n"; + return -1; + } + } + + return 0; +} + +int BackgroundMesh::gridFSI() { + Domain* domain = OPS_GetDomain(); + if (domain == 0) return 0; + int ndm = OPS_GetNDM(); + + TriangleMeshGenerator gen; + TetMeshGenerator tetgen; + + // gather bnodes + std::map fsibnodes; + for (std::map::iterator it = bcells.begin(); + it != bcells.end(); ++it) { + // only for structural cells + BCell& bcell = it->second; + if (bcell.getType() == BACKGROUND_FLUID) continue; + + // get bnode + auto& bnodes = bcell.getNodes(); + auto& bindices = bcell.getIndices(); + for (int j = 0; j < (int)bnodes.size(); ++j) { + BNode* bnode = bnodes[j]; + VInt bindex = bindices[j]; + if (bnode == 0) { + opserr << "WARNING: failed to get bnode -- gridFSI\n"; + return -1; + } + fsibnodes[bindex] = bnode; + } + } + + // add points + VInt ndtags, ndtypes, ndsids; + VVInt ndindex; + VDouble min, max; + for (std::map::iterator it = fsibnodes.begin(); + it != fsibnodes.end(); ++it) { VInt bindex = it->first; BNode* bnode = it->second; - VInt& tags = bnode->tags; - VVDouble& crdsn = bnode->crdsn; - int type = bnode->type; - VInt& sid = bnode->sid; + const VInt& tags = bnode->getTags(); + const VVDouble& crdsn = bnode->getCrds(); + int type = bnode->getType(); + const VInt& sid = bnode->getSid(); - for (int i=-1; i<(int)tags.size(); ++i) { + for (int i = -1; i < (int)tags.size(); ++i) { // -1 is only for fixed bnode - if (i==-1 && type!=FIXED) { + if (i == -1 && type != BACKGROUND_FIXED) { continue; } if (i == -1) { @@ -2142,9 +2218,9 @@ BackgroundMesh::gridFSI(ID& freenodes) } if (ndm == 2) { - gen.addPoint(crds[0],crds[1]); + gen.addPoint(crds[0], crds[1]); } else if (ndm == 3) { - tetgen.addPoint(crds[0],crds[1],crds[2],0); + tetgen.addPoint(crds[0], crds[1], crds[2], 0); } // max, min coordinates @@ -2152,14 +2228,13 @@ BackgroundMesh::gridFSI(ID& freenodes) min = crds; max = crds; } else { - for (int j=0; j crds[j]) min[j] = crds[j]; if (max[j] < crds[j]) max[j] = crds[j]; } } } } - VInt ndfree(ndtags.size()); // no mesh int numpoints = 0; @@ -2168,8 +2243,7 @@ BackgroundMesh::gridFSI(ID& freenodes) } else if (ndm == 3) { numpoints = tetgen.getNumPoints(); } - if (gen.getNumPoints() < 3 && - tetgen.getNumPoints() < 4 ) { + if (gen.getNumPoints() < 3 && tetgen.getNumPoints() < 4) { return 0; } if (min.empty() || max.empty()) { @@ -2177,22 +2251,22 @@ BackgroundMesh::gridFSI(ID& freenodes) } // add extra points to avoid small triangles on the edge - min -= 10*bsize; - max += 10*bsize; + min -= 10 * bsize; + max += 10 * bsize; if (ndm == 2) { - gen.addPoint(min[0],min[1]); - gen.addPoint(max[0],min[1]); - gen.addPoint(min[0],max[1]); - gen.addPoint(max[0],max[1]); + gen.addPoint(min[0], min[1]); + gen.addPoint(max[0], min[1]); + gen.addPoint(min[0], max[1]); + gen.addPoint(max[0], max[1]); } else if (ndm == 3) { - tetgen.addPoint(min[0],min[1],min[2],0); - tetgen.addPoint(min[0],max[1],min[2],0); - tetgen.addPoint(min[0],max[1],max[2],0); - tetgen.addPoint(min[0],min[1],max[2],0); - tetgen.addPoint(max[0],min[1],min[2],0); - tetgen.addPoint(max[0],max[1],min[2],0); - tetgen.addPoint(max[0],max[1],max[2],0); - tetgen.addPoint(max[0],min[1],max[2],0); + tetgen.addPoint(min[0], min[1], min[2], 0); + tetgen.addPoint(min[0], max[1], min[2], 0); + tetgen.addPoint(min[0], max[1], max[2], 0); + tetgen.addPoint(min[0], min[1], max[2], 0); + tetgen.addPoint(max[0], min[1], min[2], 0); + tetgen.addPoint(max[0], max[1], min[2], 0); + tetgen.addPoint(max[0], max[1], max[2], 0); + tetgen.addPoint(max[0], min[1], max[2], 0); } // mesh @@ -2214,21 +2288,20 @@ BackgroundMesh::gridFSI(ID& freenodes) VInt gtags(numele); #pragma omp parallel for - for (int i=0; i= numpoints) { extra = true; break; @@ -2239,10 +2312,10 @@ BackgroundMesh::gridFSI(ID& freenodes) // get fluid and structural indices VVInt findex, sindex; bool fixed = false; - for (int j=0; j<(int)tri.size(); ++j) { - if (ndtypes[tri[j]] == STRUCTURE) { + for (int j = 0; j < (int)tri.size(); ++j) { + if (ndtypes[tri[j]] == BACKGROUND_STRUCTURE) { sindex.push_back(ndindex[tri[j]]); - } else if (ndtypes[tri[j]] == FIXED) { + } else if (ndtypes[tri[j]] == BACKGROUND_FIXED) { fixed = true; } else { findex.push_back(ndindex[tri[j]]); @@ -2253,7 +2326,7 @@ BackgroundMesh::gridFSI(ID& freenodes) // if all structure, create contact elements if (sindex.size() == tri.size()) { VInt snds(tri.size()), sids(tri.size()); - for (int j = 0; j < (int) tri.size(); ++j) { + for (int j = 0; j < (int)tri.size(); ++j) { snds[j] = ndtags[tri[j]]; sids[j] = ndsids[tri[j]]; } @@ -2266,8 +2339,8 @@ BackgroundMesh::gridFSI(ID& freenodes) // get min and max ind VInt maxind = ndindex[tri[0]]; VInt minind = ndindex[tri[0]]; - for (int k=0; k ndindex[tri[j]][k]) { minind[k] = ndindex[tri[j]][k]; } else if (maxind[k] < ndindex[tri[j]][k]) { @@ -2281,16 +2354,17 @@ BackgroundMesh::gridFSI(ID& freenodes) if (findex.size() == tri.size()) { VInt currind(ndm); if (ndm == 2) { - for (int j=minind[0]; j::iterator it = bcells.find(currind); + std::map::iterator it = + bcells.find(currind); if (it == bcells.end()) { outside = true; break; } else { - if (it->second.type == FLUID) { + if (it->second.getType() == BACKGROUND_FLUID) { outside = true; break; } @@ -2299,18 +2373,20 @@ BackgroundMesh::gridFSI(ID& freenodes) } } } else if (ndm == 3) { - for (int j=minind[0]; j::iterator it = bcells.find(currind); + std::map::iterator it = + bcells.find(currind); if (it == bcells.end()) { outside = true; break; } else { - if (it->second.type == FLUID) { + if (it->second.getType() == + BACKGROUND_FLUID) { outside = true; break; } @@ -2325,114 +2401,64 @@ BackgroundMesh::gridFSI(ID& freenodes) // point coordinates VVDouble ptcrds(tri.size()); - for (int j=0; j<(int)tri.size(); ++j) { + for (int j = 0; j < (int)tri.size(); ++j) { ptcrds[j].resize(ndm); int mark; if (ndm == 2) { gen.getPoint(tri[j], ptcrds[j][0], ptcrds[j][1], mark); } else if (ndm == 3) { - tetgen.getPoint(tri[j], ptcrds[j][0], ptcrds[j][1], ptcrds[j][2], mark); + tetgen.getPoint(tri[j], ptcrds[j][0], ptcrds[j][1], + ptcrds[j][2], mark); } } // gather particles VParticle tripts; - if (fsiTri) { - std::set partindices; - for (int j=0; j<(int)tri.size(); ++j) { - VInt ind = ndindex[tri[j]]; - ind -= 1; - VVInt indices; - getCorners(ind, 1, 1, indices); - for (int k=0; k<(int)indices.size(); ++k) { - partindices.insert(indices[k]); - } - } - for (std::set::iterator it=partindices.begin(); - it!=partindices.end(); ++it) { - VInt ind = *it; - std::map::iterator cellit = bcells.find(ind); + for (int j = 0; j < (int)findex.size(); ++j) { + VInt ind = findex[j]; + ind -= 1; + VVInt indices; + getCorners(ind, 1, indices); + for (int k = 0; k < (int)indices.size(); ++k) { + std::map::iterator cellit = + bcells.find(indices[k]); if (cellit == bcells.end()) continue; - const VParticle& pts = cellit->second.pts; - if (pts.empty()) continue; + if (cellit->second.getType() == BACKGROUND_STRUCTURE) + continue; + if (cellit->second.getPts().empty()) continue; + const VParticle& pts = cellit->second.getPts(); tripts.insert(tripts.end(), pts.begin(), pts.end()); } - } else { - for (int j = 0; j < (int) findex.size(); ++j) { - VInt ind = findex[j]; - ind -= 1; - VVInt indices; - getCorners(ind, 1, 1, indices); - for (int k = 0; k < (int) indices.size(); ++k) { - std::map::iterator cellit = bcells.find(indices[k]); - if (cellit == bcells.end()) continue; - if (cellit->second.type == STRUCTURE) continue; - if (cellit->second.pts.empty()) continue; - const VParticle &pts = cellit->second.pts; - tripts.insert(tripts.end(), pts.begin(), pts.end()); - } - } } + if (tripts.empty()) { - // set free surface - for (int j=0; j<(int)tri.size(); ++j) { - ndfree[tri[j]] = 1; - } continue; } // in-element check - VDouble coeff; - VVDouble tetcoeff; bool zerovol = false; if (ndm == 2) { - if (preNForTri(ptcrds[0][0],ptcrds[0][1], - ptcrds[1][0],ptcrds[1][1], - ptcrds[2][0],ptcrds[2][1], - coeff) < 0) { - zerovol = true; - } - } else if (ndm == 3) { - if (preNForTet(ptcrds[0],ptcrds[1],ptcrds[2],ptcrds[3], - tetcoeff) < 0) { - zerovol = true; - } + check_area(ptcrds[0], ptcrds[1], ptcrds[2]); + } else { + check_vol(ptcrds[0], ptcrds[1], ptcrds[2], ptcrds[3]); } - if (zerovol) { continue; } VParticle newtripts; - if (fsiTri) { - for (int j = 0; j < (int) tripts.size(); ++j) { - - // get shape function - const VDouble &pcrds = tripts[j]->getCrds(); - VDouble N; - if (ndm == 2) { - getNForTri(coeff, pcrds[0], pcrds[1], N); - } else if (ndm == 3) { - getNForTet(tetcoeff, pcrds, N); - } - if (inEle(N)) { - // in tri - newtripts.push_back(tripts[j]); - } - } - } else { - newtripts = tripts; - } + newtripts = tripts; if (newtripts.empty()) continue; // find the group of this mesh - std::map numpts; - for (int j=0; j<(int)newtripts.size(); ++j) { + std::map numpts; + for (int j = 0; j < (int)newtripts.size(); ++j) { numpts[newtripts[j]->getGroupTag()] += 1; } - int num=0; - for (std::map::iterator it=numpts.begin(); it!=numpts.end(); ++it) { + int num = 0; + for (std::map::iterator it = numpts.begin(); + it != numpts.end(); ++it) { if (num < it->second) { num = it->second; gtags[i] = it->first; @@ -2441,27 +2467,18 @@ BackgroundMesh::gridFSI(ID& freenodes) // add to elenodes elends[i].resize(tri.size()); - for (int j=0; j<(int)tri.size(); ++j) { + for (int j = 0; j < (int)tri.size(); ++j) { elends[i][j] = ndtags[tri[j]]; } } - // get free surface nodes - freenodes = ID(); - for (int i=0; i<(int)ndtags.size(); ++i) { - if (ndfree[i] == 1 && ndtypes[i] == FLUID) { - freenodes.insert(ndtags[i]); - } - } - // get particle group tags - std::map elenodes; + std::map elenodes; int nextEletag = Mesh::nextEleTag(); VInt oldContactEles = contactEles; VInt removedEles(oldContactEles.size(), 1); contactEles.clear(); - for (int i=0; i<(int)elends.size(); ++i) { - + for (int i = 0; i < (int)elends.size(); ++i) { // no elenodes, no element if (elends[i].empty()) continue; @@ -2469,13 +2486,14 @@ BackgroundMesh::gridFSI(ID& freenodes) if (gtags[i] == contact_tag) { if (ndm == 2) { if (elends[i].size() != 3) { - opserr << "WARNING: 2D contact should have 3 nodes\n"; + opserr << "WARNING: 2D contact should have 3 " + "nodes\n"; return -1; } // check if exists bool created = false; - for (int j = 0; j < (int) oldContactEles.size(); ++j) { + for (int j = 0; j < (int)oldContactEles.size(); ++j) { if (removedEles[j] == 0) continue; Element* ele = domain->getElement(oldContactEles[j]); if (ele == 0) continue; @@ -2491,25 +2509,28 @@ BackgroundMesh::gridFSI(ID& freenodes) } if (created) continue; - if (contactData[0]<=0 || contactData[1]<=0 || - contactData[2]<0 || contactData[3]<0 || - contactData[4]<=0 || contactData[6]<=0 || - contactData[7]<=0) { - opserr << "WARNING: contact data is not correctly set\n"; + if (contactData[0] <= 0 || contactData[1] <= 0 || + contactData[2] < 0 || contactData[3] < 0 || + contactData[4] <= 0 || contactData[6] <= 0 || + contactData[7] <= 0) { + opserr << "WARNING: contact data is not " + "correctly " + "set\n"; return -1; } - Element *ele = new PFEMContact2D(nextEletag, elends[i][0], - elends[i][1], elends[i][2], - contactData[0], contactData[1], - contactData[2], contactData[3], - contactData[4], contactData[5], - contactData[6], contactData[7]); + Element* ele = new PFEMContact2D( + nextEletag, elends[i][0], elends[i][1], elends[i][2], + contactData[0], contactData[1], contactData[2], + contactData[3], contactData[4], contactData[5], + contactData[6], contactData[7]); if (ele == 0) { - opserr << "WARNING: failed to create contact element\n"; + opserr << "WARNING: failed to create contact " + "element\n"; return -1; } if (domain->addElement(ele) == false) { - opserr << "WARNING: failed to add element " << nextEletag << "\n"; + opserr << "WARNING: failed to add element " + << nextEletag << "\n"; delete ele; return -1; } @@ -2518,27 +2539,29 @@ BackgroundMesh::gridFSI(ID& freenodes) } else if (ndm == 3) { if (elends[i].size() != 4) { - opserr << "WARNING: 3D contact should have 4 nodes\n"; + opserr << "WARNING: 3D contact should have 4 " + "nodes\n"; return -1; } - opserr << "WARNING: 3D contact element hasn't been developed\n"; + opserr << "WARNING: 3D contact element hasn't been " + "developed\n"; } continue; } // if all nodes are fluid and fixed nodes ID& nds = elenodes[gtags[i]]; - for (int j=0; j<(int)elends[i].size(); ++j) { + for (int j = 0; j < (int)elends[i].size(); ++j) { nds[nds.Size()] = elends[i][j]; } } // remove old contact elements - for (int i = 0; i < (int) oldContactEles.size(); ++i) { + for (int i = 0; i < (int)oldContactEles.size(); ++i) { if (removedEles[i] == 1) { - opserr<<"old contact element "<removeElement(oldContactEles[i]); - opserr<getExternalNodes()<<" is removed\n"; + opserr << "old contact element " << oldContactEles[i] << ": "; + Element* ele = domain->removeElement(oldContactEles[i]); + opserr << ele->getExternalNodes() << " is removed\n"; if (ele != 0) { delete ele; } @@ -2546,226 +2569,20 @@ BackgroundMesh::gridFSI(ID& freenodes) } // create elements - for (std::map::iterator it=elenodes.begin(); it!=elenodes.end(); ++it) { - ParticleGroup* group = dynamic_cast(OPS_getMesh(it->first)); + for (std::map::iterator it = elenodes.begin(); + it != elenodes.end(); ++it) { + ParticleGroup* group = + dynamic_cast(OPS_getMesh(it->first)); if (group == 0) { - opserr << "WARNING: failed to get particle group -- BgMesh::gridFSI\n"; + opserr << "WARNING: failed to get particle group -- " + "BgMesh::gridFSI\n"; return -1; } group->addEleNodes(it->second); if (group->newElements(it->second) < 0) { opserr << "WARNING: failed to create elements for mesh "; - opserr << group->getTag()<<" -- BgMesh::gridFSI\n"; - return -1; - } - } - - return 0; -} - -int -BackgroundMesh::gridEles() -{ - Domain* domain = OPS_GetDomain(); - if (domain == 0) return 0; - int ndm = OPS_GetNDM(); - - TriangleMeshGenerator gen; - TetMeshGenerator tetgen; - - // add points - VInt ndtags; - ndtags.reserve(bnodes.size()*1.05); - for (std::map::iterator it=bnodes.begin(); it!=bnodes.end(); ++it) { - BNode& bnode = it->second; - for (int i=0; i<(int)bnode.crdsn.size(); ++i) { - ndtags.push_back(bnode.tags[i]); - if (ndm == 2) { - gen.addPoint(bnode.crdsn[i][0],bnode.crdsn[i][1]); - } else if (ndm == 3) { - tetgen.addPoint(bnode.crdsn[i][0],bnode.crdsn[i][1],bnode.crdsn[i][2],0); - } - } - } - - // mesh - if (ndm == 2) { - gen.remesh(-1.0); - } else if (ndm == 3) { - tetgen.remesh(-1.0); - } - - // get triangles or tetrahedrons - int numele = 0; - if (ndm == 2) { - numele = gen.getNumTriangles(); - } else if (ndm == 3) { - numele = tetgen.getNumTets(); - } - - VVInt elends(numele); - VInt gtags(numele); -#pragma omp parallel for - for (int i=0; i 3) { - large = true; - break; - } - } - if (large) break; - } - if (large) break; - } - if (large) { - continue; - } - - // precalculate shape functions - VDouble coeff; - VVDouble tetcoeff; - bool zerovol = false; - if (ndm == 2) { - if (preNForTri(ptcrds[0][0],ptcrds[0][1], - ptcrds[1][0],ptcrds[1][1], - ptcrds[2][0],ptcrds[2][1], - coeff) < 0) { - zerovol = true; - } - } else if (ndm == 3) { - if (preNForTet(ptcrds[0],ptcrds[1],ptcrds[2],ptcrds[3], - tetcoeff) < 0) { - zerovol = true; - } - } - - // zero volumne, no element - if (zerovol) { - continue; - } - - // get index range and point crds - VInt minind, maxind; - for (int j=0; j<(int)tri.size(); ++j) { - VInt low, up; - lowerIndex(ptcrds[j], low); - upperIndex(ptcrds[j], up); - if (minind.empty()) minind = low; - if (maxind.empty()) maxind = up; - for (int k=0; k low[k]) { - minind[k] = low[k]; - } - if (maxind[k] < up[k]) { - maxind[k] = up[k]; - } - } - } - - // get particles - VParticle pts; - gatherParticles(minind,maxind,pts); - - // check which particles are in the triangle - VParticle tripts; - for (int j=0; j<(int)pts.size(); ++j) { - - // get shape function - const VDouble& pcrds = pts[j]->getCrds(); - VDouble N; - if (ndm == 2) { - getNForTri(coeff,pcrds[0],pcrds[1],N); - } else if (ndm == 3) { - getNForTet(tetcoeff,pcrds,N); - } - if (inEle(N)) { - // in tri - tripts.push_back(pts[j]); - } - } - - // no particles, no element - if (tripts.empty()) continue; - - // find the group of this mesh - std::map numpts; - for (int j=0; j<(int)tripts.size(); ++j) { - numpts[tripts[j]->getGroupTag()] += 1; - } - int num=0; - for (std::map::iterator it=numpts.begin(); it!=numpts.end(); ++it) { - if (num < it->second) { - num = it->second; - gtags[i] = it->first; - } - } - - // add to elenodes - elends[i].resize(tri.size()); - for (int j=0; j<(int)tri.size(); ++j) { - elends[i][j] = ndtags[tri[j]]; - } - } - - // get particle group tags - std::map elenodes; - for (int i=0; i<(int)elends.size(); ++i) { - - // no elenodes, no element - if (elends[i].empty()) continue; - - // if all nodes are fluid and fixed nodes - ID& nds = elenodes[gtags[i]]; - for (int j=0; j<(int)elends[i].size(); ++j) { - nds[nds.Size()] = elends[i][j]; - } - } - - // create elements - for (std::map::iterator it=elenodes.begin(); it!=elenodes.end(); ++it) { - ParticleGroup* group = dynamic_cast(OPS_getMesh(it->first)); - if (group == 0) { - opserr << "WARNING: failed to get particle group -- BgMesh::gridEles\n"; - return -1; - } - group->setEleNodes(it->second); - - if (group->newElements(it->second) < 0) { - opserr << "WARNING: failed to create elements for mesh "; - opserr << group->getTag()<<" -- BgMesh::gridEles\n"; + opserr << group->getTag() << " -- BgMesh::gridFSI\n"; return -1; } } @@ -2776,10 +2593,7 @@ BackgroundMesh::gridEles() // time, vx, vy, (vz), top, bottom, left, right, dt, numIter // -int -BackgroundMesh::record(bool init) -{ - +int BackgroundMesh::record(bool init) { Domain* domain = OPS_GetDomain(); if (domain == 0) return 0; int ndm = OPS_GetNDM(); @@ -2788,10 +2602,12 @@ BackgroundMesh::record(bool init) currentTime = timestamp; // record - for (int i=0; i<(int)recorders.size(); ++i) { + for (int i = 0; i < (int)recorders.size(); ++i) { if (recorders[i] != 0) { - if (recorders[i]->record(domain->getCommitTag(),currentTime)) { - opserr << "WARNING: failed to record -- BgMesh::gridEles\n"; + if (recorders[i]->record(domain->getCommitTag(), + currentTime)) { + opserr << "WARNING: failed to record -- " + "BgMesh::gridEles\n"; return -1; } } @@ -2801,38 +2617,32 @@ BackgroundMesh::record(bool init) } // record time - if(theFile.good() == false) { + if (theFile.good() == false) { return 0; } theFile << timestamp << " "; // record wave height and velocity - for (int i=0; i<(int)locs.size(); i+=ndm) { - + for (int i = 0; i < (int)locs.size(); i += ndm) { // lower index VDouble crds(ndm); for (int j = 0; j < ndm; ++j) { - crds[j] = locs[i+j]; + crds[j] = locs[i + j]; } VInt index; - this->lowerIndex(crds,index); - - std::map::iterator it = bcells.find(index); - int level = 1; - if (it != bcells.end()) { - level = it->second.sizeLevel; - } + this->lowerIndex(crds, index); // shape function VDouble N; - double hh = bsize * level; + double hh = bsize; if (ndm == 2) { - getNForRect(index[0] * bsize, index[1] * bsize, - hh, hh, crds[0], crds[1], N); + getNForRect(index[0] * bsize, index[1] * bsize, hh, hh, + crds[0], crds[1], N); } else if (ndm == 3) { - getNForRect(index[0] * bsize, index[1] * bsize, index[2] * bsize, - hh, hh, hh, crds[0], crds[1], crds[2], N); + getNForRect(index[0] * bsize, index[1] * bsize, + index[2] * bsize, hh, hh, hh, crds[0], crds[1], + crds[2], N); } // velocity @@ -2840,73 +2650,81 @@ BackgroundMesh::record(bool init) // get corners VVInt indices; - getCorners(index,1,level,indices); - for (int k=0; k<(int)indices.size(); ++k) { - + getCorners(index, 1, indices); + for (int k = 0; k < (int)indices.size(); ++k) { // get crds getCrds(indices[k], crds); // check bnode - std::map::iterator bit = bnodes.find(indices[k]); + std::map::iterator bit = bnodes.find(indices[k]); if (bit == bnodes.end()) continue; // get bnode BNode& bnode = bit->second; - if (bnode.vn.empty()) { + auto& vn = bnode.getVel(); + if (vn.empty()) { continue; } // get vel for (int j = 0; j < ndm; ++j) { - vel[j] += N[k]*bnode.vn[0][j]; + vel[j] += N[k] * vn[0][j]; } } // get the lowest cell double bottom = 0.0; - for (int iy=lower[1]; iy<=upper[1]; ++iy) { + for (int iy = lower[1]; iy <= upper[1]; ++iy) { VInt ind = index; ind[1] = iy; - if (bcells.find(ind) != bcells.end()) { - bottom = iy*bsize; + auto it = bcells.find(ind); + if (it != bcells.end() && + it->second.getPts().empty() == false) { + bottom = iy * bsize + 0.5 * bsize; break; } } // get the most left cell double left = 0.0; - for (int ix=lower[0]; ix<=upper[0]; ++ix) { + for (int ix = lower[0]; ix <= upper[0]; ++ix) { VInt ind = index; ind[0] = ix; - if (bcells.find(ind) != bcells.end()) { - left = ix*bsize; + auto it = bcells.find(ind); + if (it != bcells.end() && + it->second.getPts().empty() == false) { + left = ix * bsize + 0.5 * bsize; break; } } // get the highest cell double top = 0.0; - for (int iy=upper[1]; iy>=lower[1]; --iy) { + for (int iy = upper[1]; iy >= lower[1]; --iy) { VInt ind = index; ind[1] = iy; - if (bcells.find(ind) != bcells.end()) { - top = (iy+1)*bsize; + auto it = bcells.find(ind); + if (it != bcells.end() && + it->second.getPts().empty() == false) { + top = (iy + 0.5) * bsize; break; } } // get the most right cell double right = 0.0; - for (int ix=upper[0]; ix>=lower[0]; --ix) { + for (int ix = upper[0]; ix >= lower[0]; --ix) { VInt ind = index; ind[0] = ix; - if (bcells.find(ind) != bcells.end()) { - right = (ix+1)*bsize; + auto it = bcells.find(ind); + if (it != bcells.end() && + it->second.getPts().empty() == false) { + right = (ix + 0.5) * bsize; break; } } // record velocity and wave - for (int j=0; jgetCurrentTime() - currentTime; // get current disp and velocity - for (std::map::iterator it=bnodes.begin(); it!=bnodes.end(); ++it) { + for (std::map::iterator it = bnodes.begin(); + it != bnodes.end(); ++it) { BNode& bnode = it->second; - VInt& tags = bnode.tags; + VInt& tags = bnode.getTags(); - for (int i=0; i<(int)bnode.size(); ++i) { + for (int i = 0; i < (int)bnode.size(); ++i) { Node* nd = domain->getNode(tags[i]); - Pressure_Constraint* pc = domain->getPressure_Constraint(tags[i]); + Pressure_Constraint* pc = + domain->getPressure_Constraint(tags[i]); if (pc != 0) { - bnode.pn[i] = pc->getPressure(); - bnode.dpn[i] = pc->getPdot(); + auto& pn = bnode.getPressure(); + auto& dpn = bnode.getPdot(); + pn[i] = pc->getPressure(); + dpn[i] = pc->getPdot(); } if (nd != 0) { const Vector& vel = nd->getTrialVel(); const Vector& accel = nd->getTrialAccel(); - for (int j=0; j::iterator it=bcells.begin(); it!=bcells.end(); ++it) { + for (std::map::iterator it = bcells.begin(); + it != bcells.end(); ++it) { indices.push_back(it->first); cells.push_back(&(it->second)); } @@ -2967,21 +2789,18 @@ BackgroundMesh::moveParticles() // move particles in each cell int res = 0; #pragma omp parallel for - for (int j=0; j<(int)cells.size(); ++j) { - + for (int j = 0; j < (int)cells.size(); ++j) { // get particles in cell - const VParticle& pts = cells[j]->pts; - int level = cells[j]->sizeLevel; + const VParticle& pts = cells[j]->getPts(); // move the particle - for (int i=0; i<(int)pts.size(); ++i) { - + for (int i = 0; i < (int)pts.size(); ++i) { // set update state if (pts[i] == 0) continue; pts[i]->needUpdate(dt); // convect the particle - if (convectParticle(pts[i],indices[j],level,numsub) < 0) { + if (convectParticle(pts[i], indices[j], numsub) < 0) { opserr << "WARNING: failed to convect particle"; opserr << " -- BgMesh::moveParticles\n"; res = -1; @@ -2995,10 +2814,7 @@ BackgroundMesh::moveParticles() return 0; } -int -BackgroundMesh::convectParticle(Particle* pt, VInt index, int level, int nums) -{ - +int BackgroundMesh::convectParticle(Particle* pt, VInt index, int nums) { Domain* domain = OPS_GetDomain(); if (domain == 0) return 0; @@ -3013,8 +2829,8 @@ BackgroundMesh::convectParticle(Particle* pt, VInt index, int level, int nums) // get corners VVInt indices, ndtags; VVDouble crds; - VInt fixed; - VVDouble vels, dvns, incrvels; + std::vector types; + VVDouble vels, dvns; VDouble pns, dpns; // convect in a cell @@ -3030,17 +2846,14 @@ BackgroundMesh::convectParticle(Particle* pt, VInt index, int level, int nums) // new index VInt newIndex; - lowerIndex(pcrds,newIndex); - - int newlevel = getSizeLevel(newIndex); + lowerIndex(pcrds, newIndex); // update corners if (indices.empty() || newIndex != index) { index = newIndex; - level = newlevel; VVInt temp; - getCorners(index,1,level,temp); + getCorners(index, 1, temp); indices = temp; indices[2] = temp[3]; indices[3] = temp[2]; @@ -3049,61 +2862,54 @@ BackgroundMesh::convectParticle(Particle* pt, VInt index, int level, int nums) indices[7] = temp[6]; } - // get corner coordinates, fixed, and velocities + // get corner coordinates, types, and velocities + // pressures, alphas for structural damping ndtags.assign(indices.size(), VInt()); - crds.assign(indices.size(),VDouble()); - fixed.assign(indices.size(),0); - vels.assign(indices.size(),VDouble()); - incrvels.assign(indices.size(),VDouble()); - dvns.assign(indices.size(),VDouble()); + crds.assign(indices.size(), VDouble()); + types.assign(indices.size(), BACKGROUND_FIXED); + vels.assign(indices.size(), VDouble()); + dvns.assign(indices.size(), VDouble()); pns.assign(indices.size(), 0.0); dpns.assign(indices.size(), 0.0); - for (int i=0; i<(int)indices.size(); ++i) { - + for (int i = 0; i < (int)indices.size(); ++i) { // get crds getCrds(indices[i], crds[i]); // check bnode - std::map::iterator it = bnodes.find(indices[i]); + auto it = bnodes.find(indices[i]); if (it == bnodes.end()) continue; // get bnode BNode& bnode = it->second; - if (bnode.type == FIXED) continue; + types[i] = bnode.getType(); + if (types[i] == BACKGROUND_FIXED) continue; // get node tags - ndtags[i] = bnode.tags; - - // get fixed - for (int j=0; j<(int)bnode.size(); ++j) { - if (bnode.type == FLUID) { - fixed[i] = 0; - break; - } else if (bnode.type == STRUCTURE) { - fixed[i] = 1; - break; - } - } + ndtags[i] = bnode.getTags(); // get vn and dvn - if (bnode.tags.size() < 1) { + if (bnode.getTags().size() < 1) { opserr << "WARNING: fluid bnode tags.size() < 1 "; opserr << "-- BgMesh::convectParticle\n"; return -1; } - vels[i] = bnode.vn[0]; - incrvels[i] = bnode.incrv[0]; - dvns[i] = bnode.dvn[0]; - pns[i] = bnode.pn[0]; - dpns[i] = bnode.dpn[0]; + auto& vn = bnode.getVel(); + auto& dvn = bnode.getAccel(); + auto& pn = bnode.getPressure(); + auto& dpn = bnode.getPdot(); + vels[i] = vn[0]; + dvns[i] = dvn[0]; + pns[i] = pn[0]; + dpns[i] = dpn[0]; } } // get particle velocity and move - if (interpolate(pt,indices,vels,incrvels,dvns,pns, - dpns,crds,fixed,ndtags,subdt) < 0) { - opserr << "WARNING: failed to interpolate particle velocity"; + if (interpolate(pt, indices, vels, dvns, pns, dpns, crds, types, + ndtags, subdt) < 0) { + opserr << "WARNING: failed to interpolate particle " + "velocity"; opserr << "-- BgMesh::convectParticle\n"; return -1; } @@ -3112,15 +2918,12 @@ BackgroundMesh::convectParticle(Particle* pt, VInt index, int level, int nums) return 0; } -int -BackgroundMesh::interpolate(Particle* pt, const VVInt& index, - const VVDouble& vels, const VVDouble& incrvels, - const VVDouble& dvns, - const VDouble& pns, const VDouble& dpns, - const VVDouble& crds, - const VInt& fixed, const VVInt& ndtags, - double dt) -{ +int BackgroundMesh::interpolate(Particle* pt, const VVInt& index, + const VVDouble& vels, const VVDouble& dvns, + const VDouble& pns, const VDouble& dpns, + const VVDouble& crds, + const std::vector& types, + const VVInt& ndtags, double dt) { int ndm = OPS_GetNDM(); Domain* domain = OPS_GetDomain(); if (domain == 0) return 0; @@ -3129,65 +2932,142 @@ BackgroundMesh::interpolate(Particle* pt, const VVInt& index, if (ndm == 2) { if (index.size() != 4) return 0; if (vels.size() != 4) return 0; - if (incrvels.size() != 4) return 0; if (pns.size() != 4) return 0; if (dpns.size() != 4) return 0; if (crds.size() != 4) return 0; - if (fixed.size() != 4) return 0; + if (types.size() != 4) return 0; } else if (ndm == 3) { if (index.size() != 8) return 0; if (vels.size() != 8) return 0; - if (incrvels.size() != 8) return 0; if (pns.size() != 8) return 0; if (dpns.size() != 8) return 0; if (crds.size() != 8) return 0; - if (fixed.size() != 8) return 0; + if (types.size() != 8) return 0; } const VDouble& pcrds = pt->getCrds(); if ((int)pcrds.size() != ndm) { - opserr << "WARNING: pcrds.size() != ndm -- BgMesh::interpolate\n"; + opserr << "WARNING: pcrds.size() != ndm -- " + "BgMesh::interpolate\n"; return -1; } // get shape functions for pt VDouble N; if (ndm == 2) { - double hx = (crds[1][0]+crds[2][0])/2.0-crds[0][0]; - double hy = (crds[2][1]+crds[3][1])/2.0-crds[0][1]; + double hx = (crds[1][0] + crds[2][0]) / 2.0 - crds[0][0]; + double hy = (crds[2][1] + crds[3][1]) / 2.0 - crds[0][1]; getNForRect(crds[0][0], crds[0][1], hx, hy, pcrds[0], pcrds[1], N); } else if (ndm == 3) { - double hx = (crds[1][0]+crds[2][0])/2.0-crds[0][0]; - double hy = (crds[2][1]+crds[3][1])/2.0-crds[0][1]; - double hz = (crds[4][2]+crds[5][2]+crds[6][2]+crds[7][2])/4.0-crds[0][2]; - getNForRect(crds[0][0],crds[0][1],crds[0][2], - hx,hy,hz,pcrds[0],pcrds[1],pcrds[2],N); + double hx = (crds[1][0] + crds[2][0]) / 2.0 - crds[0][0]; + double hy = (crds[2][1] + crds[3][1]) / 2.0 - crds[0][1]; + double hz = + (crds[4][2] + crds[5][2] + crds[6][2] + crds[7][2]) / 4.0 - + crds[0][2]; + getNForRect(crds[0][0], crds[0][1], crds[0][2], hx, hy, hz, + pcrds[0], pcrds[1], pcrds[2], N); } // particle velocity VDouble pvel(ndm); - VDouble pdvn(ndm), incrpvel(ndm); - double ppre=0.0, pdp=0.0; + VDouble pdvn(ndm); + double ppre = 0.0, pdp = 0.0; double Nvsum = 0.0, Npsum = 0.0; - for (int j=0; j<(int)vels.size(); ++j) { - + for (int j = 0; j < (int)vels.size(); ++j) { // no vel at this corner if (vels[j].empty()) continue; // interpolate - if (fixed[j] == 0) { - for (int k=0; ksecond.size(); + } + for (int i = 0; i < size; ++i) { + auto& v = it->second.getVel(); + svel += v[i]; + ++num_svel; + + auto& sid = it->second.getSid(); + auto it_alpha = alphaS.find(sid[i]); + if (it_alpha != alphaS.end()) { + alphas += it_alpha->second; + ++num_sid; + } + } + } + if (num_svel > 0) { + svel /= num_svel; + } + if (num_sid > 0) { + alphas /= num_sid; + } + + // check surrounding cells + getCorners(ind, 1, indices); + VVInt sindices; + for (int k = 0; k < (int)indices.size(); ++k) { + auto it = bcells.find(indices[k]); + if (it != bcells.end() && + it->second.getType() == BACKGROUND_STRUCTURE) { + sindices.push_back(indices[k]); + } + } + VInt num_equal(ndm); + for (int k = 0; k < ndm; ++k) { + for (int m = 0; m < (int)sindices.size(); ++m) { + int num = 0; + for (int n = 0; n < (int)sindices.size(); ++n) { + if (sindices[m][k] == sindices[n][k]) { + num += 1; + } + } + if (num_equal[k] < num) { + num_equal[k] = num; + } + } + } + + // interpolate + for (int k = 0; k < ndm; ++k) { + bool fixk = (ndm == 2 && num_equal[k] >= 2) || + (ndm == 3 && num_equal[k] >= 4); + if (num_svel > 0 && fixk && fabs(svel[k]) < tol) { + // k is fixed structure + pvel[k] += N[j] * svel[k]; + } else if (num_svel > 0 && + fabs(svel[k]) > fabs(vels[j][k])) { + // k is faster structure + pvel[k] += N[j] * svel[k]; + } else if (num_svel > 0 && + fabs(svel[k]) < fabs(vels[j][k])) { + // k is slower structure + pvel[k] += N[j] * (alphas * svel[k] + + (1.0 - alphas) * vels[j][k]); + } else { + // all others + pvel[k] += N[j] * vels[j][k]; + } if (pt->isUpdated() == false) { - pdvn[k] += N[j]*dvns[j][k]; + pdvn[k] += N[j] * dvns[j][k]; } } Nvsum += N[j]; } if (pt->isUpdated() == false) { - ppre += N[j]*pns[j]; - pdp += N[j]*dpns[j]; + ppre += N[j] * pns[j]; + pdp += N[j] * dpns[j]; } Npsum += N[j]; } @@ -3228,39 +3108,35 @@ BackgroundMesh::interpolate(Particle* pt, const VVInt& index, // new particle coordinates newpcrds += pcrds; - // find new cell - VInt newindex; - lowerIndex(newpcrds, newindex); - auto it = bnodes.find(newindex); - - // 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]; - } - } - } - } + // // find new cell + // VInt newindex; + // lowerIndex(newpcrds, newindex); + // auto it = bnodes.find(newindex); + + // // if new cell is structure + // if (it != bnodes.end()) { + // if (it->second.getType() == BACKGROUND_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]; + // } + // } + // } + // } // update particle if (pt->isUpdated() == false) { - if (incrVel) { - pt->incrVel(incrpvel); - } else { - pt->setVel(pvel); - } + pt->setVel(pvel); pt->setAccel(pdvn); pt->setPressure(ppre); pt->setPdot(pdp); @@ -3272,82 +3148,11 @@ BackgroundMesh::interpolate(Particle* pt, const VVInt& index, return 0; } -int -BackgroundMesh::findFreeSurface(const ID& freenodes) -{ - // quick return - if (!freesurface) return 0; - - // get domain - Domain* domain = OPS_GetDomain(); - if (domain == 0) return -1; - - // for all fluid nodes - for (std::map::iterator it=bnodes.begin(); it!=bnodes.end(); ++it) { - - // check if fluid - VInt index = it->first; - BNode& bnode = it->second; - if (bnode.tags.size() != 1) { - continue; - } - if (bnode.type != FLUID) { - continue; - } - - // get neighbors corners - index -= 1; - VVInt indices; - getCorners(index,1,1,indices); - bool free = false; - for (int i=0; i<(int)indices.size(); ++i) { - std::map::iterator it2 = bcells.find(indices[i]); - if (it2 == bcells.end()) { - free = true; - break; - } - if (it2->second.type != FLUID) continue; - if (it2->second.pts.empty()) { - free = true; - break; - } - } - - // set free surface - if (free) { - int ndtag = bnode.tags[0]; - Pressure_Constraint* pc = domain->getPressure_Constraint(ndtag); - if (pc == 0) { - opserr << "WARNING: node "<setFreeSurf(); - } - } - - // for all fsi nodes on free surface - for (int i=0; igetPressure_Constraint(ndtag); - if (pc == 0) { - opserr << "WARNING: node "<setFreeSurf(); - } - - return 0; -} - -int -BackgroundMesh::interpolate(const VVDouble& values, const VDouble& N, VDouble& newvalue) -{ +int BackgroundMesh::interpolate(const VVDouble& values, const VDouble& N, + VDouble& newvalue) { if (N.size() != values.size()) { - opserr << "WARNING: sizes of shape function and nodal values don't match\n"; + opserr << "WARNING: sizes of shape function and nodal values " + "don't match\n"; return -1; } if (N.empty()) { @@ -3361,9 +3166,10 @@ BackgroundMesh::interpolate(const VVDouble& values, const VDouble& N, VDouble& n VDouble temp(values[0].size()); newvalue.assign(values[0].size(), 0.0); - for (int i = 0; i < (int) N.size(); ++i) { + for (int i = 0; i < (int)N.size(); ++i) { if (values[i].size() != values[0].size()) { - opserr << "WARNING: dimensions of nodal values are different\n"; + opserr << "WARNING: dimensions of nodal values are " + "different\n"; newvalue.clear(); return -1; } @@ -3374,11 +3180,11 @@ BackgroundMesh::interpolate(const VVDouble& values, const VDouble& N, VDouble& n return 0; } -int -BackgroundMesh::interpolate(const VDouble& values, const VDouble& N, double& newvalue) -{ +int BackgroundMesh::interpolate(const VDouble& values, const VDouble& N, + double& newvalue) { if (N.size() != values.size()) { - opserr << "WARNING: sizes of shape function and nodal values don't match\n"; + opserr << "WARNING: sizes of shape function and nodal values " + "don't match\n"; return -1; } if (N.empty()) { @@ -3387,15 +3193,14 @@ BackgroundMesh::interpolate(const VDouble& values, const VDouble& N, double& new } newvalue = 0.0; - for (int i = 0; i < (int) N.size(); ++i) { + for (int i = 0; i < (int)N.size(); ++i) { newvalue += values[i] * N[i]; } return 0; } -int -BackgroundMesh::createContact(const VInt& ndtags, const VInt& sids, VInt& elends) -{ +int BackgroundMesh::createContact(const VInt& ndtags, const VInt& sids, + VInt& elends) { // check inputs int ndm = OPS_GetNDM(); if (ndtags.size() != sids.size()) { @@ -3413,10 +3218,9 @@ BackgroundMesh::createContact(const VInt& ndtags, const VInt& sids, VInt& elends } } - // get groups std::map grp; - for (int i = 0; i < (int) sids.size(); ++i) { + for (int i = 0; i < (int)sids.size(); ++i) { grp[sids[i]].push_back(ndtags[i]); } @@ -3429,8 +3233,8 @@ BackgroundMesh::createContact(const VInt& ndtags, const VInt& sids, VInt& elends int secondary = 0; int id = 0; bool find = false; - for (std::map::iterator it=grp.begin(); - it!=grp.end(); ++it) { + for (std::map::iterator it = grp.begin(); it != grp.end(); + ++it) { VInt& nds = it->second; if (nds.size() == 1) { // secondary node with largest sid @@ -3448,10 +3252,10 @@ BackgroundMesh::createContact(const VInt& ndtags, const VInt& sids, VInt& elends // index for secondary node int index = 0; - for (int i = 0; i < (int) ndtags.size(); ++i) { + for (int i = 0; i < (int)ndtags.size(); ++i) { if (ndtags[i] == secondary) { index = i + 1; - if (index >= (int) ndtags.size()) { + if (index >= (int)ndtags.size()) { index -= ndtags.size(); } break; @@ -3460,10 +3264,10 @@ BackgroundMesh::createContact(const VInt& ndtags, const VInt& sids, VInt& elends // get primary nodes elends.clear(); - for (int i = 0; i < (int) ndtags.size() - 1; ++i) { + for (int i = 0; i < (int)ndtags.size() - 1; ++i) { elends.push_back(ndtags[index]); index += 1; - if (index >= (int) ndtags.size()) { + if (index >= (int)ndtags.size()) { index -= ndtags.size(); } } @@ -3472,51 +3276,65 @@ BackgroundMesh::createContact(const VInt& ndtags, const VInt& sids, VInt& elends return 0; } -void -BackgroundMesh::setContactData(const VDouble& data) { +void BackgroundMesh::setContactData(const VDouble& data) { contactData = data; } -void -BackgroundMesh::getWall(VDouble& dir, double& dist, const VDouble& xbnd, - const VDouble& ybnd, const VDouble& zbnd, - const VDouble pcrds) -{ - int ndm = OPS_GetNDM(); - - // get line or plane equations - dir.resize(ndm); - if (ndm == 2) { - dir[0] = ybnd[1] - ybnd[0]; - dir[1] = xbnd[0] - xbnd[1]; - } else if (ndm == 3) { - dir[0] = ybnd[0] * zbnd[1] - ybnd[1] * zbnd[0]; - dir[1] = xbnd[1] * zbnd[0] - xbnd[0] * zbnd[1]; - dir[2] = xbnd[0] * ybnd[1] - xbnd[1] * ybnd[0]; +void BackgroundMesh::splitPrism(const VInt& prism, VVInt& tets, bool incl1, + bool incl4) { + if (prism.size() != 6) return; + tets.clear(); + VInt tet(4); + + // first tetehedron + if (incl4) { + tet[0] = prism[3]; + tet[1] = prism[4]; + tet[2] = prism[2]; + tet[3] = prism[5]; + tets.push_back(tet); + } + + // second tetehedron + if (incl1 && incl4) { + tet[0] = prism[3]; + tet[1] = prism[1]; + tet[2] = prism[2]; + tet[3] = prism[4]; + tets.push_back(tet); + } + + // third tetehedron + if (incl1) { + tet[0] = prism[3]; + tet[1] = prism[0]; + tet[2] = prism[2]; + tet[3] = prism[1]; + tets.push_back(tet); } - dir /= normVDouble(dir); +} - VDouble sidedir1 = pcrds; - sidedir1[0] -= xbnd[0]; - sidedir1[1] -= ybnd[0]; - if (ndm == 3) { - sidedir1[2] -= zbnd[0]; - } - if (dotVDouble(sidedir1, dir) > 0) { - dir *= -1.0; +bool BackgroundMesh::check_area(const VDouble& ndcrds1, + const VDouble& ndcrds2, + const VDouble& ndcrds3) { + VDouble coeff; + bool zerovol = false; + if (preNForTri(ndcrds1[0], ndcrds1[1], ndcrds2[0], ndcrds2[1], + ndcrds3[0], ndcrds3[1], coeff) < 0) { + zerovol = true; } + return zerovol; +} - double C = 0.0; - C -= dir[0] * xbnd[0]; - C -= dir[1] * ybnd[0]; - if (ndm == 3) { - C -= dir[2] * zbnd[0]; +bool BackgroundMesh::check_vol(const VDouble& ndcrds1, + const VDouble& ndcrds2, + const VDouble& ndcrds3, + const VDouble& ndcrds4) { + VVDouble coeff; + bool zerovol = false; + if (preNForTet(ndcrds1, ndcrds2, ndcrds3, ndcrds4, coeff) < 0) { + zerovol = true; } - // distance to wall - dist = C; - for (int m = 0; m < ndm; ++m) { - dist += dir[m] * pcrds[m]; - } - dist = fabs(dist); + return zerovol; } diff --git a/SRC/element/PFEMElement/BackgroundMesh.h b/SRC/element/PFEMElement/BackgroundMesh.h index 62edd7821..31fb7bdda 100644 --- a/SRC/element/PFEMElement/BackgroundMesh.h +++ b/SRC/element/PFEMElement/BackgroundMesh.h @@ -30,113 +30,43 @@ #ifndef BackgroundMesh_h #define BackgroundMesh_h -#include "BackgroundDef.h" -#include -#include #include #include #include + #include +#include +#include -class BackgroundMesh -{ -private: - - static int FLUID, STRUCTURE, FIXED; - - // FLUID - a grid fluid node - // STRUCTURE - a structural node - // FIXED - a fixed grid fluid node - struct BNode { - - VInt tags; - VVDouble crdsn; - VVDouble vn; - VVDouble incrv; - VVDouble dvn; - VDouble pn; - VDouble dpn; - int type; - VInt sid; // structure id, <0:fluid, >0:structure, =0:not in contact - - BNode():tags(),crdsn(),vn(),incrv(), dvn(),pn(),dpn(),type(FLUID){} - void addNode(int tag, const VDouble& crds, const VDouble& v, - const VDouble& dv, double p, double dp, int tp, int id=-1) { - tags.push_back(tag); - crdsn.push_back(crds); - vn.push_back(v); - incrv.push_back(v); - dvn.push_back(dv); - pn.push_back(p); - dpn.push_back(dp); - type = tp; - sid.push_back(id); - } - void clear() { - tags.clear(); - crdsn.clear(); - vn.clear(); - incrv.clear(); - dvn.clear(); - pn.clear(); - dpn.clear(); - type = FLUID; - sid.clear(); - } - int size() const {return (int)tags.size();} - - }; - - // FLUID - a grid fluid cell - // STRUCTURE - a structural cell, which should have no particles - struct BCell { - VParticle pts; - int type; - std::vector bnodes; - std::vector bindex; - int sizeLevel; - - BCell():pts(),type(FLUID),bnodes(),bindex(),sizeLevel(0) {} - void add(Particle* pt) {pts.push_back(pt);} - }; - -public: +#include "BCell.h" +#include "BNode.h" +#include "BackgroundDef.h" + +class BackgroundMesh { + public: BackgroundMesh(); virtual ~BackgroundMesh(); // background info - void setTol(double t) {this->tol = t;} - double getTol() const {return this->tol;} - void setMeshTol(double t) {meshtol = t;} - double getMeshTol() const {return meshtol;} + void setTol(double t) { this->tol = t; } + double getTol() const { return this->tol; } void setRange(const VDouble& l, const VDouble& u); - void setBasicSize(double size) {bsize = size; dispon= false;} + void setBasicSize(double size) { bsize = size; } void addRecorder(Recorder* recorder); - int record(bool init=false); - void setLocs(const VDouble& l) {this->locs = l;} + int record(bool init = false); + void setLocs(const VDouble& l) { this->locs = l; } int setFile(const char* name); - void setNumSub(int num) {numsub = num;} + void setNumSub(int num) { numsub = num; } void addStructuralNodes(VInt& snodes, int sid); void setContactData(const VDouble& data); - bool isIncrVel() const { return incrVel;} - void setIncrVel(bool ivel) {incrVel = ivel;} - bool isFSITri() const {return fsiTri;} - void setFSITri(bool fsi) {fsiTri = fsi;} - void setBoundReduceFactor(double factor) {boundReduceFactor = factor;} - void addLargeSize(int numbasic, - const VDouble& range_low, + void addLargeSize(int numbasic, const VDouble& range_low, const VDouble& range_up); - int getSizeLevel(VInt& index); - void setPressureOnce(bool flag) {pressureonce = flag;} - bool isPressureOnce() const {return pressureonce;} - bool isDispOn() const {return dispon;} - void setFastAssembly(bool flag) {fastAssembly = flag;} - bool isFastAssembly() const {return fastAssembly;} - void setKernelClose(bool flag) {kernelClose = flag;} - bool isKernelClose() const {return kernelClose;} + bool isDispOn() const { return dispon; } + void setAlphaS(int sid, double alpha) { alphaS[sid] = alpha; } + void setDispOn(bool on); // remesh all - int remesh(bool init=false); + int remesh(bool init = false); // get grids void getIndex(const VDouble& crds, double incr, VInt& index) const; @@ -144,33 +74,31 @@ class BackgroundMesh void upperIndex(const VDouble& crds, VInt& index) const; void nearIndex(const VDouble& crds, VInt& index) const; void getCrds(const VInt& index, VDouble& crds) const; - void getCorners(const VInt& index, int num, int level, VVInt& indices) const; + void getCorners(const VInt& index, int num, VVInt& indices) const; // particles int addParticles(); void gatherParticles(const VInt& minindex, const VInt& maxindex, - VParticle& pts, bool checkfsi=false); + VParticle& pts, bool checkfsi = false); int moveParticles(); - int convectParticle(Particle* pt, VInt index, int level, int nums); + int convectParticle(Particle* pt, VInt index, int nums); int moveFixedParticles(); - int inlet(); - void addInlet(const VDouble& crds, const VDouble& vel); - void setInletNum(const VInt& num) {inletNum = num;} // create grid nodes and elements int addStructure(); int gridNodes(); int gridFluid(); - int gridFSI(ID& freenodes); + int gridFSI(); + int gridFSInoDT(); int gridEles(); - static int createContact(const VInt& ndtags, const VInt& sids, VInt& elends); + static int createContact(const VInt& ndtags, const VInt& sids, + VInt& elends); // particle kernel static double QuinticKernel(double q, double h, int ndm); static int preNForTri(double x1, double y1, double x2, double y2, double x3, double y3, VDouble& coeff); - void getNForTri(const VDouble& coeff, double x, double y, - VDouble& N); + void getNForTri(const VDouble& coeff, double x, double y, VDouble& N); static void getNForRect(double x0, double y0, double hx, double hy, double x, double y, VDouble& N); @@ -179,11 +107,23 @@ class BackgroundMesh VVDouble& coeff); void getNForTet(const VVDouble& coeff, const VDouble& crds, VDouble& N); - static void getNForRect(double x0, double y0, double z0, - double hx, double hy, double hz, - double x, double y, double z, - VDouble& N); - + static void getNForRect(double x0, double y0, double z0, double hx, + double hy, double hz, double x, double y, + double z, VDouble& N); + static bool check_area(const VDouble& ndcrds1, const VDouble& ndcrds2, + const VDouble& ndcrds3); + static bool check_vol(const VDouble& ndcrds1, const VDouble& ndcrds2, + const VDouble& ndcrds3, const VDouble& ndcrds4); + // 1 + // /\ upper + // 0 / \ 2 + // ------ + // | 4 | + // | /\ | lower + // |/ \| + // 3------5 + static void splitPrism(const VInt& prism, VVInt& tets, bool incl1, + bool incl4); // clear all void clearAll(); @@ -192,55 +132,36 @@ class BackgroundMesh void clearGrid(); // interpolate in a cell - int interpolate(Particle* pt, const VVInt& index, - const VVDouble& vels, const VVDouble& incrvels, - const VVDouble& dvns, - const VDouble& pns, const VDouble& dpns, - const VVDouble& crds, - const VInt& fixed, const VVInt& ndtags, - double dt); - static int interpolate(const VVDouble& values, const VDouble& N, VDouble& newvalue); - static int interpolate(const VDouble& values, const VDouble& N, double& newvalue); - static int solveLine(const VDouble& p1, const VDouble& dir, - int dim, double crd, double& k); + int interpolate(Particle* pt, const VVInt& index, const VVDouble& vels, + const VVDouble& dvns, const VDouble& pns, + const VDouble& dpns, const VVDouble& crds, + const std::vector& types, + const VVInt& ndtags, double dt); + static int interpolate(const VVDouble& values, const VDouble& N, + VDouble& newvalue); + static int interpolate(const VDouble& values, const VDouble& N, + double& newvalue); + static int solveLine(const VDouble& p1, const VDouble& dir, int dim, + double crd, double& k); static bool inEle(const VDouble& N); - // find free surface - int findFreeSurface(const ID& freenodes); - void setFreeSurface() {freesurface = true;} - - // wall - void getWall(VDouble& dir, double& dist, const VDouble& xbnd, - const VDouble& ybnd, const VDouble& zbnd, - const VDouble pcrds); - -private: - + private: VInt lower, upper; - std::map bcells; - std::map bnodes; - double tol, meshtol; + std::map bcells; + std::map bnodes; + double tol; double bsize; int numave, numsub; std::vector recorders; VDouble locs; double currentTime; std::ofstream theFile; - std::map structuralNodes; // >0:structure, <0: fluid, 0:invalid, larger:debris - bool freesurface; + std::map structuralNodes; // >0:structure, <0: fluid, + // 0:invalid, larger:debris VDouble contactData; VInt contactEles; - bool incrVel; - bool fsiTri; // move partiles in fsi area through triangles - double boundReduceFactor; - VVInt inletLoc; - VVDouble inletVel; - VInt inletNum; - VVInt largesize; - bool pressureonce; bool dispon; - bool fastAssembly; - bool kernelClose; + std::map alphaS; // alphaS for sids static const int contact_tag = -13746; }; diff --git a/SRC/element/PFEMElement/Makefile b/SRC/element/PFEMElement/Makefile index 9f30b2785..3a07daa86 100755 --- a/SRC/element/PFEMElement/Makefile +++ b/SRC/element/PFEMElement/Makefile @@ -5,7 +5,7 @@ OBJS = PFEMElement2D.o PFEMElement2DFIC.o PFEMElement3D.o TclModelBuilder_addPFE tetgen.o predicates.o triangle.o PFEMElement2Dmini.o TriangleMeshGenerator.o TetMeshGenerator.o \ BackgroundMesh.o Particle.o ParticleGroup.o BackgroundDef.o TaylorHood2D.o TriGaussPoints.o \ HigherOrder.o MINI.o Mesh.o LineMeshGenerator.o LineMesh.o TriMesh.o TetMesh.o \ - QuadMeshGenerator.o QuadMesh.o PFEMContact2D.o + QuadMeshGenerator.o QuadMesh.o PFEMContact2D.o BNode.o BCell.o all: $(OBJS) diff --git a/SRC/element/PFEMElement/Mesh.cpp b/SRC/element/PFEMElement/Mesh.cpp index 03381277b..44995437f 100644 --- a/SRC/element/PFEMElement/Mesh.cpp +++ b/SRC/element/PFEMElement/Mesh.cpp @@ -318,8 +318,6 @@ Mesh::setEleArgs() { } } else if (strcmp(type, "PFEMElementCompressible") == 0) { - opserr << "WARNING: PFEMElementCompressible needs fix in TriMesh\n"; - return -1; if (ndm == 2) { eleType = ELE_TAG_PFEMElement2DCompressible; if (OPS_PFEMElement2DCompressible(info) == 0) { @@ -462,7 +460,8 @@ Mesh::newElements(const ID &elends) { } - int eletag = this->nextEleTag(); + int eletag = nextEleTag(); + int ndtag = nextNodeTag(); // create elements ID neweletags(elends.Size() / numelenodes); @@ -476,6 +475,9 @@ Mesh::newElements(const ID &elends) { // info ID info(numelenodes + 3); + if (eleType == ELE_TAG_PFEMElement2DCompressible) { + info.resize(numelenodes + 4); + } info(0) = 2; // load data info(1) = this->getTag(); // mesh tag info(2) = neweletags(i); // ele tag @@ -483,6 +485,9 @@ Mesh::newElements(const ID &elends) { // get elenode info(3 + j) = elends(numelenodes * i + j); } + if (eleType == ELE_TAG_PFEMElement2DCompressible) { + info(3+numelenodes) = ndtag + i; + } // create element neweles[i] = (Element *) OPS_Func(info); diff --git a/SRC/element/PFEMElement/PFEMElement2DBubble.cpp b/SRC/element/PFEMElement/PFEMElement2DBubble.cpp index 398405b89..9b2198a73 100644 --- a/SRC/element/PFEMElement/PFEMElement2DBubble.cpp +++ b/SRC/element/PFEMElement/PFEMElement2DBubble.cpp @@ -59,7 +59,7 @@ void* OPS_PFEMElement2DBubble(const ID &info) } int idata[4]; - double data[6] = {0,0,0,0,1.0,-1}; + double data[7] = {0,0,0,0,1.0,-1,1e-16}; int numdata; // regular element, not in a mesh, get tags @@ -81,13 +81,13 @@ void* OPS_PFEMElement2DBubble(const ID &info) // regular element, or save data if (info.Size()==0 || info(0)==1) { if(OPS_GetNumRemainingInputArgs() < 4) { - opserr<<"insufficient arguments: rho, mu, b1, b2, (thinknes,kappa)\n"; + opserr<<"insufficient arguments: rho, mu, b1, b2, (thinknes,kappa,minJ)\n"; return 0; } - // rho, mu, b1, b2, (thinknes,kappa) + // rho, mu, b1, b2, (thinknes,kappa,minJ) numdata = OPS_GetNumRemainingInputArgs(); - if(numdata > 6) numdata = 6; + if(numdata > 7) numdata = 7; if(OPS_GetDoubleInput(&numdata,data) < 0) { opserr << "WARNING: failed to get fluid properties\n"; return 0; @@ -104,8 +104,8 @@ void* OPS_PFEMElement2DBubble(const ID &info) // save the data for a mesh Vector& mdata = meshdata[info(1)]; - mdata.resize(6); - for (int i=0; i<6; ++i) { + mdata.resize(7); + for (int i=0; i<7; ++i) { mdata(i) = data[i]; } return &meshdata; @@ -125,7 +125,7 @@ void* OPS_PFEMElement2DBubble(const ID &info) idata[i+1] = info(3+i); } - for (int i=0; i<6; ++i) { + for (int i=0; i<7; ++i) { data[i] = mdata(i); } @@ -141,14 +141,14 @@ void* OPS_PFEMElement2DBubble(const ID &info) } return new PFEMElement2DBubble(idata[0],idata[1],idata[2],idata[3], - data[0],data[1],data[2],data[3],data[4],data[5]); + data[0],data[1],data[2],data[3],data[4],data[5],data[6]); } // for FEM_ObjectBroker, recvSelf must invoke PFEMElement2DBubble::PFEMElement2DBubble() :Element(0, ELE_TAG_PFEMElement2DBubble), ntags(6), rho(0), mu(0), bx(0), by(0), J(0.0), dJ(6), - numDOFs(),thickness(1.0), kappa(-1), parameterID(0), + numDOFs(),thickness(1.0), kappa(-1), minJ(1e-16),parameterID(0), M(), D(), F(), Fp() { for(int i=0;i<3;i++) @@ -164,10 +164,10 @@ PFEMElement2DBubble::PFEMElement2DBubble() // for object PFEMElement2DBubble::PFEMElement2DBubble(int tag, int nd1, int nd2, int nd3, double r, double m, double b1, double b2, - double thk, double ka) + double thk, double ka, double minj) :Element(tag, ELE_TAG_PFEMElement2DBubble), ntags(6), rho(r), mu(m), bx(b1), by(b2), J(0.0), dJ(6), numDOFs(), - thickness(thk), kappa(ka), parameterID(0), + thickness(thk), kappa(ka), minJ(minj), parameterID(0), M(), D(), F(), Fp() { ntags(0)=nd1; ntags(2)=nd2; ntags(4)=nd3; @@ -292,7 +292,7 @@ PFEMElement2DBubble::update() } // this is the trick to check negative jacobian - if((kappa==-2 && J<0) || (kappa!=-2 && fabs(J)<1e-15)) { + if((kappa==-2 && J<0) || (kappa!=-2 && fabs(J)getTag()<<" area is "<getTag()<<": \n"; diff --git a/SRC/element/PFEMElement/PFEMElement2DBubble.h b/SRC/element/PFEMElement/PFEMElement2DBubble.h index 6ce270cdd..ad8540626 100644 --- a/SRC/element/PFEMElement/PFEMElement2DBubble.h +++ b/SRC/element/PFEMElement/PFEMElement2DBubble.h @@ -43,7 +43,7 @@ class PFEMElement2DBubble : public Element PFEMElement2DBubble(); PFEMElement2DBubble(int tag, int nd1, int nd2, int nd3, double r, double m, double b1, double b2, - double thk=1.0, double ka=-1); + double thk=1.0, double ka=-1,double minj=1e-16); ~PFEMElement2DBubble(); @@ -111,6 +111,7 @@ class PFEMElement2DBubble : public Element ID numDOFs; double thickness; double kappa; + double minJ; int parameterID; static Matrix K; diff --git a/SRC/element/PFEMElement/Particle.cpp b/SRC/element/PFEMElement/Particle.cpp index db27447c8..ac441a088 100644 --- a/SRC/element/PFEMElement/Particle.cpp +++ b/SRC/element/PFEMElement/Particle.cpp @@ -18,7 +18,6 @@ ** ** ** ****************************************************************** */ - // $Revision: 1.0 $ // $Date: 2016-1-27 $ @@ -32,9 +31,14 @@ size_t Particle::curr_tag = 1; Particle::Particle() - : coord(), coordn(), velocity(), accel(), pressure(0), pdot(0), gtag(0), - updated(false), dt(0.0), fixed(false), tag(curr_tag++) { -} + : coord(), + velocity(), + accel(), + pressure(0), + pdot(0), + gtag(0), + updated(false), + dt(0.0), + tag(curr_tag++) {} -Particle::~Particle() { -} +Particle::~Particle() {} diff --git a/SRC/element/PFEMElement/Particle.h b/SRC/element/PFEMElement/Particle.h index cfff3a581..f8a17d6aa 100644 --- a/SRC/element/PFEMElement/Particle.h +++ b/SRC/element/PFEMElement/Particle.h @@ -18,10 +18,6 @@ ** ** ** ****************************************************************** */ - -// $Revision: 1.0 $ -// $Date: 2016-1-27 $ - // Written: Minjie Zhu // // Description: This class defines the Particle class @@ -33,8 +29,7 @@ #include "BackgroundDef.h" class Particle { - -public: + public: Particle(); ~Particle(); @@ -54,48 +49,27 @@ class Particle { void setVel(const VDouble &vel) { if (!updated) { this->velocity = vel; - this->coordn = this->coord; updated = true; } } - void incrVel(const VDouble &dv) { - if (!updated) { - this->velocity += dv; - this->coordn = this->coord; - updated = true; - } - } + void setVelOnly(const VDouble &vel) { this->velocity = vel; } - void setPressure(double p) { - pressure = p; - } + void setPressure(double p) { pressure = p; } - void setAccel(const VDouble &accel) { - this->accel = accel; - } + void setAccel(const VDouble &accel) { this->accel = accel; } - void setPdot(double pdot) { - this->pdot = pdot; - } + void setPdot(double pdot) { this->pdot = pdot; } - void setGroupTag(int tag) { - this->gtag = tag; - } + void setGroupTag(int tag) { this->gtag = tag; } void needUpdate(double dt) { updated = false; this->dt = dt; } - void setFixed() { - fixed = true; - } - const VDouble &getCrds() const { return coord; } - const VDouble &getCrdsn() const { return coordn; } - const VDouble &getVel() const { return velocity; } const VDouble &getAccel() const { return accel; } @@ -108,25 +82,21 @@ class Particle { bool isUpdated() const { return updated; } - bool isFixed() const { return fixed; } - double getDt() const { return dt; } - size_t getTag() const {return tag;} + size_t getTag() const { return tag; } -private: - VDouble coord, coordn; + private: + VDouble coord; VDouble velocity; VDouble accel; double pressure, pdot; int gtag; bool updated; double dt; - bool fixed; size_t tag; static size_t curr_tag; }; - #endif diff --git a/SRC/element/PFEMElement/ParticleGroup.cpp b/SRC/element/PFEMElement/ParticleGroup.cpp index 1629a37d6..1bfc1d9ee 100644 --- a/SRC/element/PFEMElement/ParticleGroup.cpp +++ b/SRC/element/PFEMElement/ParticleGroup.cpp @@ -98,6 +98,46 @@ int OPS_ParticleGroup() { return -1; } } else if (strcmp(geotype, "cube") == 0) { + if (OPS_GetNumRemainingInputArgs() < 2 * ndm + 3) { + opserr << "WARNING: insufficient args -- "; + opserr << "lower point, upper point, nx, ny, nz\n"; + return -1; + } + // node coord + if (OPS_GetDoubleInput(&ndm, &p1[0]) < 0) { + opserr << "WARNING: failed to get cooridnates for the " + "lower point\n"; + return -1; + } + if (OPS_GetDoubleInput(&ndm, &p7[0]) < 0) { + opserr << "WARNING: failed to get cooridnates for the " + "upper point\n"; + return -1; + } + p2 = p1; + p3 = p1; + p4 = p1; + p5 = p7; + p6 = p7; + p8 = p7; + p2[0] = p7[0]; + p3[0] = p7[0]; + p3[1] = p7[1]; + p4[1] = p7[1]; + p5[0] = p1[0]; + p5[1] = p1[1]; + p6[1] = p1[1]; + p8[0] = p1[0]; + + // num of particles + int numdata = 3; + nump.resize(numdata); + if (OPS_GetIntInput(&numdata, &nump[0]) < 0) { + opserr << "WARNING: failed to get particle mesh size\n"; + return -1; + } + + } else if (strcmp(geotype, "hex") == 0) { if (OPS_GetNumRemainingInputArgs() < 8 * ndm + 3) { opserr << "WARNING: insufficient args -- "; opserr << "bottom p1, p2, p3, p4 and top p5, p6, p7, p8\n"; @@ -106,37 +146,45 @@ int OPS_ParticleGroup() { // node coord if (OPS_GetDoubleInput(&ndm, &p1[0]) < 0) { - opserr << "WARNING: failed to get cooridnates for first bottom point\n"; + opserr << "WARNING: failed to get cooridnates for first " + "bottom point\n"; return -1; } if (OPS_GetDoubleInput(&ndm, &p2[0]) < 0) { - opserr << "WARNING: failed to get cooridnates for second bottom point\n"; + opserr << "WARNING: failed to get cooridnates for second " + "bottom point\n"; return -1; } if (OPS_GetDoubleInput(&ndm, &p3[0]) < 0) { - opserr << "WARNING: failed to get cooridnates for third bottom point\n"; + opserr << "WARNING: failed to get cooridnates for third " + "bottom point\n"; return -1; } if (OPS_GetDoubleInput(&ndm, &p4[0]) < 0) { - opserr << "WARNING: failed to get cooridnates for fouth bottom point\n"; + opserr << "WARNING: failed to get cooridnates for fouth " + "bottom point\n"; return -1; } // node coord if (OPS_GetDoubleInput(&ndm, &p5[0]) < 0) { - opserr << "WARNING: failed to get cooridnates for first top point\n"; + opserr << "WARNING: failed to get cooridnates for first " + "top point\n"; return -1; } if (OPS_GetDoubleInput(&ndm, &p6[0]) < 0) { - opserr << "WARNING: failed to get cooridnates for second top point\n"; + opserr << "WARNING: failed to get cooridnates for second " + "top point\n"; return -1; } if (OPS_GetDoubleInput(&ndm, &p7[0]) < 0) { - opserr << "WARNING: failed to get cooridnates for third top point\n"; + opserr << "WARNING: failed to get cooridnates for third " + "top point\n"; return -1; } if (OPS_GetDoubleInput(&ndm, &p8[0]) < 0) { - opserr << "WARNING: failed to get cooridnates for fouth top point\n"; + opserr << "WARNING: failed to get cooridnates for fouth " + "top point\n"; return -1; } @@ -285,7 +333,8 @@ int OPS_ParticleGroup() { // generate particles if (strcmp(geotype, "quad") == 0) { group->qua_d(p1, p2, p3, p4, nump[0], nump[1], vel0, p0); - } else if (strcmp(geotype, "cube") == 0) { + } else if (strcmp(geotype, "cube") == 0 || + strcmp(geotype, "hex") == 0) { VVDouble pts(8); pts[0] = p1; pts[1] = p2; @@ -325,7 +374,7 @@ void ParticleGroup::addParticle(const VDouble &coord, const VDouble &vel, double particles.push_back(particle); particle->moveTo(coord, 0.0); - particle->setVel(vel); + particle->setVelOnly(vel); particle->setPressure(p); VDouble accel = vel; accel *= 0.0; @@ -334,16 +383,14 @@ void ParticleGroup::addParticle(const VDouble &coord, const VDouble &vel, double particle->setGroupTag(this->getTag()); } -void ParticleGroup::addParticle(const VDouble &coordn, - const VDouble &coord, +void ParticleGroup::addParticle(const VDouble &coord, const VDouble &vel, const VDouble &accel, double p) { Particle *particle = new Particle; particles.push_back(particle); - particle->moveTo(coordn, 0.0); - particle->setVel(vel); + particle->setVelOnly(vel); particle->moveTo(coord, 0.0); particle->setPressure(p); particle->setAccel(accel); @@ -395,18 +442,14 @@ int ParticleGroup::line(const VDouble &p1, const VDouble &p2, int num, int ParticleGroup::pointlist(VDouble &pointdata) { int ndm = OPS_GetNDM(); pointdata.clear(); - pointdata.reserve(particles.size() * (4 * ndm + 1)); + pointdata.reserve(particles.size() * (3 * ndm + 1)); for (auto particle : particles) { auto tag = particle->getTag(); - const auto& crdsn = particle->getCrdsn(); const auto& crds = particle->getCrds(); const auto& vel = particle->getVel(); const auto& accel = particle->getAccel(); double p = particle->getPressure(); pointdata.push_back(tag); - for (int j = 0; j < ndm; ++j) { - pointdata.push_back(crdsn[j]); - } for (int j = 0; j < ndm; ++j) { pointdata.push_back(crds[j]); } @@ -423,15 +466,11 @@ int ParticleGroup::pointlist(VDouble &pointdata) { } int ParticleGroup::pointlist(const VDouble &pointdata, int ndm) { - VDouble crdsn(ndm); VDouble crds(ndm); VDouble vel(ndm); VDouble accel(ndm); double p0 = 0.0; for (int i = 0; i < (int)pointdata.size(); i += 4 * ndm + 1) { - for (int j = 0; j < ndm; ++j) { - crdsn[j] = pointdata[i + j]; - } for (int j = 0; j < ndm; ++j) { crds[j] = pointdata[i + ndm + j]; } @@ -442,7 +481,7 @@ int ParticleGroup::pointlist(const VDouble &pointdata, int ndm) { accel[j] = pointdata[i + 3 * ndm + j]; } p0 = pointdata[i + 4 * ndm]; - this->addParticle(crdsn, crds, vel, accel, p0); + this->addParticle(crds, vel, accel, p0); } return 0; diff --git a/SRC/element/PFEMElement/ParticleGroup.h b/SRC/element/PFEMElement/ParticleGroup.h index 2087f6ee9..007456a02 100644 --- a/SRC/element/PFEMElement/ParticleGroup.h +++ b/SRC/element/PFEMElement/ParticleGroup.h @@ -43,7 +43,7 @@ class ParticleGroup : public Mesh // particles void addParticle(const VDouble& coord, const VDouble& vel, double p); - void addParticle(const VDouble& coordn, const VDouble& coord, + void addParticle(const VDouble& coord, const VDouble& vel, const VDouble& accel, double p); void removeParticles(const VInt& rm); diff --git a/SRC/element/RockingBC/RockingBC.cpp b/SRC/element/RockingBC/RockingBC.cpp index dd3f7fc44..c66e22e04 100644 --- a/SRC/element/RockingBC/RockingBC.cpp +++ b/SRC/element/RockingBC/RockingBC.cpp @@ -273,8 +273,8 @@ RockingBC::RockingBC(int tag, int Nd1, int Nd2, int nw, ey = sy / E; for (size_t i = 0; i != Nw - 1; i++) { - Vec vvv1{ Yw[i],Yw[i + 1] }; - Vec vvv2{ 0.0, 0.0 }; + RBCVec vvv1{ Yw[i],Yw[i + 1] }; + RBCVec vvv2{ 0.0, 0.0 }; Vecint vvv3{ 0 }; Matrix mmm4{}; Ysi.push_back(vvv1); @@ -2117,7 +2117,7 @@ void RockingBC::Uel_K_calc() } } - UBnew_R = Vec(Ydks.Size(), 0.0); + UBnew_R = RBCVec(Ydks.Size(), 0.0); UBnew = Matrix(Nw, Ydks.Size()); dUBnew_dR = Matrix(Nw, Ydks.Size()); @@ -3471,12 +3471,12 @@ void RockingBC::Up_interval_split(const Vector& Yup, const Vector& Up, const Vec Yup_ints.clear(); Up_ints.clear(); for (size_t i = 0; i != Yind.size() - 1; i++) { - Vec X1{}; + RBCVec X1{}; for (size_t j = Yind[i]; j != Yind[i + 1] +1; j++) { X1.push_back(Up[j]); } Up_ints.push_back(X1); - Vec X2{}; + RBCVec X2{}; for (size_t j = Yind[i]; j != Yind[i + 1] +1; j++) { X2.push_back(Yup[j]); } @@ -3486,7 +3486,7 @@ void RockingBC::Up_interval_split(const Vector& Yup, const Vector& Up, const Vec } Vector RockingBC::interval_join(const VecVec& X_ints) { - static Vec X{}; + static RBCVec X{}; X.clear(); for (size_t i = 0; i != X_ints.size(); i++) { @@ -3532,7 +3532,7 @@ Matrix RockingBC::interval_join(const VecMatOS& X_ints) { } Vector RockingBC::array_join(const VecVec& X_ints) { - Vec X{}; + RBCVec X{}; for (size_t i = 0; i != X_ints.size(); i++) { for (size_t j = 0; j != X_ints.at(i).size(); j++) { X.push_back(X_ints[i][j]); @@ -3563,7 +3563,7 @@ Matrix RockingBC::array_join(const VecMatOS& X_ints) { return res; } -void RockingBC::commony(const Vec& ya, const Vec& fa, const Vec& yb, const Vec& fb, Vec& Y, Vec& FA, Vec& FB) +void RockingBC::commony(const RBCVec& ya, const RBCVec& fa, const RBCVec& yb, const RBCVec& fb, RBCVec& Y, RBCVec& FA, RBCVec& FB) { Y.clear(); FA.clear(); @@ -3599,10 +3599,10 @@ void RockingBC::commony(const Vec& ya, const Vec& fa, const Vec& yb, const Vec& return; } -void RockingBC::interval_interior(double wl, double wr, double ey, double dy, const Vec& up_com, const Vec& yup_com, - const Vec& ys_com, const Vec& s_com, double beta_Dt, - Vec& ys_new, Vec& s_new, Vecint& ys_cats, Vec& yup_new, Vec& up_new, - Vec& dys_new_dwl, Vec& dys_new_dwr, Vec& ds_new_dwl, Vec& ds_new_dwr, Vec& ua_pos) +void RockingBC::interval_interior(double wl, double wr, double ey, double dy, const RBCVec& up_com, const RBCVec& yup_com, + const RBCVec& ys_com, const RBCVec& s_com, double beta_Dt, + RBCVec& ys_new, RBCVec& s_new, Vecint& ys_cats, RBCVec& yup_new, RBCVec& up_new, + RBCVec& dys_new_dwl, RBCVec& dys_new_dwr, RBCVec& ds_new_dwl, RBCVec& ds_new_dwr, RBCVec& ua_pos) { static const double pi{ std::atan(1.) * 4 }; @@ -3613,14 +3613,14 @@ void RockingBC::interval_interior(double wl, double wr, double ey, double dy, co } double eyn = ey*DU_DS; - static Vec Y{}; - static Vec Up{}; - static Vec S{}; + static RBCVec Y{}; + static RBCVec Up{}; + static RBCVec S{}; commony(yup_com,up_com,ys_com,s_com,Y,Up,S); // Plastic displacements differences - static Vec Upd; Upd.clear(); + static RBCVec Upd; Upd.clear(); double yline{}; double kyline = (Up[Up.size()-1]-Up[0])/(Y[Y.size()-1]-Y[0]); for (size_t iy = 0; iy != Y.size(); iy++) @@ -3630,8 +3630,8 @@ void RockingBC::interval_interior(double wl, double wr, double ey, double dy, co } // Limits - static Vec Slim; Slim.clear(); - static Vec Slimn; Slimn.clear(); + static RBCVec Slim; Slim.clear(); + static RBCVec Slimn; Slimn.clear(); for (size_t i = 0; i != Y.size(); i++) { Slim.push_back(S[i]*DAMPC); @@ -3674,9 +3674,9 @@ void RockingBC::interval_interior(double wl, double wr, double ey, double dy, co double dkwnline_dwr=dwrn_dwr/dy; // Plastic displacements into stresses insertion - static Vec Wn; Wn.clear(); - static Vec dWn_dwl; dWn_dwl.clear(); - static Vec dWn_dwr; dWn_dwr.clear(); + static RBCVec Wn; Wn.clear(); + static RBCVec dWn_dwl; dWn_dwl.clear(); + static RBCVec dWn_dwr; dWn_dwr.clear(); double wline{}; for (size_t iy = 0; iy != Y.size(); iy++) { @@ -3686,16 +3686,16 @@ void RockingBC::interval_interior(double wl, double wr, double ey, double dy, co } // Crossings - static Vec Yf{}; Yf.clear(); - static Vec Wnf{}; Wnf.clear(); - static Vec Upf{}; Upf.clear(); - static Vec Slimnf{}; Slimnf.clear(); - static Vec dYf_dwl{}; dYf_dwl.clear(); - static Vec dWnf_dwl{}; dWnf_dwl.clear(); - static Vec dSlimnf_dwl{}; dSlimnf_dwl.clear(); - static Vec dYf_dwr{}; dYf_dwr.clear(); - static Vec dWnf_dwr{}; dWnf_dwr.clear(); - static Vec dSlimnf_dwr{}; dSlimnf_dwr.clear(); + static RBCVec Yf{}; Yf.clear(); + static RBCVec Wnf{}; Wnf.clear(); + static RBCVec Upf{}; Upf.clear(); + static RBCVec Slimnf{}; Slimnf.clear(); + static RBCVec dYf_dwl{}; dYf_dwl.clear(); + static RBCVec dWnf_dwl{}; dWnf_dwl.clear(); + static RBCVec dSlimnf_dwl{}; dSlimnf_dwl.clear(); + static RBCVec dYf_dwr{}; dYf_dwr.clear(); + static RBCVec dWnf_dwr{}; dWnf_dwr.clear(); + static RBCVec dSlimnf_dwr{}; dSlimnf_dwr.clear(); double wnf1{}, wnf2{}; bool wnf1found = false; @@ -3848,11 +3848,11 @@ void RockingBC::interval_interior(double wl, double wr, double ey, double dy, co //Separation into stresses, plastic displacements - static Vec Sf_new{}; Sf_new.clear(); - static Vec dSf_new_dwl{}; dSf_new_dwl.clear(); - static Vec dSf_new_dwr{}; dSf_new_dwr.clear(); - static Vec Upf_new{}; Upf_new.clear(); - static Vec Ua_pos{}; Ua_pos.clear(); + static RBCVec Sf_new{}; Sf_new.clear(); + static RBCVec dSf_new_dwl{}; dSf_new_dwl.clear(); + static RBCVec dSf_new_dwr{}; dSf_new_dwr.clear(); + static RBCVec Upf_new{}; Upf_new.clear(); + static RBCVec Ua_pos{}; Ua_pos.clear(); for (size_t i = 0; i != Wnf.size(); i++) { if (Wnf[i] > Slimnf[i]) { @@ -3959,8 +3959,8 @@ void RockingBC::interval_dists(const Vector& Yw, const Vector& W, const VecVec& for (size_t i = 0; i != W.Size() - 1; i++) { - Vec dwl_dW(W.Size()); dwl_dW[i] = 1.0; - Vec dwr_dW(W.Size()); dwr_dW[i+1] = 1.0; + RBCVec dwl_dW(W.Size()); dwl_dW[i] = 1.0; + RBCVec dwr_dW(W.Size()); dwr_dW[i+1] = 1.0; Matrix dys_dW = Matrix(dys_dwl_list[i].size(), W.Size()); Matrix ds_dW = Matrix(ds_dwl_list[i].size(), W.Size()); for (size_t l = 0; l != W.Size(); l++) { @@ -3983,7 +3983,7 @@ void RockingBC::interval_dists(const Vector& Yw, const Vector& W, const VecVec& } -void RockingBC::NM_calc_int(const Vec& Ys, const Matrix& dYs_dW, const Vec& S, const Matrix& dS_dW, double& N, double& M, Vector& dN_dW, Vector& dM_dW) +void RockingBC::NM_calc_int(const RBCVec& Ys, const Matrix& dYs_dW, const RBCVec& S, const Matrix& dS_dW, double& N, double& M, Vector& dN_dW, Vector& dM_dW) { N = 0; M = 0; @@ -4007,7 +4007,7 @@ void RockingBC::NM_calc_int(const Vec& Ys, const Matrix& dYs_dW, const Vec& S, c return; } -void RockingBC::critpoints(const Vec& y, const Vec& s, int rinit, int rend, Vecint& cp) +void RockingBC::critpoints(const RBCVec& y, const RBCVec& s, int rinit, int rend, Vecint& cp) { cp.clear(); @@ -4030,8 +4030,8 @@ void RockingBC::critpoints(const Vec& y, const Vec& s, int rinit, int rend, Veci return; } -void RockingBC::int_bilin(const Vecint& ys_cats, const Vec& ys, const Vec& s, const Vec& yup, const Vec& up, const Vec& ua_pos, double ey, - Vec& ys_new, Vec& s_new, Vec& yup_new, Vec& up_new) +void RockingBC::int_bilin(const Vecint& ys_cats, const RBCVec& ys, const RBCVec& s, const RBCVec& yup, const RBCVec& up, const RBCVec& ua_pos, double ey, + RBCVec& ys_new, RBCVec& s_new, RBCVec& yup_new, RBCVec& up_new) { if ((ys.size() != yup.size()) || (ys_cats.size() != ys.size() - 1) || (ys.size() != ua_pos.size())) { @@ -4045,8 +4045,8 @@ void RockingBC::int_bilin(const Vecint& ys_cats, const Vec& ys, const Vec& s, co static const double pi{ std::atan(1.) * 4 }; double DU_DS = (ys[ys.size()-1] - ys[0]) / pi; - static Vec w{}; w.clear(); - static Vec sm{}; sm.clear(); + static RBCVec w{}; w.clear(); + static RBCVec sm{}; sm.clear(); for (size_t i = 0; i != s.size(); i++) { w.push_back(s[i] * DU_DS + ua_pos[i]); sm.push_back(s[i] * DU_DS); @@ -4099,20 +4099,20 @@ void RockingBC::int_bilin(const Vecint& ys_cats, const Vec& ys, const Vec& s, co static VecVec up_bl{}; up_bl.clear(); static VecVec yup_bl{}; yup_bl.clear(); - static Vec ysp{}; - static Vec smp{}; - static Vec sp{}; - static Vec wp{}; - static Vec ss{}; - static Vec ys_try{}, sm_try{}, yw_try{}, w_try{}, s_try{}; + static RBCVec ysp{}; + static RBCVec smp{}; + static RBCVec sp{}; + static RBCVec wp{}; + static RBCVec ss{}; + static RBCVec ys_try{}, sm_try{}, yw_try{}, w_try{}, s_try{}; static Vecint v{}; for (size_t ir = 0; ir != regs2.size(); ir++) { Vecint r = regs2[ir]; if (regs2_cats[ir] == 0) { - ysp = Vec(ys.begin() + r[0], ys.begin() + r[1] + 1); - smp = Vec(sm.begin() + r[0], sm.begin() + r[1] + 1); - wp = Vec(w.begin() + r[0], w.begin() + r[1] + 1); + ysp = RBCVec(ys.begin() + r[0], ys.begin() + r[1] + 1); + smp = RBCVec(sm.begin() + r[0], sm.begin() + r[1] + 1); + wp = RBCVec(w.begin() + r[0], w.begin() + r[1] + 1); ys_try.clear(); sm_try.clear(); yw_try.clear(); w_try.clear(); bool suc = bilin_two(ysp, smp, ysp, wp, ys_try, sm_try, yw_try, w_try); if (suc) { @@ -4157,8 +4157,8 @@ void RockingBC::int_bilin(const Vecint& ys_cats, const Vec& ys, const Vec& s, co } } else { - ysp = Vec(ys.begin() + r[0], ys.begin() + r[1] + 1); - sp = Vec(s.begin() + r[0], s.begin() + r[1] + 1); + ysp = RBCVec(ys.begin() + r[0], ys.begin() + r[1] + 1); + sp = RBCVec(s.begin() + r[0], s.begin() + r[1] + 1); ys_try.clear(); s_try.clear(); bool suc = bilin_one(ysp, sp, ys_try, s_try); if (suc) { @@ -4299,7 +4299,7 @@ void RockingBC::Up_interval_split_K(const Vector& Yup, const Vector& Up, const V return; } -void RockingBC::commony_K(const Vector& ya, const Vector& fa, const Vector& ka, const Vector& yb, const Vector& fb, const Vector& kb, Vec& Y, Vec& FA, Vec& FB, Vec& KA, Vec& KB) +void RockingBC::commony_K(const Vector& ya, const Vector& fa, const Vector& ka, const Vector& yb, const Vector& fb, const Vector& kb, RBCVec& Y, RBCVec& FA, RBCVec& FB, RBCVec& KA, RBCVec& KB) { Y.clear(); FA.clear(); @@ -4346,27 +4346,27 @@ void RockingBC::commony_K(const Vector& ya, const Vector& fa, const Vector& ka, void RockingBC::interval_interior_K(double wl, double wr, double ey, double dy, const Vector& up_com, const Vector& yup_com, const Vector& kup_com, const Vector& ys_com, const Vector& s_com, const Vector& ks_com, double beta_Dt, - Vec& ys_new, Vec& s_new, Vec& ks_new, Vecint& ys_cats, Vec& yup_new, Vec& up_new, Vec& kup_new, - Vec& dys_new_dwl, Vec& dys_new_dwr, Vec& ds_new_dwl, Vec& ds_new_dwr, Vec& dks_new_dwl, Vec& dks_new_dwr, - Vec& ydks, Vec& dks, Vec& dydks_dwl, Vec& dydks_dwr, Vec& ddks_dwl, Vec& ddks_dwr, - Vec& ds, Vec& dds_dwl, Vec& dds_dwr) + RBCVec& ys_new, RBCVec& s_new, RBCVec& ks_new, Vecint& ys_cats, RBCVec& yup_new, RBCVec& up_new, RBCVec& kup_new, + RBCVec& dys_new_dwl, RBCVec& dys_new_dwr, RBCVec& ds_new_dwl, RBCVec& ds_new_dwr, RBCVec& dks_new_dwl, RBCVec& dks_new_dwr, + RBCVec& ydks, RBCVec& dks, RBCVec& dydks_dwl, RBCVec& dydks_dwr, RBCVec& ddks_dwl, RBCVec& ddks_dwr, + RBCVec& ds, RBCVec& dds_dwl, RBCVec& dds_dwr) { static const double pi{ std::atan(1.) * 4 }; double DU_DS = dy / pi; double DAMPC = beta_Dt / (1.0 + beta_Dt); double eyn = ey * DU_DS; - static Vec Y{}; - static Vec Up{}; - static Vec S{}; - static Vec KUp{}; - static Vec KS{}; + static RBCVec Y{}; + static RBCVec Up{}; + static RBCVec S{}; + static RBCVec KUp{}; + static RBCVec KS{}; commony_K(yup_com, up_com, kup_com, ys_com, s_com, ks_com, Y, Up, S, KUp, KS); // Plastic displacements differences - static Vec Upd; Upd.clear(); - static Vec KUpd; KUpd.clear(); + static RBCVec Upd; Upd.clear(); + static RBCVec KUpd; KUpd.clear(); double yline{}; double kyline = (Up[Up.size() - 1] - Up[0]) / (Y[Y.size() - 1] - Y[0]); for (size_t iy = 0; iy != Y.size(); iy++) @@ -4380,9 +4380,9 @@ void RockingBC::interval_interior_K(double wl, double wr, double ey, double dy, } // Limits - static Vec Slim; Slim.clear(); - static Vec Slimn; Slimn.clear(); - static Vec KSlim; KSlim.clear(); + static RBCVec Slim; Slim.clear(); + static RBCVec Slimn; Slimn.clear(); + static RBCVec KSlim; KSlim.clear(); for (size_t i = 0; i != Y.size(); i++) { Slim.push_back(S[i] * DAMPC); @@ -4429,12 +4429,12 @@ void RockingBC::interval_interior_K(double wl, double wr, double ey, double dy, double dkwnline_dwr = dwrn_dwr / dy; // Plastic displacements into stresses insertion - static Vec Wn; Wn.clear(); - static Vec dWn_dwl; dWn_dwl.clear(); - static Vec dWn_dwr; dWn_dwr.clear(); - static Vec KWn; KWn.clear(); - static Vec dKWn_dwl; dKWn_dwl.clear(); - static Vec dKWn_dwr; dKWn_dwr.clear(); + static RBCVec Wn; Wn.clear(); + static RBCVec dWn_dwl; dWn_dwl.clear(); + static RBCVec dWn_dwr; dWn_dwr.clear(); + static RBCVec KWn; KWn.clear(); + static RBCVec dKWn_dwl; dKWn_dwl.clear(); + static RBCVec dKWn_dwr; dKWn_dwr.clear(); double wline{}; for (size_t iy = 0; iy != Y.size(); iy++) { @@ -4450,21 +4450,21 @@ void RockingBC::interval_interior_K(double wl, double wr, double ey, double dy, } // Crossings - static Vec Yf{}; Yf.clear(); - static Vec Wnf{}; Wnf.clear(); - static Vec Upf{}; Upf.clear(); - static Vec Slimnf{}; Slimnf.clear(); - static Vec dYf_dwl{}; dYf_dwl.clear(); - static Vec dWnf_dwl{}; dWnf_dwl.clear(); - static Vec dSlimnf_dwl{}; dSlimnf_dwl.clear(); - static Vec dYf_dwr{}; dYf_dwr.clear(); - static Vec dWnf_dwr{}; dWnf_dwr.clear(); - static Vec dSlimnf_dwr{}; dSlimnf_dwr.clear(); - static Vec KWnf{}; KWnf.clear(); - static Vec KUpf{}; KUpf.clear(); - static Vec KSlimf{}; KSlimf.clear(); - static Vec dKWnf_dwl{}; dKWnf_dwl.clear(); - static Vec dKWnf_dwr{}; dKWnf_dwr.clear(); + static RBCVec Yf{}; Yf.clear(); + static RBCVec Wnf{}; Wnf.clear(); + static RBCVec Upf{}; Upf.clear(); + static RBCVec Slimnf{}; Slimnf.clear(); + static RBCVec dYf_dwl{}; dYf_dwl.clear(); + static RBCVec dWnf_dwl{}; dWnf_dwl.clear(); + static RBCVec dSlimnf_dwl{}; dSlimnf_dwl.clear(); + static RBCVec dYf_dwr{}; dYf_dwr.clear(); + static RBCVec dWnf_dwr{}; dWnf_dwr.clear(); + static RBCVec dSlimnf_dwr{}; dSlimnf_dwr.clear(); + static RBCVec KWnf{}; KWnf.clear(); + static RBCVec KUpf{}; KUpf.clear(); + static RBCVec KSlimf{}; KSlimf.clear(); + static RBCVec dKWnf_dwl{}; dKWnf_dwl.clear(); + static RBCVec dKWnf_dwr{}; dKWnf_dwr.clear(); double wnf1{}, wnf2{}; bool wnf1found = false; @@ -4642,10 +4642,10 @@ void RockingBC::interval_interior_K(double wl, double wr, double ey, double dy, //Separation into stresses, plastic displacements - static Vec Sf_new{}; Sf_new.clear(); - static Vec dSf_new_dwl{}; dSf_new_dwl.clear(); - static Vec dSf_new_dwr{}; dSf_new_dwr.clear(); - static Vec Upf_new{}; Upf_new.clear(); + static RBCVec Sf_new{}; Sf_new.clear(); + static RBCVec dSf_new_dwl{}; dSf_new_dwl.clear(); + static RBCVec dSf_new_dwr{}; dSf_new_dwr.clear(); + static RBCVec Upf_new{}; Upf_new.clear(); for (size_t i = 0; i != Wnf.size(); i++) { if (Wnf[i] > Slimnf[i]) { @@ -4668,9 +4668,9 @@ void RockingBC::interval_interior_K(double wl, double wr, double ey, double dy, } } - static Vec DSf{}; DSf.clear(); - static Vec dDSf_dwl{}; dDSf_dwl.clear(); - static Vec dDSf_dwr{}; dDSf_dwr.clear(); + static RBCVec DSf{}; DSf.clear(); + static RBCVec dDSf_dwl{}; dDSf_dwl.clear(); + static RBCVec dDSf_dwr{}; dDSf_dwr.clear(); for (size_t i = 0; i != Sf_new.size(); i++) { DSf.push_back(Sf_new[i] - Slimnf[i] / DU_DS); @@ -4680,13 +4680,13 @@ void RockingBC::interval_interior_K(double wl, double wr, double ey, double dy, //Slopes - static Vec KSf_new{}; KSf_new.clear(); - static Vec dKSf_new_dwl{}; dKSf_new_dwl.clear(); - static Vec dKSf_new_dwr{}; dKSf_new_dwr.clear(); - static Vec KUpf_new{}; KUpf_new.clear(); - static Vec DKSf{}; DKSf.clear(); - static Vec dDKSf_dwl{}; dDKSf_dwl.clear(); - static Vec dDKSf_dwr{}; dDKSf_dwr.clear(); + static RBCVec KSf_new{}; KSf_new.clear(); + static RBCVec dKSf_new_dwl{}; dKSf_new_dwl.clear(); + static RBCVec dKSf_new_dwr{}; dKSf_new_dwr.clear(); + static RBCVec KUpf_new{}; KUpf_new.clear(); + static RBCVec DKSf{}; DKSf.clear(); + static RBCVec dDKSf_dwl{}; dDKSf_dwl.clear(); + static RBCVec dDKSf_dwr{}; dDKSf_dwr.clear(); for (size_t i = 0; i != intcats.size(); i++) { if (intcats[i] == 0) { @@ -4897,8 +4897,8 @@ void RockingBC::interval_dists_K(const Vector& Yw, const Vector& W, const Vector for (size_t i = 0; i != W.Size() - 1; i++) { - Vec dwl_dW(W.Size()); dwl_dW[i] = 1.0; - Vec dwr_dW(W.Size()); dwr_dW[i + 1] = 1.0; + RBCVec dwl_dW(W.Size()); dwl_dW[i] = 1.0; + RBCVec dwr_dW(W.Size()); dwr_dW[i + 1] = 1.0; Matrix dys_dW = Matrix(dys_dwl_list[i].size(), W.Size()); Matrix ds_dW = Matrix(ds_dwl_list[i].size(), W.Size()); Matrix dks_dW = Matrix(dks_dwl_list[i].size(), W.Size()); @@ -4966,7 +4966,7 @@ void RockingBC::Ys_cats_dist_calc(const VecVecint& Ys_cats, Vecint& Ys_cats_dist // bilin funcs -void RockingBC::commony_BL(const Vec& ya, const Vec& fa, const Vec& yb, const Vec& fb, Vec& Y, Vec& FA, Vec& FB) +void RockingBC::commony_BL(const RBCVec& ya, const RBCVec& fa, const RBCVec& yb, const RBCVec& fb, RBCVec& Y, RBCVec& FA, RBCVec& FB) { Y.clear(); FA.clear(); @@ -5003,11 +5003,11 @@ void RockingBC::commony_BL(const Vec& ya, const Vec& fa, const Vec& yb, const Ve return; } -bool RockingBC::distintersec(const Vec& YP, const Vec& P, const Vec& YQ, const Vec& Q) +bool RockingBC::distintersec(const RBCVec& YP, const RBCVec& P, const RBCVec& YQ, const RBCVec& Q) { - static Vec Y{}; - static Vec PT{}; - static Vec QT{}; + static RBCVec Y{}; + static RBCVec PT{}; + static RBCVec QT{}; commony_BL(YP, P, YQ, Q, Y, PT, QT); int sgn = 0; @@ -5056,7 +5056,7 @@ bool RockingBC::twobilinintersec(double y1, double y2, double p1, double p2, dou } } -void RockingBC::NM_BL(const Vec& Y, const Vec& S, double& N, double& M, double& Nd, double& Md) +void RockingBC::NM_BL(const RBCVec& Y, const RBCVec& S, double& N, double& M, double& Nd, double& Md) { N = 0.; M = 0.; @@ -5085,7 +5085,7 @@ bool RockingBC::bilinable(double Nd, double Md, double y1, double y2, double BIL } } -void RockingBC::bilindist(const Vec& Y, const Vec& S, double Nd, double Md, Vec& Ybl, Vec& Sbl, double BILINLIM) +void RockingBC::bilindist(const RBCVec& Y, const RBCVec& S, double Nd, double Md, RBCVec& Ybl, RBCVec& Sbl, double BILINLIM) { Ybl.clear(); Sbl.clear(); @@ -5106,7 +5106,7 @@ void RockingBC::bilindist(const Vec& Y, const Vec& S, double Nd, double Md, Vec& } -bool RockingBC::bilin_two(const Vec& YP, const Vec& P, const Vec& YQ, const Vec& Q, Vec& YPn, Vec& Pn, Vec& YQn, Vec& Qn) +bool RockingBC::bilin_two(const RBCVec& YP, const RBCVec& P, const RBCVec& YQ, const RBCVec& Q, RBCVec& YPn, RBCVec& Pn, RBCVec& YQn, RBCVec& Qn) { double NP{}, MP{}, NPd{}, MPd{}, NQ{}, MQ{}, NQd{}, MQd{}; NM_BL(YP, P, NP, MP, NPd, MPd); @@ -5147,7 +5147,7 @@ bool RockingBC::bilin_two(const Vec& YP, const Vec& P, const Vec& YQ, const Vec& } -bool RockingBC::bilin_one(const Vec& YP, const Vec& P, Vec& YPn, Vec& Pn) { +bool RockingBC::bilin_one(const RBCVec& YP, const RBCVec& P, RBCVec& YPn, RBCVec& Pn) { double NP{}, MP{}, NPd{}, MPd{}; NM_BL(YP, P, NP, MP, NPd, MPd); diff --git a/SRC/element/RockingBC/RockingBC.h b/SRC/element/RockingBC/RockingBC.h index aab424966..1040b9ae9 100644 --- a/SRC/element/RockingBC/RockingBC.h +++ b/SRC/element/RockingBC/RockingBC.h @@ -61,7 +61,7 @@ // #include "Eigen/Dense" // REMOVE EIGEN -using Vec = std::vector; +using RBCVec = std::vector; using Vecint = std::vector; using VecVecOS = std::vector< Vector >; using VecVecXd = std::vector; @@ -194,7 +194,7 @@ class RockingBC : public Element VecVec Ysi, Si, Yupi, Upi, Ysi_com, Si_com, Yupi_com, Upi_com, Ua_pos; VecMatOS dYsi_dW{}; VecMatOS dSi_dW{}; - Vec ysi_new, si_new, yupi_new, upi_new; + RBCVec ysi_new, si_new, yupi_new, upi_new; Vector Ys, S, Ud; Matrix dYs_dW, dS_dW; @@ -364,7 +364,7 @@ class RockingBC : public Element Vector Ks, Ks_com, Ydks, Kup, Kup_com, DS, Dks, DDKs; Matrix dKs_dW, dYdks_dW, dDks_dW, dDDKs_dW, dDS_dW; - Vec rnotfound{}; + RBCVec rnotfound{}; std::vector rfoundi{}; std::vector ifound{}; std::vector inotfound{}; @@ -374,10 +374,10 @@ class RockingBC : public Element Matrix dUnf_dR; Matrix UB{}; Matrix dUB_dR{}; - Vec UB_R{}; + RBCVec UB_R{}; Matrix UBnew{}; Matrix dUBnew_dR{}; - Vec UBnew_R{}; + RBCVec UBnew_R{}; Vector Im1, Jm1; Vector Uel_com; @@ -531,36 +531,36 @@ class RockingBC : public Element Vector array_join(const VecVec& X_ints); Matrix array_join(const VecMatOS& X_ints); - void commony(const Vec& ya, const Vec& fa, const Vec& yb, const Vec& fb, Vec& Y, Vec& FA, Vec& FB); + void commony(const RBCVec& ya, const RBCVec& fa, const RBCVec& yb, const RBCVec& fb, RBCVec& Y, RBCVec& FA, RBCVec& FB); - void interval_interior(double wl, double wr, double ey, double dy, const Vec& up_com, const Vec& yup_com, - const Vec& ys_com, const Vec& s_com, double beta_Dt, - Vec& ys_new, Vec& s_new, Vecint& ys_cats, Vec& yup_new, Vec& up_new, - Vec& dys_new_dwl, Vec& dys_new_dwr, Vec& ds_new_dwl, Vec& ds_new_dwr, - Vec& ua_pos); + void interval_interior(double wl, double wr, double ey, double dy, const RBCVec& up_com, const RBCVec& yup_com, + const RBCVec& ys_com, const RBCVec& s_com, double beta_Dt, + RBCVec& ys_new, RBCVec& s_new, Vecint& ys_cats, RBCVec& yup_new, RBCVec& up_new, + RBCVec& dys_new_dwl, RBCVec& dys_new_dwr, RBCVec& ds_new_dwl, RBCVec& ds_new_dwr, + RBCVec& ua_pos); - void NM_calc_int(const Vec& Ys, const Matrix& dYs_dW, const Vec& S, const Matrix& dS_dW, double& N, double& M, Vector& dN_dW, Vector& dM_dW); + void NM_calc_int(const RBCVec& Ys, const Matrix& dYs_dW, const RBCVec& S, const Matrix& dS_dW, double& N, double& M, Vector& dN_dW, Vector& dM_dW); void interval_dists(const Vector& Yw, const Vector& W, const VecVec& Yupi_com, const VecVec& Upi_com, const VecVec& Ysi_com, const VecVec& Si_com, double ey, double beta_Dt, VecVec& Ysi, VecVec& Si, VecVec& Yupi_new, VecVec& Upi_new, VecVecint& Ys_cats, Vector& Nints, Vector& Mints, Matrix& dNints_dW, Matrix& dMints_dW, VecVec& Ua_pos, VecMatOS& dYsi_dW, VecMatOS& dSi_dW); - void critpoints(const Vec& y, const Vec& s, int rinit, int rend, Vecint& cp); + void critpoints(const RBCVec& y, const RBCVec& s, int rinit, int rend, Vecint& cp); - void int_bilin(const Vecint& ys_cats, const Vec& ys, const Vec& s, const Vec& yup, const Vec& up, const Vec& ua_pos, double ey, - Vec& ys_new, Vec& s_new, Vec& yup_new, Vec& up_new); + void int_bilin(const Vecint& ys_cats, const RBCVec& ys, const RBCVec& s, const RBCVec& yup, const RBCVec& up, const RBCVec& ua_pos, double ey, + RBCVec& ys_new, RBCVec& s_new, RBCVec& yup_new, RBCVec& up_new); void Up_interval_split_K(const Vector& Yup, const Vector& Up, const Vector& Kup, const Vector& Yw, VecVecOS& Yup_ints, VecVecOS& Up_ints, VecVecOS& Kup_ints); - void commony_K(const Vector& ya, const Vector& fa, const Vector& ka, const Vector& yb, const Vector& fb, const Vector& kb, Vec& Y, Vec& FA, Vec& FB, Vec& KA, Vec& KB); + void commony_K(const Vector& ya, const Vector& fa, const Vector& ka, const Vector& yb, const Vector& fb, const Vector& kb, RBCVec& Y, RBCVec& FA, RBCVec& FB, RBCVec& KA, RBCVec& KB); void interval_interior_K(double wl, double wr, double ey, double dy, const Vector& up_com, const Vector& yup_com, const Vector& kup_com, const Vector& ys_com, const Vector& s_com, const Vector& ks_com, double beta_Dt, - Vec& ys_new, Vec& s_new, Vec& ks_new, Vecint& ys_cats, Vec& yup_new, Vec& up_new, Vec& kup_new, - Vec& dys_new_dwl, Vec& dys_new_dwr, Vec& ds_new_dwl, Vec& ds_new_dwr, Vec& dks_new_dwl, Vec& dks_new_dwr, - Vec& ydks, Vec& dks, Vec& dydks_dwl, Vec& dydks_dwr, Vec& ddks_dwl, Vec& ddks_dwr, - Vec& ds, Vec& dds_dwl, Vec& dds_dwr); + RBCVec& ys_new, RBCVec& s_new, RBCVec& ks_new, Vecint& ys_cats, RBCVec& yup_new, RBCVec& up_new, RBCVec& kup_new, + RBCVec& dys_new_dwl, RBCVec& dys_new_dwr, RBCVec& ds_new_dwl, RBCVec& ds_new_dwr, RBCVec& dks_new_dwl, RBCVec& dks_new_dwr, + RBCVec& ydks, RBCVec& dks, RBCVec& dydks_dwl, RBCVec& dydks_dwr, RBCVec& ddks_dwl, RBCVec& ddks_dwr, + RBCVec& ds, RBCVec& dds_dwl, RBCVec& dds_dwr); void interval_dists_K(const Vector& Yw, const Vector& W, const Vector& Yup_com, const Vector& Up_com, const Vector& Kup_com, const Vector& Ys_com, const Vector& S_com, const Vector& Ks_com, double ey, double beta_Dt, Vector& Ys, Vector& S, Vector& Ks, Vector& Yup_new, Vector& Up_new, Vector& Kup_new, @@ -570,14 +570,14 @@ class RockingBC : public Element // bilin - void commony_BL(const Vec& ya, const Vec& fa, const Vec& yb, const Vec& fb, Vec& Y, Vec& FA, Vec& FB); - bool distintersec(const Vec& YP, const Vec& P, const Vec& YQ, const Vec& Q); + void commony_BL(const RBCVec& ya, const RBCVec& fa, const RBCVec& yb, const RBCVec& fb, RBCVec& Y, RBCVec& FA, RBCVec& FB); + bool distintersec(const RBCVec& YP, const RBCVec& P, const RBCVec& YQ, const RBCVec& Q); bool twobilinintersec(double y1, double y2, double p1, double p2, double q1, double q2, double yp, double p0, double yq, double q0); - void NM_BL(const Vec& Y, const Vec& S, double& N, double& M, double& Nd, double& Md); + void NM_BL(const RBCVec& Y, const RBCVec& S, double& N, double& M, double& Nd, double& Md); bool bilinable(double Nd, double Md, double y1, double y2, double BILINLIM = 1.0e-18); - void bilindist(const Vec& Y, const Vec& S, double Nd, double Md, Vec& Ybl, Vec& Sbl, double BILINLIM = 1.0e-18); - bool bilin_two(const Vec& YP, const Vec& P, const Vec& YQ, const Vec& Q, Vec& YPn, Vec& Pn, Vec& YQn, Vec& Qn); - bool bilin_one(const Vec& YP, const Vec& P, Vec& YPn, Vec& Pn); + void bilindist(const RBCVec& Y, const RBCVec& S, double Nd, double Md, RBCVec& Ybl, RBCVec& Sbl, double BILINLIM = 1.0e-18); + bool bilin_two(const RBCVec& YP, const RBCVec& P, const RBCVec& YQ, const RBCVec& Q, RBCVec& YPn, RBCVec& Pn, RBCVec& YQn, RBCVec& Qn); + bool bilin_one(const RBCVec& YP, const RBCVec& P, RBCVec& YPn, RBCVec& Pn); diff --git a/SRC/element/TclElementCommands.cpp b/SRC/element/TclElementCommands.cpp index c1284896d..3a9e66a9d 100644 --- a/SRC/element/TclElementCommands.cpp +++ b/SRC/element/TclElementCommands.cpp @@ -160,6 +160,7 @@ extern void* OPS_BeamColumn3DwLHNMYS(void); extern void *OPS_ShellMITC4Thermal(void);//Added by L.Jiang [SIF] extern void *OPS_ShellNLDKGQThermal(void);//Added by L.Jiang [SIF] extern void *OPS_CatenaryCableElement(void); +extern void *OPS_ASDEmbeddedNodeElement(void); // Massimo Petracca (ASDEA) extern void *OPS_ShellANDeS(void); extern void *OPS_FourNodeTetrahedron(void); extern void *OPS_LysmerTriangle(void); @@ -185,8 +186,13 @@ extern void *OPS_RJWatsonEQS3d(void); //extern void* OPS_GradientInelasticBeamColumn2d(); //extern void* OPS_GradientInelasticBeamColumn3d(); extern void *OPS_RockingBC(void); - extern void* OPS_LehighJoint2d(void); +extern void *OPS_MasonPan12(void); +extern void *OPS_MasonPan3D(void); +extern void *OPS_BeamGT(void); + +extern void* OPS_DispBeamColumnAsym3dTcl(); //Xinlong Du +extern void* OPS_MixedBeamColumnAsym3dTcl(); //Xinlong Du extern int TclModelBuilder_addFeapTruss(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv, Domain*, TclModelBuilder *, int argStart); @@ -286,6 +292,18 @@ extern int TclModelBuilder_addForceBeamColumn(ClientData, Tcl_Interp *, int, TCL_Char **, Domain*, TclModelBuilder *); +extern int +TclModelBuilder_addMasonPan12(ClientData , Tcl_Interp *, int argc, + TCL_Char **argv, Domain*, TclModelBuilder *); + +extern int +TclModelBuilder_addMasonPan3D(ClientData , Tcl_Interp *, int argc, + TCL_Char **argv, Domain*, TclModelBuilder *); + +extern int +TclModelBuilder_addBeamGT(ClientData , Tcl_Interp *, int argc, + TCL_Char **argv, Domain*, TclModelBuilder *); + // NM extern int TclModelBuilder_addBeamColumnJoint(ClientData, Tcl_Interp *, int, TCL_Char **, Domain*, int); @@ -789,6 +807,42 @@ 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], "MasonPan12") == 0)) { + + void *theEle = OPS_MasonPan12(); + + 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], "MasonPan3D") == 0)) { + + void *theEle = OPS_MasonPan3D(); + + 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], "BeamGT") == 0)) { + + void *theEle = OPS_BeamGT(); + + 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],"MultiFP2d") == 0) || (strcmp(argv[1],"MultiFPB2d") == 0)){ @@ -1193,6 +1247,17 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, } } + else if (strcmp(argv[1], "ASDEmbeddedNodeElement") == 0) { + void *theEle = OPS_ASDEmbeddedNodeElement(); + if (theEle != 0) { + theElement = (Element*)theEle; + } else { + opserr<<"tclelementcommand -- unable to create element of type : " + <addElement(theElement) == false) { diff --git a/SRC/element/UP-ucsd/BBarBrickUP.h b/SRC/element/UP-ucsd/BBarBrickUP.h index 135004d2d..346a5b545 100644 --- a/SRC/element/UP-ucsd/BBarBrickUP.h +++ b/SRC/element/UP-ucsd/BBarBrickUP.h @@ -136,6 +136,7 @@ class BBarBrickUP : public Element { // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet private : diff --git a/SRC/element/UP-ucsd/BBarFourNodeQuadUP.h b/SRC/element/UP-ucsd/BBarFourNodeQuadUP.h index 99374e677..b2e9a7525 100644 --- a/SRC/element/UP-ucsd/BBarFourNodeQuadUP.h +++ b/SRC/element/UP-ucsd/BBarFourNodeQuadUP.h @@ -83,6 +83,7 @@ class BBarFourNodeQuadUP : public Element // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/element/UP-ucsd/BrickUP.h b/SRC/element/UP-ucsd/BrickUP.h index fd03b9bcd..996288ccb 100644 --- a/SRC/element/UP-ucsd/BrickUP.h +++ b/SRC/element/UP-ucsd/BrickUP.h @@ -134,6 +134,7 @@ class BrickUP : public Element { // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet private : diff --git a/SRC/element/UP-ucsd/FourNodeQuadUP.h b/SRC/element/UP-ucsd/FourNodeQuadUP.h index dc1697531..e26376b68 100644 --- a/SRC/element/UP-ucsd/FourNodeQuadUP.h +++ b/SRC/element/UP-ucsd/FourNodeQuadUP.h @@ -78,9 +78,9 @@ class FourNodeQuadUP : public Element 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; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/element/UP-ucsd/Nine_Four_Node_QuadUP.h b/SRC/element/UP-ucsd/Nine_Four_Node_QuadUP.h index 5201de0c4..828aaf864 100644 --- a/SRC/element/UP-ucsd/Nine_Four_Node_QuadUP.h +++ b/SRC/element/UP-ucsd/Nine_Four_Node_QuadUP.h @@ -83,6 +83,7 @@ class NineFourNodeQuadUP : public Element // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/element/UP-ucsd/Nine_Four_Node_QuadUPOld.h b/SRC/element/UP-ucsd/Nine_Four_Node_QuadUPOld.h index 53d53f40d..01ba988cb 100644 --- a/SRC/element/UP-ucsd/Nine_Four_Node_QuadUPOld.h +++ b/SRC/element/UP-ucsd/Nine_Four_Node_QuadUPOld.h @@ -83,6 +83,7 @@ class NineFourNodeQuadUP : public Element // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/element/UP-ucsd/Twenty_Eight_Node_BrickUP.h b/SRC/element/UP-ucsd/Twenty_Eight_Node_BrickUP.h index 7b18d873b..2cd0a4ceb 100644 --- a/SRC/element/UP-ucsd/Twenty_Eight_Node_BrickUP.h +++ b/SRC/element/UP-ucsd/Twenty_Eight_Node_BrickUP.h @@ -136,6 +136,7 @@ public : // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet private : //static data diff --git a/SRC/element/UWelements/SSPbrick.cpp b/SRC/element/UWelements/SSPbrick.cpp index b2cc7986e..9e0e14acc 100644 --- a/SRC/element/UWelements/SSPbrick.cpp +++ b/SRC/element/UWelements/SSPbrick.cpp @@ -1366,6 +1366,7 @@ SSPbrick::GetStab(void) // constitutive constants from material const Matrix &CmatI = theMaterial->getInitialTangent(); + double C1 = CmatI(0,0); double C2 = CmatI(0,1); double C3 = CmatI(3,3); diff --git a/SRC/element/UWelements/SSPquad.h b/SRC/element/UWelements/SSPquad.h index 63814377c..510f557f6 100644 --- a/SRC/element/UWelements/SSPquad.h +++ b/SRC/element/UWelements/SSPquad.h @@ -91,8 +91,9 @@ class SSPquad : public Element int updateParameter(int parameterID, Information &info); // allow PyLiq1 and TzLiq1 classes to get stresses from SSPquadUP class - friend class PyLiq1; - friend class TzLiq1; + friend class PyLiq1; + friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/element/UWelements/SSPquadUP.h b/SRC/element/UWelements/SSPquadUP.h index bf246b283..5f0040bd5 100644 --- a/SRC/element/UWelements/SSPquadUP.h +++ b/SRC/element/UWelements/SSPquadUP.h @@ -108,6 +108,7 @@ class SSPquadUP : public Element // allow PyLiq1 and TzLiq1 classes to get stresses from SSPquadUP class friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/element/UWelements/SimpleContact3D.cpp b/SRC/element/UWelements/SimpleContact3D.cpp index df3ddf498..ea7b27e50 100644 --- a/SRC/element/UWelements/SimpleContact3D.cpp +++ b/SRC/element/UWelements/SimpleContact3D.cpp @@ -1158,10 +1158,10 @@ SimpleContact3D::Print(OPS_Stream &s, int flag) Response* -SimpleContact3D::setResponse(const char **argv, int argc, OPS_Stream &eleInfo) +SimpleContact3D::setResponse(const char **argv, int argc, OPS_Stream &output) { #ifdef DEBUG - opserr << "SimpleContact3D::setResponse(const char **argv, int argc, Information &eleInfo): " << MyTag << endln; + opserr << "SimpleContact3D::setResponse(const char **argv, int argc, OPS_Stream &output): " << MyTag << endln; #endif if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) return new ElementResponse(this, 1, Vector(3)); diff --git a/SRC/element/XMUelements/AC3D8HexWithSensitivity.h b/SRC/element/XMUelements/AC3D8HexWithSensitivity.h index ca80895d8..e298ca196 100644 --- a/SRC/element/XMUelements/AC3D8HexWithSensitivity.h +++ b/SRC/element/XMUelements/AC3D8HexWithSensitivity.h @@ -93,7 +93,7 @@ class AC3D8HexWithSensitivity: public Element int recvSelf (int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); - Response *setResponse (const char **argv, int argc, OPS_Stream &matInformation); + Response *setResponse (const char **argv, int argc, OPS_Stream &output); int getResponse (int responseID, Information &matInformation); int displaySelf(Renderer &theViewer, int displayMode, float fact, const char **modes, int numMode); diff --git a/SRC/element/absorbentBoundaries/LysmerTriangle.cpp b/SRC/element/absorbentBoundaries/LysmerTriangle.cpp index 7be7c9dc1..761e2dc65 100644 --- a/SRC/element/absorbentBoundaries/LysmerTriangle.cpp +++ b/SRC/element/absorbentBoundaries/LysmerTriangle.cpp @@ -721,15 +721,15 @@ LysmerTriangle::Print(OPS_Stream &s, int flag) } Response* -LysmerTriangle::setResponse(const char **argv, int argc, Information &eleInfo) +LysmerTriangle::setResponse(const char **argv, int argc, OPS_Stream &output) { - return 0; + return Element::setResponse(argv, argc, output); } int LysmerTriangle::getResponse(int responseID, Information &eleInfo) { - return -1; + return Element::getResponse(responseID, eleInfo); } diff --git a/SRC/element/absorbentBoundaries/LysmerTriangle.h b/SRC/element/absorbentBoundaries/LysmerTriangle.h index 31e18e21c..a4f1861fd 100644 --- a/SRC/element/absorbentBoundaries/LysmerTriangle.h +++ b/SRC/element/absorbentBoundaries/LysmerTriangle.h @@ -90,7 +90,7 @@ class LysmerTriangle : public Element void Print(OPS_Stream &s, int flag =0); - Response *setResponse(const char **argv, int argc, Information &eleInfo); + Response *setResponse(const char **argv, int argc, OPS_Stream &output); int getResponse(int responseID, Information &eleInformation); int setParameter(const char **argv, int argc, Parameter ¶m); diff --git a/SRC/element/dispBeamColumn/DispBeamColumn2d.cpp b/SRC/element/dispBeamColumn/DispBeamColumn2d.cpp index 4dbbf3b34..32b31a370 100644 --- a/SRC/element/dispBeamColumn/DispBeamColumn2d.cpp +++ b/SRC/element/dispBeamColumn/DispBeamColumn2d.cpp @@ -1603,6 +1603,9 @@ DispBeamColumn2d::setResponse(const char **argv, int argc, else if (strcmp(argv[0],"integrationWeights") == 0) return new ElementResponse(this, 8, Vector(numSections)); + else if (strcmp(argv[0],"sectionTags") == 0) + theResponse = new ElementResponse(this, 110, ID(numSections)); + else if (strcmp(argv[0], "energy") == 0) //by SAJalali { return new ElementResponse(this, 10, 0.0); @@ -1735,6 +1738,14 @@ DispBeamColumn2d::getResponse(int responseID, Information &eleInfo) weights(i) = wt[i]*L; return eleInfo.setVector(weights); } + + else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = theSections[i]->getTag(); + return eleInfo.setID(tags); + } + //by SAJalali else if (responseID == 10) { double xi[maxNumSections]; diff --git a/SRC/element/dispBeamColumn/DispBeamColumn3d.cpp b/SRC/element/dispBeamColumn/DispBeamColumn3d.cpp index 565ef8a31..ec1114e8c 100644 --- a/SRC/element/dispBeamColumn/DispBeamColumn3d.cpp +++ b/SRC/element/dispBeamColumn/DispBeamColumn3d.cpp @@ -1382,6 +1382,9 @@ 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],"sectionTags") == 0) + theResponse = new ElementResponse(this, 110, ID(numSections)); + else if (strcmp(argv[0],"xaxis") == 0 || strcmp(argv[0],"xlocal") == 0) theResponse = new ElementResponse(this, 201, Vector(3)); @@ -1557,6 +1560,13 @@ DispBeamColumn3d::getResponse(int responseID, Information &eleInfo) return eleInfo.setVector(weights); } + else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = theSections[i]->getTag(); + return eleInfo.setID(tags); + } + else if (responseID >= 201 && responseID <= 203) { static Vector xlocal(3); static Vector ylocal(3); diff --git a/SRC/element/dispBeamColumn/DispBeamColumnAsym3d.cpp b/SRC/element/dispBeamColumn/DispBeamColumnAsym3d.cpp new file mode 100644 index 000000000..a1d05653c --- /dev/null +++ b/SRC/element/dispBeamColumn/DispBeamColumnAsym3d.cpp @@ -0,0 +1,2324 @@ +/* ****************************************************************** ** +** 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$ +// $URL$ + +// Written: MHS +// Created: Feb 2001 +// +// Description: This file contains the class definition for DispBeamColumnAsym3d. + +// Modified by: Xinlong Du and Jerome F. Hajjar, Northeastern University, USA; Year 2019 +// Description: Adapted for analysis of asymmetric sections with introducing +// high-order axial terms for the basic element formulation +// References: +// Du, X., & Hajjar, J. (2021). Three-dimensional nonlinear displacement-based beam element +// for members with angle and tee sections. Engineering Structures, 239, 112239. + +#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 + +Matrix DispBeamColumnAsym3d::K(12,12); +Vector DispBeamColumnAsym3d::P(12); +double DispBeamColumnAsym3d::workArea[200]; + +void* OPS_DispBeamColumnAsym3d() +{ + 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; + double dData[2]; //input of ys and zs + dData[0] = 0.0; + dData[1] = 0.0; + 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; + } + } + } else if (strcmp(type, "-shearCenter") == 0) { + // Get the coordinates of shear center w.r.t centroid + numData = 2; + if (OPS_GetDoubleInput(&numData, dData) < 0) { + opserr << "WARNING: invalid ys and zs\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 0) { + const char *sData = OPS_GetString(); + + if (strcmp(sData, "-cMass") == 0) { + cmass = 1; + } + else if (strcmp(sData, "-mass") == 0) { + numData = 1; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING invalid input, want: -mass $massDens \n"; + return 0; + } + massDens = dData[0]; + + } + else if (strcmp(sData, "-integration") == 0) { + const char *sData2 = OPS_GetString(); + + 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; + } + } + else if (strcmp(sData, "-shearCenter") == 0) { + // Get the coordinates of shear center w.r.t centroid + numData = 2; + if (OPS_GetDoubleInput(&numData, &dData2[0]) < 0) { + opserr << "WARNING: invalid ys and zs\n"; + return 0; + } + } + else { + opserr << "WARNING unknown option " << sData << "\n"; + } + } + + // 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 DispBeamColumnAsym3d(eleTag, nodeI, nodeJ, numIntgrPts, sections, *beamIntegr, *theTransf, + dData2[0], dData2[1], massDens, cmass); + + if (theElement == 0) { + opserr << "WARNING ran out of memory creating element with tag " << eleTag << endln; + return 0; + } + + delete[] sections; + if (beamIntegr != 0) + delete beamIntegr; + + return theElement; +} + +DispBeamColumnAsym3d::DispBeamColumnAsym3d(int tag, int nd1, int nd2, + int numSec, SectionForceDeformation **s, + BeamIntegration &bi, + CrdTransf &coordTransf, double yss, double zss, double r, int cm) //Xinlong +:Element (tag, ELE_TAG_DispBeamColumnAsym3d), +numSections(numSec), theSections(0), crdTransf(0), beamInt(0), +connectedExternalNodes(2), +Q(12), q(6), ys(yss), zs(zss), rho(r), cMass(cm), parameterID(0) //Xinlong +{ + // Allocate arrays of pointers to SectionForceDeformations + theSections = new SectionForceDeformation *[numSections]; + + if (theSections == 0) { + opserr << "DispBeamColumnAsym3d::DispBeamColumnAsym3d - 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 << "DispBeamColumnAsym3d::DispBeamColumnAsym3d -- failed to get a copy of section model\n"; + exit(-1); + } + } + + beamInt = bi.getCopy(); + + if (beamInt == 0) { + opserr << "DispBeamColumnAsym3d::DispBeamColumnAsym3d - failed to copy beam integration\n"; + exit(-1); + } + + crdTransf = coordTransf.getCopy3d(); + + if (crdTransf == 0) { + opserr << "DispBeamColumnAsym3d::DispBeamColumnAsym3d - 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; +} + +DispBeamColumnAsym3d::DispBeamColumnAsym3d() +:Element (0, ELE_TAG_DispBeamColumnAsym3d), +numSections(0), theSections(0), crdTransf(0), beamInt(0), +connectedExternalNodes(2), +Q(12), q(6), ys(0.0), zs(0.0), rho(0.0), cMass(0), parameterID(0) //Xinlong +{ + 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; +} + +DispBeamColumnAsym3d::~DispBeamColumnAsym3d() +{ + 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 +DispBeamColumnAsym3d::getNumExternalNodes() const +{ + return 2; +} + +const ID& +DispBeamColumnAsym3d::getExternalNodes() +{ + return connectedExternalNodes; +} + +Node ** +DispBeamColumnAsym3d::getNodePtrs() +{ + + return theNodes; +} + +int +DispBeamColumnAsym3d::getNumDOF() +{ + return 12; +} + +void +DispBeamColumnAsym3d::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 DispBeamColumnAsym3d (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 DispBeamColumnAsym3d (tag: %d), has differing number of DOFs at its nodes", + // this->getTag()); + + return; + } + + 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 +DispBeamColumnAsym3d::commitState() +{ + int retVal = 0; + + // call element commitState to do any base class stuff + if ((retVal = this->Element::commitState()) != 0) { + opserr << "DispBeamColumnAsym3d::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 +DispBeamColumnAsym3d::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 +DispBeamColumnAsym3d::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 +DispBeamColumnAsym3d::update(void) +{ + int err = 0; + + // Update the transformation + crdTransf->update(); + + // Get basic deformations + const Vector &v = crdTransf->getBasicTrialDisp(); + + 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, 5); + + double xi1 = xi[i]; + double dNv1 = 1.0 + 3.0*xi1*xi1 - 4.0*xi1; + double ddNv1 = 6.0*xi1*oneOverL - 4.0*oneOverL; + double dNv2 = 3.0*xi1*xi1 - 2.0*xi1; + double ddNv2 = 6.0*xi1*oneOverL - 2.0*oneOverL; + double dNw1 = -dNv1; + double ddNw1 = -ddNv1; + double dNw2 = -dNv2; + double ddNw2 = -ddNv2; + double Nf1 = xi1; + + //generalized strain + double s0 = oneOverL * v(0); //u' + double s1 = ddNv1 * v(1) + ddNv2 * v(2); //v" + double s2 = ddNw1 * v(3) + ddNw2 * v(4); //w" + double s3 = oneOverL * v(5); //phi' + double s4 = dNv1 * v(1) + dNv2 * v(2); //v' + double s5 = dNw1 * v(3) + dNw2 * v(4); //w' + double s6 = Nf1 * v(5); //phi + double s7 = v(1); //theta_Iz + double s8 = v(3); //theta_Iy + double s9 = v(2); //theta_Jz + double s10 = v(4); //theta_Jy + + //section deformation to be sent to FiberSection + e(0) = s0 + (4.0*s7*s7 + 4.0*s8*s8 + 4.0*s9*s9 + 4.0*s10*s10 - 2.0*s7*s9 - 2.0*s8*s10) / 60.0 + (zs*s4 - ys * s5)*s3; + e(1) = s1 + s2 * s6; + e(2) = -s2 + s1 * s6; + e(3) = 0.5*s3*s3; + e(4) = s3; + + // Set the section deformations + err += theSections[i]->setTrialSectionDeformation(e); + } + + if (err != 0) { + opserr << "DispBeamColumnAsym3d::update() - failed setTrialSectionDeformations()\n"; + return err; + } + return 0; +} + +const Matrix& +DispBeamColumnAsym3d::getTangentStiff() +{ + //double zs = 0.6385; //z coord of shear center w.r.t. centroid + //double ys = -0.6741; //y coord of shear center w.r.t. centroid + + static Matrix kb(6,6); + static Matrix N1(5, 11); //Xinlong + static Matrix N2(11, 6); //Xinlong + static Matrix N3(11, 11); //Xinlong + static Matrix kbPart1(6, 6); + static Matrix Gmax(11, 11); + static Matrix kbPart2(6, 6); + static Matrix Tr(6, 6); + static Matrix kf1(6, 6); + static Matrix kf2(6, 6); + + const Vector &v = crdTransf->getBasicTrialDisp(); + + // 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++) { + + N1.Zero(); + N2.Zero(); + N3.Zero(); + kbPart1.Zero(); + kbPart2.Zero(); + Gmax.Zero(); + + Tr.Zero(); + kf1.Zero(); + kf2.Zero(); + + double xi1 = xi[i]; + double dNv1 = 1.0 + 3.0*xi1*xi1 - 4.0*xi1; + double ddNv1 = 6.0*xi1*oneOverL - 4.0*oneOverL; + double dNv2 = 3.0*xi1*xi1 - 2.0*xi1; + double ddNv2 = 6.0*xi1*oneOverL - 2.0*oneOverL; + double dNw1 = -dNv1; + double ddNw1 = -ddNv1; + double dNw2 = -dNv2; + double ddNw2 = -ddNv2; + double Nf1 = xi1; + + double dv = dNv1 * v(1) + dNv2 * v(2); //v' + double ddv = ddNv1 * v(1) + ddNv2 * v(2); //v" + double dw = dNw1 * v(3) + dNw2 * v(4); //w' + double ddw = ddNw1 * v(3) + ddNw2 * v(4); //w" + double f = Nf1 * v(5); //phi + double df = oneOverL * v(5); //phi' + + //Matrix Ndeltad1------------------------------------------------------- + N1(0, 0) = 1.0; + N1(0, 1) = (4.0*v(1) - v(2)) / 30.0; + N1(0, 2) = (4.0*v(3) - v(4)) / 30.0; + N1(0, 3) = (4.0*v(2) - v(1)) / 30.0; + N1(0, 4) = (4.0*v(4) - v(3)) / 30.0; + N1(0, 5) = zs * df; + N1(0, 6) = - ys * df; + N1(0, 10) = zs * dv - ys * dw; + N1(1, 7) = 1.0; + N1(1, 8) = f; + N1(1, 9) = ddw; + N1(2, 7) = f; + N1(2, 8) = -1.0; + N1(2, 9) = ddv; + N1(3, 10) = df; + N1(4, 10) = 1.0; + + //Matrix Ndeltad2------------------------------------------------------- + N2(0, 0) = oneOverL; + N2(1, 1) = 1.0; + N2(2, 3) = 1.0; + N2(3, 2) = 1.0; + N2(4, 4) = 1.0; + N2(5, 1) = dNv1; + N2(5, 2) = dNv2; + N2(6, 3) = dNw1; + N2(6, 4) = dNw2; + N2(7, 1) = ddNv1; + N2(7, 2) = ddNv2; + N2(8, 3) = ddNw1; + N2(8, 4) = ddNw2; + N2(9, 5) = Nf1; + N2(10, 5) = oneOverL; + + //Transformation matrix - transform axial force form centroid to shear center + Tr(0, 0) = 1.0; + Tr(1, 1) = 1.0; + Tr(2, 2) = 1.0; + Tr(3, 3) = 1.0; + Tr(4, 4) = 1.0; + Tr(5, 5) = 1.0; + Tr(0, 1) = -ys; + Tr(0, 2) = ys; + Tr(0, 3) = zs; + Tr(0, 4) = -zs; + + // Get the section tangent stiffness and stress resultant + const Matrix &ks = theSections[i]->getSectionTangent(); + const Vector &s = theSections[i]->getStressResultant(); + + //calculate kbPart1 - material stiffness matrix + N3.addMatrixTripleProduct(0.0, N1, ks, 1.0); + kbPart1.addMatrixTripleProduct(0.0, N2, N3, 1.0); + + //calculate kbPart2 - geometric stiffness matrix + Gmax(1, 1) = Gmax(2, 2) = Gmax(3, 3) = Gmax(4, 4) = s(0)*4.0 / 30.0; // 4/30*N + Gmax(1, 3) = Gmax(2, 4) = Gmax(3, 1) = Gmax(4, 2) = -s(0) / 30.0; // -1/30*N + Gmax(9, 8) = Gmax(8, 9) = s(1); //Mz + Gmax(9, 7) = Gmax(7, 9) = s(2); //My + Gmax(10, 5) = Gmax(5, 10) = s(0)*zs; //Nzs + Gmax(10, 6) = Gmax(6, 10) = -s(0)*ys; //-Nys + Gmax(10, 10) = s(3); //W + + kbPart2.addMatrixTripleProduct(0.0, N2, Gmax, 1.0); + + //perform transformation - transform axial force form centroid to shear center + kf1.addMatrixTripleProduct(0.0, Tr, kbPart1, 1.0); + kf2.addMatrixTripleProduct(0.0, Tr, kbPart2, 1.0); + + //perform numerical integration + double wti = wt[i]; + for (int j = 0; j < 6; j++) { + for (int k = 0; k < 6; k++) { + kb(j, k) += kf1(j, k)*L*wti + kf2(j, k)*L*wti; + } + } + + //assemble internal force vector q + static Vector qProduct1(11); + static Vector qProduct2(6); + static Vector qProduct3(6); + qProduct1.Zero(); + qProduct2.Zero(); + qProduct3.Zero(); + qProduct1.addMatrixTransposeVector(0.0, N1, s, 1.0); + qProduct2.addMatrixTransposeVector(0.0, N2, qProduct1, 1.0); + qProduct3.addMatrixTransposeVector(0.0, Tr, qProduct2, 1.0); + + for (int j = 0; j < 6; j++) { + q(j) += qProduct3(j)*L*wti; + } + } + + 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& +DispBeamColumnAsym3d::getInitialBasicStiff() +{ + //double zs = 0.6385; //z coord of shear center w.r.t. centroid + //double ys = -0.6741; //y coord of shear center w.r.t. centroid + + static Matrix kb(6,6); + static Matrix N1(5, 11); //Xinlong + static Matrix N2(11, 6); //Xinlong + static Matrix N3(11, 11); //Xinlong + static Matrix kbPart1(6, 6); + static Matrix Gmax(11, 11); + static Matrix kbPart2(6, 6); + static Matrix Tr(6, 6); + static Matrix kf1(6, 6); + static Matrix kf2(6, 6); + + // Zero for integral + kb.Zero(); + + const Vector &v = crdTransf->getBasicTrialDisp(); + + 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++) { + + N1.Zero(); + N2.Zero(); + N3.Zero(); + kbPart1.Zero(); + kbPart2.Zero(); + Gmax.Zero(); + + Tr.Zero(); + kf1.Zero(); + kf2.Zero(); + + double xi1 = xi[i]; + double dNv1 = 1.0 + 3.0*xi1*xi1 - 4.0*xi1; + double ddNv1 = 6.0*xi1*oneOverL - 4.0*oneOverL; + double dNv2 = 3.0*xi1*xi1 - 2.0*xi1; + double ddNv2 = 6.0*xi1*oneOverL - 2.0*oneOverL; + double dNw1 = -dNv1; + double ddNw1 = -ddNv1; + double dNw2 = -dNv2; + double ddNw2 = -ddNv2; + double Nf1 = xi1; + + double dv = dNv1 * v(1) + dNv2 * v(2); //v' + double ddv = ddNv1 * v(1) + ddNv2 * v(2); //v" + double dw = dNw1 * v(3) + dNw2 * v(4); //w' + double ddw = ddNw1 * v(3) + ddNw2 * v(4); //w" + double f = Nf1 * v(5); //phi + double df = oneOverL * v(5); //phi' + + //Matrix Ndeltad1------------------------------------------------------- + N1(0, 0) = 1.0; + N1(0, 1) = (4.0*v(1) - v(2)) / 30.0; + N1(0, 2) = (4.0*v(3) - v(4)) / 30.0; + N1(0, 3) = (4.0*v(2) - v(1)) / 30.0; + N1(0, 4) = (4.0*v(4) - v(3)) / 30.0; + N1(0, 5) = zs * df; + N1(0, 6) = -ys * df; + N1(0, 10) = zs * dv - ys * dw; + N1(1, 7) = 1.0; + N1(1, 8) = f; + N1(1, 9) = ddw; + N1(2, 7) = f; + N1(2, 8) = -1.0; + N1(2, 9) = ddv; + N1(3, 10) = df; + N1(4, 10) = 1.0; + + //Matrix Ndeltad2------------------------------------------------------- + N2(0, 0) = oneOverL; + N2(1, 1) = 1.0; + N2(2, 3) = 1.0; + N2(3, 2) = 1.0; + N2(4, 4) = 1.0; + N2(5, 1) = dNv1; + N2(5, 2) = dNv2; + N2(6, 3) = dNw1; + N2(6, 4) = dNw2; + N2(7, 1) = ddNv1; + N2(7, 2) = ddNv2; + N2(8, 3) = ddNw1; + N2(8, 4) = ddNw2; + N2(9, 5) = Nf1; + N2(10, 5) = oneOverL; + + //Transformation matrix - transform axial force form centroid to shear center + Tr(0, 0) = 1.0; + Tr(1, 1) = 1.0; + Tr(2, 2) = 1.0; + Tr(3, 3) = 1.0; + Tr(4, 4) = 1.0; + Tr(5, 5) = 1.0; + Tr(0, 1) = -ys; + Tr(0, 2) = ys; + Tr(0, 3) = zs; + Tr(0, 4) = -zs; + + // Get the section tangent stiffness and stress resultant + const Matrix &ks = theSections[i]->getInitialTangent(); + const Vector &s = theSections[i]->getStressResultant(); + + //calculate kbPart1 - material stiffness matrix + N3.addMatrixTripleProduct(0.0, N1, ks, 1.0); + kbPart1.addMatrixTripleProduct(0.0, N2, N3, 1.0); + + //calculate kbPart2 - geometric stiffness matrix + Gmax(1, 1) = Gmax(2, 2) = Gmax(3, 3) = Gmax(4, 4) = s(0)*4.0 / 30.0; // 4/30*N + Gmax(1, 3) = Gmax(2, 4) = Gmax(3, 1) = Gmax(4, 2) = -s(0) / 30.0; // -1/30*N + Gmax(9, 8) = Gmax(8, 9) = s(1); //Mz + Gmax(9, 7) = Gmax(7, 9) = s(2); //My + Gmax(10, 5) = Gmax(5, 10) = s(0)*zs; //Nzs + Gmax(10, 6) = Gmax(6, 10) = -s(0)*ys; //-Nys + Gmax(10, 10) = s(3); //W + + kbPart2.addMatrixTripleProduct(0.0, N2, Gmax, 1.0); + + //perform transformation - transform axial force form centroid to shear center + kf1.addMatrixTripleProduct(0.0, Tr, kbPart1, 1.0); + kf2.addMatrixTripleProduct(0.0, Tr, kbPart2, 1.0); + + //perform numerical integration + double wti = wt[i]; + for (int j = 0; j < 6; j++) { + for (int k = 0; k < 6; k++) { + kb(j, k) += kf1(j, k)*L*wti + kf2(j, k)*L*wti; + } + } + + } + + return kb; +} + +const Matrix& +DispBeamColumnAsym3d::getInitialStiff() +{ + const Matrix &kb = this->getInitialBasicStiff(); + + // Transform to global stiffness + K = crdTransf->getInitialGlobalStiffMatrix(kb); + + return K; +} + +const Matrix& +DispBeamColumnAsym3d::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 +DispBeamColumnAsym3d::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 +DispBeamColumnAsym3d::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 << "DispBeamColumnAsym3d::addLoad() -- load type unknown for element with tag: " << + this->getTag() << endln; + return -1; + } + + return 0; +} + +int +DispBeamColumnAsym3d::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 << "DispBeamColumnAsym3d::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& +DispBeamColumnAsym3d::getResistingForce() +{ + //double zs = 0.6385; //z coord of shear center w.r.t. centroid + //double ys = -0.6741; //y coord of shear center w.r.t. centroid + + static Matrix N1(5, 11); //Xinlong + static Matrix N2(11, 6); //Xinlong + static Matrix Tr(6, 6); + + const Vector &v = crdTransf->getBasicTrialDisp(); + + // Zero for integral + 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++) { + + N1.Zero(); + N2.Zero(); + Tr.Zero(); + + double xi1 = xi[i]; + double dNv1 = 1.0 + 3.0*xi1*xi1 - 4.0*xi1; + double ddNv1 = 6.0*xi1*oneOverL - 4.0*oneOverL; + double dNv2 = 3.0*xi1*xi1 - 2.0*xi1; + double ddNv2 = 6.0*xi1*oneOverL - 2.0*oneOverL; + double dNw1 = -dNv1; + double ddNw1 = -ddNv1; + double dNw2 = -dNv2; + double ddNw2 = -ddNv2; + double Nf1 = xi1; + + double dv = dNv1 * v(1) + dNv2 * v(2); //v' + double ddv = ddNv1 * v(1) + ddNv2 * v(2); //v" + double dw = dNw1 * v(3) + dNw2 * v(4); //w' + double ddw = ddNw1 * v(3) + ddNw2 * v(4); //w" + double f = Nf1 * v(5); //phi + double df = oneOverL * v(5); //phi' + + //Matrix Ndeltad1------------------------------------------------------- + N1(0, 0) = 1.0; + N1(0, 1) = (4.0*v(1) - v(2)) / 30.0; + N1(0, 2) = (4.0*v(3) - v(4)) / 30.0; + N1(0, 3) = (4.0*v(2) - v(1)) / 30.0; + N1(0, 4) = (4.0*v(4) - v(3)) / 30.0; + N1(0, 5) = zs * df; + N1(0, 6) = -ys * df; + N1(0, 10) = zs * dv - ys * dw; + N1(1, 7) = 1.0; + N1(1, 8) = f; + N1(1, 9) = ddw; + N1(2, 7) = f; + N1(2, 8) = -1.0; + N1(2, 9) = ddv; + N1(3, 10) = df; + N1(4, 10) = 1.0; + + //Matrix Ndeltad2------------------------------------------------------- + N2(0, 0) = oneOverL; + N2(1, 1) = 1.0; + N2(2, 3) = 1.0; + N2(3, 2) = 1.0; + N2(4, 4) = 1.0; + N2(5, 1) = dNv1; + N2(5, 2) = dNv2; + N2(6, 3) = dNw1; + N2(6, 4) = dNw2; + N2(7, 1) = ddNv1; + N2(7, 2) = ddNv2; + N2(8, 3) = ddNw1; + N2(8, 4) = ddNw2; + N2(9, 5) = Nf1; + N2(10, 5) = oneOverL; + + //Transformation matrix - transform axial force form centroid to shear center + Tr(0, 0) = 1.0; + Tr(1, 1) = 1.0; + Tr(2, 2) = 1.0; + Tr(3, 3) = 1.0; + Tr(4, 4) = 1.0; + Tr(5, 5) = 1.0; + Tr(0, 1) = -ys; + Tr(0, 2) = ys; + Tr(0, 3) = zs; + Tr(0, 4) = -zs; + + // Get the section stress resultant + const Vector &s = theSections[i]->getStressResultant(); + + //perform numerical integration + double wti = wt[i]; + + //assemble internal force vector q + static Vector qProduct1(11); + static Vector qProduct2(6); + static Vector qProduct3(6); + qProduct1.Zero(); + qProduct2.Zero(); + qProduct3.Zero(); + qProduct1.addMatrixTransposeVector(0.0, N1, s, 1.0); + qProduct2.addMatrixTransposeVector(0.0, N2, qProduct1, 1.0); + qProduct3.addMatrixTransposeVector(0.0, Tr, qProduct2, 1.0); + + for (int j = 0; j < 6; j++) { + q(j) += qProduct3(j)*L*wti; + } + + } + + 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& +DispBeamColumnAsym3d::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 +DispBeamColumnAsym3d::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(16); + 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) = ys; + data(15) = zs; + + if (theChannel.sendVector(dbTag, commitTag, data) < 0) { + opserr << "DispBeamColumnAsym3d::sendSelf() - failed to send data Vector\n"; + return -1; + } + + // send the coordinate transformation + if (crdTransf->sendSelf(commitTag, theChannel) < 0) { + opserr << "DispBeamColumnAsym3d::sendSelf() - failed to send crdTranf\n"; + return -1; + } + + // send the beam integration + if (beamInt->sendSelf(commitTag, theChannel) < 0) { + opserr << "DispBeamColumnAsym3d::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; igetClassTag(); + 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 << "DispBeamColumnAsym3d::sendSelf() - failed to send ID data\n"; + return -1; + } + + // + // send the sections + // + + for (j = 0; jsendSelf(commitTag, theChannel) < 0) { + opserr << "DispBeamColumnAsym3d::sendSelf() - section " << j << "failed to send itself\n"; + return -1; + } + } + + return 0; +} + +int +DispBeamColumnAsym3d::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(16); + + if (theChannel.recvVector(dbTag, commitTag, data) < 0) { + opserr << "DispBeamColumnAsym3d::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); + ys = data(14); + zs = data(15); + + // 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 << "DispBeamColumnAsym3d::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 << "DispBeamColumnAsym3d::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 << "DispBeamColumnAsym3d::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 << "DispBeamColumnAsym3d::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 << "DispBeamColumnAsym3d::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; isetDbTag(sectDbTag); + if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "DispBeamColumnAsym3d::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; igetClassTag() != sectClassTag) { + // delete the old section[i] and create a new one + delete theSections[i]; + theSections[i] = theBroker.getNewSection(sectClassTag); + if (theSections[i] == 0) { + opserr << "DispBeamColumnAsym3d::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 << "DispBeamColumnAsym3d::recvSelf() - section " << + i << "failed to recv itself\n"; + return -1; + } + } + } + + return 0; +} + +void +DispBeamColumnAsym3d::Print(OPS_Stream &s, int flag) +{ + if (flag == OPS_PRINT_CURRENTSTATE) { + s << "\nDispBeamColumnAsym3d, element id: " << this->getTag() << endln; + s << "\tConnected external nodes: " << connectedExternalNodes; + s << "\tCoordTransf: " << crdTransf->getTag() << endln; + s << "\tmass density: " << rho << ", cMass: " << cMass << 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; + + 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\": \"DispBeamColumnAsym3d\", "; + s << "\"nodes\": [" << connectedExternalNodes(0) << ", " << connectedExternalNodes(1) << "], "; + s << "\"sections\": ["; + for (int i = 0; i < numSections - 1; i++) + s << "\"" << theSections[i]->getTag() << "\", "; + s << "\"" << theSections[numSections - 1]->getTag() << "\"], "; + s << "\"integration\": "; + beamInt->Print(s, flag); + s << ", \"massperlength\": " << rho << ", "; + s << "\"crdTransformation\": \"" << crdTransf->getTag() << "\"}"; + } +} + + +int +DispBeamColumnAsym3d::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* +DispBeamColumnAsym3d::setResponse(const char **argv, int argc, OPS_Stream &output) +{ + + Response *theResponse = 0; + + output.tag("ElementOutput"); + output.attr("eleType","DispBeamColumnAsym3d"); + 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)); + + else if (strcmp(argv[0],"sectionTags") == 0) + theResponse = new ElementResponse(this, 110, ID(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; isetResponse(&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; + } + } + } + + output.endTag(); + return theResponse; +} + +int +DispBeamColumnAsym3d::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); + } + + else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = theSections[i]->getTag(); + return eleInfo.setID(tags); + } + + else + return -1; +} + +// AddingSensitivity:BEGIN /////////////////////////////////// +int +DispBeamColumnAsym3d::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 +DispBeamColumnAsym3d::updateParameter (int parameterID, Information &info) +{ + if (parameterID == 1) { + rho = info.theDouble; + return 0; + } + else + return -1; +} + + + + +int +DispBeamColumnAsym3d::activateParameter(int passedParameterID) +{ + parameterID = passedParameterID; + + return 0; +} + +const Matrix & +DispBeamColumnAsym3d::getKiSensitivity(int gradNumber) +{ + K.Zero(); + return K; +} + +const Matrix & +DispBeamColumnAsym3d::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 & +DispBeamColumnAsym3d::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 +DispBeamColumnAsym3d::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 ///////////////////////////////////////////// + diff --git a/SRC/element/dispBeamColumn/DispBeamColumnAsym3d.h b/SRC/element/dispBeamColumn/DispBeamColumnAsym3d.h new file mode 100644 index 000000000..b611297c8 --- /dev/null +++ b/SRC/element/dispBeamColumn/DispBeamColumnAsym3d.h @@ -0,0 +1,151 @@ +/* ****************************************************************** ** +** 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$ +// $URL$ + +// Written: MHS +// Created: Feb 2001 +// +// Description: This file contains the class definition for DispBeamColumnAsym3d. +// The element displacement field gives rise to constant axial strain, +// linear curvature, and constant twist angle. + +// Modified by: Xinlong Du and Jerome F. Hajjar, Northeastern University, USA; Year 2019 +// Description: Adapted for analysis of asymmetric sections with introducing +// high-order axial terms for the basic element formulation +// References: +// Du, X., & Hajjar, J. (2021). Three-dimensional nonlinear displacement-based beam element +// for members with angle and tee sections. Engineering Structures, 239, 112239. + +#ifndef DispBeamColumnAsym3d_h +#define DispBeamColumnAsym3d_h + +#ifndef _bool_h +#include "bool.h" +#endif + +#include +#include +#include +#include + +class Node; +class SectionForceDeformation; +class CrdTransf; +class BeamIntegration; +class Response; + +class DispBeamColumnAsym3d : public Element +{ + public: + DispBeamColumnAsym3d(int tag, int nd1, int nd2, + int numSections, SectionForceDeformation **s, + BeamIntegration &bi, CrdTransf &coordTransf, + double ys=0.0, double zs=0.0, //Xinlong + double rho = 0.0, int cMass = 0); + DispBeamColumnAsym3d(); + ~DispBeamColumnAsym3d(); + + const char *getClassType(void) const {return "DispBeamColumnAsym3d";}; + + 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 /////////////////////////////////////////// + + 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 ys; //Xinlong: y coord of shear center relative to centroid + double zs; //Xinlong: z coord of shear center relative to centroid + 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/DispBeamColumnNL2d.cpp b/SRC/element/dispBeamColumn/DispBeamColumnNL2d.cpp index 94022f466..2202b30e6 100644 --- a/SRC/element/dispBeamColumn/DispBeamColumnNL2d.cpp +++ b/SRC/element/dispBeamColumn/DispBeamColumnNL2d.cpp @@ -1601,6 +1601,9 @@ DispBeamColumnNL2d::setResponse(const char **argv, int argc, else if (strcmp(argv[0],"integrationWeights") == 0) return new ElementResponse(this, 8, Vector(numSections)); + + else if (strcmp(argv[0],"sectionTags") == 0) + theResponse = new ElementResponse(this, 110, ID(numSections)); output.endTag(); return theResponse; @@ -1723,6 +1726,13 @@ DispBeamColumnNL2d::getResponse(int responseID, Information &eleInfo) return eleInfo.setVector(weights); } + else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = theSections[i]->getTag(); + return eleInfo.setID(tags); + } + else return Element::getResponse(responseID, eleInfo); } diff --git a/SRC/element/dispBeamColumn/DispBeamColumnNL3d.cpp b/SRC/element/dispBeamColumn/DispBeamColumnNL3d.cpp new file mode 100644 index 000000000..32c3f34dd --- /dev/null +++ b/SRC/element/dispBeamColumn/DispBeamColumnNL3d.cpp @@ -0,0 +1,2483 @@ +/* ****************************************************************** ** +** 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$ + +// Written: MHS +// Created: Feb 2001 +// +// Description: This file contains the class definition for DispBeamColumnNL3d. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Matrix DispBeamColumnNL3d::K(12,12); +Vector DispBeamColumnNL3d::P(12); +double DispBeamColumnNL3d::workArea[200]; + +void* OPS_DispBeamColumnNL3d() +{ + 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 <-cmass>\n"; + return 0; + } + + int ndm = OPS_GetNDM(); + int ndf = OPS_GetNDF(); + if(ndm != 2 || ndf != 3) { + opserr<<"ndm must be 2 and ndf must be 3\n"; + return 0; + } + + // inputs: + numData = 3; + if(OPS_GetIntInput(&numData,&iData[0]) < 0) { + opserr<<"WARNING: invalid integer inputs\n"; + return 0; + } + } + + // regular element, or in a mesh + if (info.Size()==0 || info(0)==1) { + if(OPS_GetNumRemainingInputArgs() < 2) { + opserr<<"insufficient arguments: transfTag,integrationTag\n"; + return 0; + } + + numData = 2; + if(OPS_GetIntInput(&numData,&iData[3]) < 0) { + opserr << "WARNING invalid int inputs\n"; + return 0; + } + + // options + 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; + } + } + } + } + } + + // store data for different mesh + static std::map meshdata; + if (info.Size()>0 && info(0)==1) { + if (info.Size() < 2) { + opserr << "WARNING: need info -- inmesh, meshtag\n"; + return 0; + } + + // save the data for a mesh + Vector& mdata = meshdata[info(1)]; + mdata.resize(4); + mdata(0) = iData[3]; + mdata(1) = iData[4]; + mdata(2) = mass; + mdata(3) = cmass; + return &meshdata; + + } else if (info.Size()>0 && info(0)==2) { + if (info.Size() < 5) { + opserr << "WARNING: need info -- inmesh, meshtag, eleTag, nd1, nd2\n"; + return 0; + } + + // get the data for a mesh + Vector& mdata = meshdata[info(1)]; + if (mdata.Size() < 4) return 0; + + iData[0] = info(2); + iData[1] = info(3); + iData[2] = info(4); + iData[3] = mdata(0); + iData[4] = mdata(1); + mass = mdata(2); + cmass = mdata(3); + } + + // 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; igetCopy(); + + // Check allocation + if (theSections[i] == 0) { + opserr << "DispBeamColumnNL3d::DispBeamColumnNL3d -- failed to get a copy of section model\n"; + exit(-1); + } + } + + beamInt = bi.getCopy(); + + if (beamInt == 0) { + opserr << "DispBeamColumnNL3d::DispBeamColumnNL3d - failed to copy beam integration\n"; + exit(-1); + } + + crdTransf = coordTransf.getCopy3d(); + + if (crdTransf == 0) { + opserr << "DispBeamColumnNL3d::DispBeamColumnNL3d - 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; +} + +DispBeamColumnNL3d::DispBeamColumnNL3d() +:Element (0, ELE_TAG_DispBeamColumnNL3d), + numSections(0), theSections(0), crdTransf(0), beamInt(0), + connectedExternalNodes(2), + Q(12), q(6), rho(0.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; +} + +DispBeamColumnNL3d::~DispBeamColumnNL3d() +{ + 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 +DispBeamColumnNL3d::getNumExternalNodes() const +{ + return 2; +} + +const ID& +DispBeamColumnNL3d::getExternalNodes() +{ + return connectedExternalNodes; +} + +Node ** +DispBeamColumnNL3d::getNodePtrs() +{ + return theNodes; +} + +int +DispBeamColumnNL3d::getNumDOF() +{ + return 12; +} + +void +DispBeamColumnNL3d::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 << "WARNING DispBeamColumnNL3d (tag: %d), node not found in domain" << this->getTag() << endln;; + return; + } + + int dofNd1 = theNodes[0]->getNumberDOF(); + int dofNd2 = theNodes[1]->getNumberDOF(); + + if (dofNd1 != 6 || dofNd2 != 6) { + //opserr << "FATAL ERROR DispBeamColumnNL3d (tag: %d), has differing number of DOFs at its nodes", + // this->getTag()); + + return; + } + + 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 +DispBeamColumnNL3d::commitState() +{ + int retVal = 0; + + // call element commitState to do any base class stuff + if ((retVal = this->Element::commitState()) != 0) { + opserr << "DispBeamColumnNL3d::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 +DispBeamColumnNL3d::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 +DispBeamColumnNL3d::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 +DispBeamColumnNL3d::update(void) +{ + int err = 0; + + // Update the transformation + crdTransf->update(); + + // Get basic deformations + const Vector &v = crdTransf->getBasicTrialDisp(); + + 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*pts(i,0); + double xi6 = 6.0*xi[i]; + double zeta = xi[i]; + + double thetaz = (3*zeta*zeta-4*zeta+1)*v(1) + (3*zeta*zeta-2*zeta)*v(2); + double thetay = (3*zeta*zeta-4*zeta+1)*v(3) + (3*zeta*zeta-2*zeta)*v(4); + + int j; + for (j = 0; j < order; j++) { + switch(code(j)) { + case SECTION_RESPONSE_P: + e(j) = oneOverL*v(0) + 0.5*thetaz*thetaz + 0.5*thetay*thetay; 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 << "DispBeamColumnNL3d::update() - failed setTrialSectionDeformations()\n"; + return err; + } + + return 0; +} + +void +DispBeamColumnNL3d::getBasicStiff(Matrix &kb, int initial) +{ + // Zero for integral + kb.Zero(); + + // Update the transformation + crdTransf->update(); + + // Get basic deformations + const Vector &v = crdTransf->getBasicTrialDisp(); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + 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]; + double zeta = xi[i]; + + double c1 = 3*zeta*zeta-4*zeta+1; + double c2 = 3*zeta*zeta-2*zeta; + double thetaz = c1*v(1) + c2*v(2); + double thetay = c1*v(3) + c2*v(4); + + // 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 = wts(i)*oneOverL; + double wti = wt[i]*oneOverL; + double tmp; + int j, k; + + // Axial force term: int_0^L N*C'*C dx + for (j = 0; j < order; j++) { + switch(code(j)) { + case SECTION_RESPONSE_P: + tmp = s(j)*wt[i]*L; + kb(1,1) += tmp*c1*c1; + kb(2,1) += tmp*c2*c1; + kb(1,2) += tmp*c1*c2; + kb(2,2) += tmp*c2*c2; + + kb(3,3) += tmp*c1*c1; + kb(4,3) += tmp*c2*c1; + kb(3,4) += tmp*c1*c2; + kb(4,4) += tmp*c2*c2; + break; + } + } + + Matrix B(order,6); + Matrix Cz(order,6); + Matrix Cy(order,6); + static Matrix Cz1(1,6); + static Matrix Cy1(1,6); + for (j = 0; j < order; j++) { + switch(code(j)) { + case SECTION_RESPONSE_P: + B(j,0) = 1.0; + + Cz(j,1) = c1; + Cz(j,2) = c2; + Cz1(0,1) = c1; + Cz1(0,2) = c2; + + Cy(j,3) = c1; + Cy(j,4) = c2; + Cy1(0,3) = c1; + Cy1(0,4) = c2; + break; + case SECTION_RESPONSE_T: + B(j,5) = 1.0; + break; + case SECTION_RESPONSE_MZ: + B(j,1) = xi6-4.0; + B(j,2) = xi6-2.0; + break; + case SECTION_RESPONSE_MY: + B(j,3) = xi6-4.0; + B(j,4) = xi6-2.0; + break; + default: + break; + } + } + + // B'*ks*B + kb.addMatrixTripleProduct(1.0, B, ks, wti); + + Matrix kC(order,6); + + // B'*ks*C*theta + kC.addMatrixProduct(0.0, ks, Cz, 1.0); + kb.addMatrixTransposeProduct(1.0, B, kC, thetaz*wt[i]); + kC.addMatrixProduct(0.0, ks, Cy, 1.0); + kb.addMatrixTransposeProduct(1.0, B, kC, thetay*wt[i]); + + Matrix ks1(1,order); + static Matrix ksB(1,6); + + for (j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_P) { + for (int jj = 0; jj < order; jj++) + ks1(0,jj) = ks(j,jj); + + ksB.addMatrixProduct(0.0, ks1, B, 1.0); + kb.addMatrixTransposeProduct(1.0, Cz1, ksB, thetaz*wt[i]); + ksB.addMatrixProduct(0.0, ks1, Cz, 1.0); + kb.addMatrixTransposeProduct(1.0, Cz1, ksB, thetaz*thetaz*wt[i]*L); + ksB.addMatrixProduct(0.0, ks1, Cz, 1.0); + kb.addMatrixTransposeProduct(1.0, Cy1, ksB, thetaz*thetay*wt[i]*L); + + ksB.addMatrixProduct(0.0, ks1, B, 1.0); + kb.addMatrixTransposeProduct(1.0, Cy1, ksB, thetay*wt[i]); + ksB.addMatrixProduct(0.0, ks1, Cy, 1.0); + kb.addMatrixTransposeProduct(1.0, Cy1, ksB, thetay*thetay*wt[i]*L); + ksB.addMatrixProduct(0.0, ks1, Cy, 1.0); + kb.addMatrixTransposeProduct(1.0, Cz1, ksB, thetay*thetaz*wt[i]*L); + } + } + + continue; + + 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; + } + for (int jj = 0; jj < order; jj++) { + switch(code(jj)) { + case SECTION_RESPONSE_P: + tmp = ks(k,jj)*wt[i]*thetaz; + ka(k,1) += tmp*c1; + ka(k,2) += tmp*c2; + break; + } + } + break; + default: + break; + } + } + for (j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_P: + for (k = 0; k < 3; k++) + kb(0,k) += ka(j,k); + break; + case SECTION_RESPONSE_MZ: + for (k = 0; k < 3; k++) { + tmp = ka(j,k); + kb(1,k) += (xi6-4.0)*tmp; + kb(2,k) += (xi6-2.0)*tmp; + } + break; + default: + break; + } + } + } +} + +const Matrix& +DispBeamColumnNL3d::getTangentStiff() +{ + static Matrix kb(6,6); + + this->getBasicStiff(kb); + + // Zero for integral + q.Zero(); + + // Update the transformation + crdTransf->update(); + + // Get basic deformations + const Vector &v = crdTransf->getBasicTrialDisp(); + + 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); + + // 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 zeta = xi[i]; + + double thetaz = (3*zeta*zeta-4*zeta+1)*v(1) + (3*zeta*zeta-2*zeta)*v(2); + double thetay = (3*zeta*zeta-4*zeta+1)*v(3) + (3*zeta*zeta-2*zeta)*v(4); + + // Get the section tangent stiffness and stress resultant + const Vector &s = theSections[i]->getStressResultant(); + + // Perform numerical integration + //q.addMatrixTransposeVector(1.0, *B, s, wts(i)); + double si; + for (int j = 0; j < order; j++) { + //si = s(j)*wts(i); + si = s(j)*wt[i]; + switch(code(j)) { + case SECTION_RESPONSE_P: + q(0) += si; break; + case SECTION_RESPONSE_T: + q(5) += si; break; + case SECTION_RESPONSE_MZ: + q(1) += (xi6-4.0)*si; + q(2) += (xi6-2.0)*si; + for (int jj = 0; jj < order; jj++) { + switch(code(jj)) { + case SECTION_RESPONSE_P: + q(1) += (3*zeta*zeta-4*zeta+1)*thetaz*s(jj)*wt[i]*L; + q(2) += (3*zeta*zeta-2*zeta)*thetaz*s(jj)*wt[i]*L; + break; + } + } + break; + case SECTION_RESPONSE_MY: + q(3) += (xi6-4.0)*si; + q(4) += (xi6-2.0)*si; + for (int jj = 0; jj < order; jj++) { + switch(code(jj)) { + case SECTION_RESPONSE_P: + q(3) += (3*zeta*zeta-4*zeta+1)*thetay*s(jj)*wt[i]*L; + q(4) += (3*zeta*zeta-2*zeta)*thetay*s(jj)*wt[i]*L; + break; + } + } + break; + default: + break; + } + } + + } + + // Add effects of element loads, q = q(v) + q0 + 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); + + return K; +} + +const Matrix& +DispBeamColumnNL3d::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*pts(i,0); + 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 = wts(i)*oneOverL; + 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); + default: + break; + } + } + + } + + return kb; +} + +const Matrix& +DispBeamColumnNL3d::getInitialStiff() +{ + const Matrix &kb = this->getInitialBasicStiff(); + + // Transform to global stiffness + K = crdTransf->getInitialGlobalStiffMatrix(kb); + + return K; +} + +const Matrix& +DispBeamColumnNL3d::getMass() +{ + K.Zero(); + + if (rho == 0.0) + return K; + + double L = crdTransf->getInitialLength(); + 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; + + return K; +} + +void +DispBeamColumnNL3d::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 +DispBeamColumnNL3d::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 << "DispBeamColumnNL3d::addLoad() -- load type unknown for element with tag: " << + this->getTag() << endln; + return -1; + } + + return 0; +} + +int +DispBeamColumnNL3d::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 << "DispBeamColumnNL3d::addInertiaLoadToUnbalance matrix and vector sizes are incompatible\n"; + return -1; + } + + double L = crdTransf->getInitialLength(); + double m = 0.5*rho*L; + + // Want to add ( - fact * M R * accel ) to unbalance + // Take advantage of lumped mass matrix + 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); + + return 0; +} + +const Vector& +DispBeamColumnNL3d::getResistingForce() +{ + // Update the transformation + crdTransf->update(); + + // Get basic deformations + const Vector &v = crdTransf->getBasicTrialDisp(); + + 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*pts(i,0); + double xi6 = 6.0*xi[i]; + double zeta = xi[i]; + + double c1 = 3*zeta*zeta-4*zeta+1; + double c2 = 3*zeta*zeta-2*zeta; + double thetaz = c1*v(1) + c2*v(2); + double thetay = c1*v(3) + c2*v(4); + + // 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)*wts(i); + si = s(j)*wt[i]; + switch(code(j)) { + case SECTION_RESPONSE_P: + q(0) += si; break; + case SECTION_RESPONSE_T: + q(5) += si; break; + case SECTION_RESPONSE_MZ: + q(1) += (xi6-4.0)*si; + q(2) += (xi6-2.0)*si; + for (int jj = 0; jj < order; jj++) { + switch(code(jj)) { + case SECTION_RESPONSE_P: + q(1) += c1*thetaz*s(jj)*wt[i]*L; + q(2) += c2*thetaz*s(jj)*wt[i]*L; + break; + } + } + break; + case SECTION_RESPONSE_MY: + q(3) += (xi6-4.0)*si; + q(4) += (xi6-2.0)*si; + for (int jj = 0; jj < order; jj++) { + switch(code(jj)) { + case SECTION_RESPONSE_P: + q(3) += c1*thetay*s(jj)*wt[i]*L; + q(4) += c2*thetay*s(jj)*wt[i]*L; + break; + } + } + break; + default: + break; + } + } + + } + + // Add effects of element loads, q = q(v) + q0 + q(0) += q0[0]; + q(1) += q0[1]; + q(2) += q0[2]; + q(3) += q0[3]; + q(4) += q0[4]; + + // Vector for reactions in basic system + Vector p0Vec(p0, 5); + + P = crdTransf->getGlobalResistingForce(q, p0Vec); + + // Subtract other external nodal loads ... P_res = P_int - P_ext + P.addVector(1.0, Q, -1.0); + + return P; +} + +const Vector& +DispBeamColumnNL3d::getResistingForceIncInertia() +{ + + this->getResistingForce(); + + if (rho != 0.0) { + const Vector &accel1 = theNodes[0]->getTrialAccel(); + const Vector &accel2 = theNodes[1]->getTrialAccel(); + + // Compute the current resisting force + this->getResistingForce(); + + 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); + + // add the damping forces if rayleigh damping + if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P += this->getRayleighDampingForces(); + + } else { + + // add the damping forces if rayleigh damping + if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P += this->getRayleighDampingForces(); + } + + return P; +} + +int +DispBeamColumnNL3d::sendSelf(int commitTag, Channel &theChannel) +{ + // place the integer data into an ID + + int dbTag = this->getDbTag(); + int i, j; + int loc = 0; + + static ID idData(9); // 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) = crdTransf->getClassTag(); + int crdTransfDbTag = crdTransf->getDbTag(); + if (crdTransfDbTag == 0) { + crdTransfDbTag = theChannel.getDbTag(); + if (crdTransfDbTag != 0) + crdTransf->setDbTag(crdTransfDbTag); + } + idData(5) = crdTransfDbTag; + + if (alphaM != 0 || betaK != 0 || betaK0 != 0 || betaKc != 0) + idData(6) = 1; + else + idData(6) = 0; + + idData(7) = beamInt->getClassTag(); + int beamIntDbTag = beamInt->getDbTag(); + if (beamIntDbTag == 0) { + beamIntDbTag = theChannel.getDbTag(); + if (beamIntDbTag != 0) + beamInt->setDbTag(beamIntDbTag); + } + idData(8) = beamIntDbTag; + + if (theChannel.sendID(dbTag, commitTag, idData) < 0) { + opserr << "DispBeamColumnNL3d::sendSelf() - failed to send ID data\n"; + return -1; + } + + if (idData(6) == 1) { + // send damping coefficients + static Vector dData(4); + dData(0) = alphaM; + dData(1) = betaK; + dData(2) = betaK0; + dData(3) = betaKc; + if (theChannel.sendVector(dbTag, commitTag, dData) < 0) { + opserr << "DispBeamColumnNL3d::sendSelf() - failed to send double data\n"; + return -1; + } + } + + // send the coordinate transformation + if (crdTransf->sendSelf(commitTag, theChannel) < 0) { + opserr << "DispBeamColumnNL3d::sendSelf() - failed to send crdTranf\n"; + return -1; + } + + // send the beam integration + if (beamInt->sendSelf(commitTag, theChannel) < 0) { + opserr << "DispBeamColumnNL3d::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; igetClassTag(); + 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 << "DispBeamColumnNL3d::sendSelf() - failed to send ID data\n"; + return -1; + } + + // + // send the sections + // + + for (j = 0; jsendSelf(commitTag, theChannel) < 0) { + opserr << "DispBeamColumnNL3d::sendSelf() - section " << + j << "failed to send itself\n"; + return -1; + } + } + + return 0; +} + +int +DispBeamColumnNL3d::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 ID idData(9); // one bigger than needed so no clash with section ID + + if (theChannel.recvID(dbTag, commitTag, idData) < 0) { + opserr << "DispBeamColumnNL3d::recvSelf() - failed to recv ID data\n"; + return -1; + } + + this->setTag(idData(0)); + connectedExternalNodes(0) = idData(1); + connectedExternalNodes(1) = idData(2); + + int crdTransfClassTag = idData(4); + int crdTransfDbTag = idData(5); + + + if (idData(6) == 1) { + // recv damping coefficients + static Vector dData(4); + if (theChannel.recvVector(dbTag, commitTag, dData) < 0) { + opserr << "DispBeamColumnNL3d::sendSelf() - failed to recv double data\n"; + return -1; + } + alphaM = dData(0); + betaK = dData(1); + betaK0 = dData(2); + betaKc = dData(3); + } + + int beamIntClassTag = idData(7); + int beamIntDbTag = idData(8); + + // 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 << "DispBeamColumnNL3d::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 << "DispBeamColumnNL3d::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 << "DispBeamColumnNL3d::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 << "DispBeamColumnNL3d::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 << "DispBeamColumnNL3d::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 (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "DispBeamColumnNL3d::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; igetClassTag() != sectClassTag) { + // delete the old section[i] and create a new one + delete theSections[i]; + theSections[i] = theBroker.getNewSection(sectClassTag); + if (theSections[i] == 0) { + opserr << "DispBeamColumnNL3d::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 << "DispBeamColumnNL3d::recvSelf() - section " << i << " failed to recv itself\n"; + return -1; + } + } + } + + return 0; +} + +void +DispBeamColumnNL3d::Print(OPS_Stream &s, int flag) +{ + s << "\nDispBeamColumnNL3d, element id: " << this->getTag() << endln; + s << "\tConnected external nodes: " << connectedExternalNodes; + s << "\tCoordTransf: " << crdTransf->getTag() << endln; + s << "\tmass density: " << rho << endln; + s << "\tNum sections: " << numSections << endln; + + double L = crdTransf->getInitialLength(); + double P = q(0); + double M1 = q(1); + double M2 = q(2); + double V = (M1+M2)/L; + 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; + + beamInt->Print(s, flag); + + for (int i = 0; i < numSections; i++) + theSections[i]->Print(s,flag); +} + + +int +DispBeamColumnNL3d::displaySelf(Renderer &theViewer, int displayMode, float fact) +{ + static Vector v1(3); + static Vector v2(3); + + theNodes[0]->getDisplayCrds(v1, fact, displayMode); + theNodes[1]->getDisplayCrds(v2, fact, displayMode); + + return theViewer.drawLine(v1, v2, 1.0, 1.0, this->getTag()); +} + +Response* +DispBeamColumnNL3d::setResponse(const char **argv, int argc, + OPS_Stream &output) +{ + Response *theResponse = 0; + + output.tag("ElementOutput"); + output.attr("eleType","DispBeamColumnNL3d"); + 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","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); + + + // basic force - + } else if (strcmp(argv[0],"basicForce") == 0 || strcmp(argv[0],"basicForces") == 0) { + + output.tag("ResponseType","N"); + output.tag("ResponseType","M1"); + output.tag("ResponseType","M2"); + + theResponse = new ElementResponse(this, 9, Vector(6)); + + // basic stiffness - + } else if (strcmp(argv[0],"basicStiffness") == 0) { + + output.tag("ResponseType","N"); + output.tag("ResponseType","M1"); + output.tag("ResponseType","M2"); + + theResponse = new ElementResponse(this, 19, Matrix(6,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","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","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, 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],"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],"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(); + 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 (strstr(argv[0],"section") != 0) { + + if (argc > 1) { + + int sectionNum = atoi(argv[1]); + + if (sectionNum > 0 && sectionNum <= numSections && argc > 2) { + + output.tag("GaussPointOutput"); + output.attr("number",sectionNum); + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamInt->getSectionLocations(numSections, L, xi); + output.attr("eta",xi[sectionNum-1]*L); + + if (strcmp(argv[2],"dsdh") != 0) { + theResponse = theSections[sectionNum-1]->setResponse(&argv[2], argc-2, output); + } else { + int order = theSections[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(); + beamInt->getSectionLocations(numSections, L, xi); + + for (int i=0; isetResponse(&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; + } + } + } + + // curvature sensitivity along element length + else if (strcmp(argv[0],"dcurvdh") == 0) + return new ElementResponse(this, 5, Vector(numSections)); + + // basic deformation sensitivity + else if (strcmp(argv[0],"dvdh") == 0) + return new ElementResponse(this, 6, Vector(3)); + + else if (strcmp(argv[0],"integrationPoints") == 0) + return new ElementResponse(this, 7, Vector(numSections)); + + else if (strcmp(argv[0],"integrationWeights") == 0) + return new ElementResponse(this, 8, Vector(numSections)); + + else if (strcmp(argv[0],"sectionTags") == 0) + theResponse = new ElementResponse(this, 110, ID(numSections)); + + output.endTag(); + return theResponse; +} + +int +DispBeamColumnNL3d::getResponse(int responseID, Information &eleInfo) +{ + double V; + double L = crdTransf->getInitialLength(); + + if (responseID == 1) + return eleInfo.setVector(this->getResistingForce()); + + else if (responseID == 12) + return eleInfo.setVector(this->getRayleighDampingForces()); + + else if (responseID == 2) { + P(3) = q(0); + P(0) = -q(0)+p0[0]; + P(2) = q(1); + P(5) = q(2); + V = (q(1)+q(2))/L; + P(1) = V+p0[1]; + P(4) = -V+p0[2]; + return eleInfo.setVector(P); + } + + else if (responseID == 9) { + return eleInfo.setVector(q); + } + + else if (responseID == 19) { + static Matrix kb(6,6); + this->getBasicStiff(kb); + return eleInfo.setMatrix(kb); + } + + // 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); + } + + // Curvature sensitivity + else if (responseID == 5) { + /* + Vector curv(numSections); + const Vector &v = crdTransf->getBasicDispGradient(1); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + double pts[2]; + pts[0] = 0.0; + pts[1] = 1.0; + + // 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*pts[i]; + curv(i) = oneOverL*((xi6-4.0)*v(1) + (xi6-2.0)*v(2)); + } + + return eleInfo.setVector(curv); + */ + + Vector curv(numSections); + + /* + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + const Vector &dedh = theSections[i]->getdedh(); + for (int j = 0; j < order; j++) { + if (code(j) == SECTION_RESPONSE_MZ) + curv(i) = dedh(j); + } + } + */ + + return eleInfo.setVector(curv); + } + + // Basic deformation sensitivity + else if (responseID == 6) { + const Vector &dvdh = crdTransf->getBasicDisplSensitivity(1); + return eleInfo.setVector(dvdh); + } + + else if (responseID == 7) { + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + Vector locs(numSections); + for (int i = 0; i < numSections; i++) + locs(i) = xi[i]*L; + return eleInfo.setVector(locs); + } + + else if (responseID == 8) { + //const Vector &wts = quadRule.getIntegrPointWeights(numSections); + double wt[maxNumSections]; + beamInt->getSectionWeights(numSections, L, wt); + Vector weights(numSections); + for (int i = 0; i < numSections; i++) + weights(i) = wt[i]*L; + return eleInfo.setVector(weights); + } + + else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = theSections[i]->getTag(); + return eleInfo.setID(tags); + } + + else if (responseID == 111 || responseID == 1111) { + double L = crdTransf->getInitialLength(); + double pts[maxNumSections]; + beamInt->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 = theSections[i]->getType(); + const Vector &e = theSections[i]->getSectionDeformation(); + int order = theSections[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); + beamInt->getSectionLocations(numSections, L, pts); + static Vector uxb(3); + static Vector uxg(3); + Matrix disps(numSections,3); + static Vector vp(6); + 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 >= 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 Element::getResponse(responseID, eleInfo); +} + +int +DispBeamColumnNL3d::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 == 9) { + static Vector dqdh(6); + + dqdh.Zero(); + + return eleInfo.setVector(dqdh); + } + + // dsdh + else if (responseID == 76) { + + int sectionNum = eleInfo.theInt; + int order = theSections[sectionNum-1]->getOrder(); + const ID &code = theSections[sectionNum-1]->getType(); + + Vector dsdh(order); + dsdh = theSections[sectionNum-1]->getStressResultantSensitivity(gradNumber, true); + + const Vector &v = crdTransf->getBasicTrialDisp(); + const Vector &dvdh = crdTransf->getBasicDisplSensitivity(gradNumber); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + const Matrix &ks = theSections[sectionNum-1]->getSectionTangent(); + + Vector dedh(order); + + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + + double x = xi[sectionNum-1]; + + //double xi6 = 6.0*pts(i,0); + double xi6 = 6.0*x; + double zeta = x; + + double theta = (3*zeta*zeta-4*zeta+1)*v(1) + (3*zeta*zeta-2*zeta)*v(2); + double dthetadh = (3*zeta*zeta-4*zeta+1)*dvdh(1) + (3*zeta*zeta-2*zeta)*dvdh(2); + + int j; + for (j = 0; j < order; j++) { + switch(code(j)) { + case SECTION_RESPONSE_P: + dedh(j) = oneOverL*dvdh(0) + theta*dthetadh; break; + case SECTION_RESPONSE_MZ: + dedh(j) = oneOverL*((xi6-4.0)*dvdh(1) + (xi6-2.0)*dvdh(2)); break; + default: + dedh(j) = 0.0; break; + } + } + + dsdh.addMatrixVector(1.0, ks, dedh, 1.0); + + return eleInfo.setVector(dsdh); + } + + else + return -1; +} + +// AddingSensitivity:BEGIN /////////////////////////////////// +int +DispBeamColumnNL3d::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc < 1) + return -1; + + // If the parameter belongs to the element itself + if (strcmp(argv[0],"rho") == 0) + 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: 1...Np + 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); + } + int result =-1; + // Default, send to every object + int ok = 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 +DispBeamColumnNL3d::updateParameter (int parameterID, Information &info) +{ + if (parameterID == 1) { + rho = info.theDouble; + return 0; + } + else + return -1; +} + + + + +int +DispBeamColumnNL3d::activateParameter(int passedParameterID) +{ + parameterID = passedParameterID; + + return 0; +} + + + +const Matrix & +DispBeamColumnNL3d::getInitialStiffSensitivity(int gradNumber) +{ + 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*pts(i,0); + double xi6 = 6.0*xi[i]; + + // Get the section tangent stiffness and stress resultant + const Matrix &ks = theSections[i]->getInitialTangentSensitivity(gradNumber); + + // Perform numerical integration + //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L); + //double wti = wts(i)*oneOverL; + 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; + default: + break; + } + } + for (j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_P: + for (k = 0; k < 3; k++) + kb(0,k) += ka(j,k); + break; + case SECTION_RESPONSE_MZ: + for (k = 0; k < 3; k++) { + tmp = ka(j,k); + kb(1,k) += (xi6-4.0)*tmp; + kb(2,k) += (xi6-2.0)*tmp; + } + break; + default: + break; + } + } + + } + + // Transform to global stiffness + K = crdTransf->getInitialGlobalStiffMatrix(kb); + + return K; +} + +const Matrix & +DispBeamColumnNL3d::getMassSensitivity(int gradNumber) +{ + K.Zero(); + return K; +} + + + +const Vector & +DispBeamColumnNL3d::getResistingForceSensitivity(int gradNumber) +{ + // Update the transformation + crdTransf->update(); + + // Get basic deformations + const Vector &v = crdTransf->getBasicTrialDisp(); + + double L = crdTransf->getInitialLength(); + + 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 zeta = xi[i]; + + double c1 = 3*zeta*zeta-4*zeta+1; + double c2 = 3*zeta*zeta-2*zeta; + double theta = c1*v(1) + c2*v(2); + + //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; // 1 + dqdh(1) += c1*theta*sensi*L; // 2 + dqdh(2) += c2*theta*sensi*L; // 2 + break; + case SECTION_RESPONSE_MZ: + dqdh(1) += (xi6-4.0)*sensi; // 1 + dqdh(2) += (xi6-2.0)*sensi; // 1 + break; + default: + break; + } + } + } + + + + if (crdTransf->isShapeSensitivity()) { + double dLdh = crdTransf->getdLdh(); + + double dptsdh[maxNumSections]; + beamInt->getLocationsDeriv(numSections, L, dLdh, dptsdh); + + double dwtsdh[maxNumSections]; + beamInt->getWeightsDeriv(numSections, L, dLdh, dwtsdh); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + double dwtLdh = wt[i]*dLdh + dwtsdh[i]*L; + double dptLdh = xi[i]*dLdh + dptsdh[i]*L; + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + double xi6 = 6.0*xi[i]; + double zeta = xi[i]; + + double c1 = 3*zeta*zeta-4*zeta+1; + double c2 = 3*zeta*zeta-2*zeta; + double theta = c1*v(1) + c2*v(2); + + Matrix B(order,3); + Matrix dBdh(order,3); + Matrix C(order,3); + Matrix dCdh(order,3); + Matrix C1(1,3); + Matrix dC1dh(1,3); + + const Vector &s = theSections[i]->getStressResultant(); + const Matrix &ks = theSections[i]->getSectionTangent(); + + double N = 0.0; + + for(int j = 0; j < order; j++) { + switch(code(j)) { + case SECTION_RESPONSE_P: + N += s(j); + + B(j,0) = 1.0/L; + dBdh(j,0) = -dLdh/(L*L); + + C(j,1) = c1; + C(j,2) = c2; + dCdh(j,1) = -(xi6-4.0)*xi[i]/L*dLdh + (xi6-4.0)/L*dptLdh; + dCdh(j,2) = -(xi6-2.0)*xi[i]/L*dLdh + (xi6-2.0)/L*dptLdh; + + C1(0,1) = c1; + C1(0,2) = c2; + dC1dh(0,1) = -(xi6-4.0)*xi[i]/L*dLdh + (xi6-4.0)/L*dptLdh; + dC1dh(0,2) = -(xi6-2.0)*xi[i]/L*dLdh + (xi6-2.0)/L*dptLdh; + break; + case SECTION_RESPONSE_MZ: + B(j,1) = (xi6-4.0)/L; + B(j,2) = (xi6-2.0)/L; + dBdh(j,1) = -(12*xi[i]-4.0)/(L*L)*dLdh + 6/(L*L)*dptLdh; + dBdh(j,2) = -(12*xi[i]-2.0)/(L*L)*dLdh + 6/(L*L)*dptLdh; + break; + } + } + + dqdh.addMatrixTransposeVector(1.0, dBdh, s, wt[i]*L); // 3 + + dqdh(1) += dC1dh(0,1)*theta*N*wt[i]*L; // 4 + dqdh(2) += dC1dh(0,2)*theta*N*wt[i]*L; // 4 + + double dCdhv = dC1dh(0,1)*v(1) + dC1dh(0,2)*v(2); + dqdh(1) += C1(0,1)*dCdhv*N*wt[i]*L; // 5 + dqdh(2) += C1(0,2)*dCdhv*N*wt[i]*L; // 5 + + Matrix tmp(order,3); + tmp = dBdh; + tmp.addMatrix(1.0, dCdh, theta); + + Matrix tmp2(3,3); + tmp2.addMatrixTripleProduct(0.0, C, ks, tmp, 1.0); + dqdh.addMatrixVector(1.0, tmp2, v, theta*wt[i]*L); // 7 + + tmp2.addMatrixTripleProduct(0.0, B, ks, tmp, 1.0); + dqdh.addMatrixVector(1.0, tmp2, v, wt[i]*L); // 6 + + dqdh.addMatrixTransposeVector(1.0, B, s, dwtLdh); // 8 + + dqdh(1) += C1(0,1)*theta*N*dwtLdh; // 9 + dqdh(2) += C1(0,2)*theta*N*dwtLdh; // 9 + + continue; + + double si; + for(int j = 0; j < order; j++) { + switch(code(j)) { + si = s(j)*wt[i]; + case SECTION_RESPONSE_P: + dqdh(0) += -dLdh/(L*L); + dqdh(1) += (-6*xi[i]+4.0)*xi[i]/L*theta*si*L*dLdh; + dqdh(2) += (-6*xi[i]+2.0)*xi[i]/L*theta*si*L*dLdh; + break; + case SECTION_RESPONSE_MZ: + dqdh(1) += (-12*xi[i]+4.0)/(L*L)*si*L*dLdh; + dqdh(2) += (-12*xi[i]+2.0)/(L*L)*si*L*dLdh; + break; + default: + break; + } + } + + } + + } + + + // Transform forces + static Vector dp0dh(5); // No distributed loads + dp0dh.Zero(); + + P.Zero(); + + ////////////////////////////////////////////////////////////// + + if (crdTransf->isShapeSensitivity()) { + + // Perform numerical integration to obtain basic stiffness matrix + // Some extra declarations + static Matrix kbmine(6,6); + this->getBasicStiff(kbmine); + + // k dAdh u + const Vector &dAdh_u = crdTransf->getBasicTrialDispShapeSensitivity(); + //dqdh.addMatrixVector(1.0, kbmine, dAdh_u, oneOverL); + dqdh.addMatrixVector(1.0, kbmine, dAdh_u, 1.0); + + // 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 +DispBeamColumnNL3d::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; + + 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*xi[i]; + + double zeta = xi[i]; + + double c1 = 3*zeta*zeta-4*zeta+1; + double c2 = 3*zeta*zeta-2*zeta; + double theta = c1*v(1) + c2*v(2); + + for (int j = 0; j < order; j++) { + switch(code(j)) { + case SECTION_RESPONSE_P: + e(j) = oneOverL*dvdh(0) + + d1oLdh*v(0) + + theta*(c1*dvdh(1)+c2*dvdh(2)); + 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; + default: + e(j) = 0.0; + break; + } + } + + // Set the section deformations + theSections[i]->commitSensitivity(e,gradNumber,numGrads); + } + + return 0; +} + + +// AddingSensitivity:END ///////////////////////////////////////////// + diff --git a/SRC/element/dispBeamColumn/DispBeamColumnNL3d.h b/SRC/element/dispBeamColumn/DispBeamColumnNL3d.h new file mode 100644 index 000000000..6a01eb413 --- /dev/null +++ b/SRC/element/dispBeamColumn/DispBeamColumnNL3d.h @@ -0,0 +1,145 @@ +/* ****************************************************************** ** +** 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$ + +// Written: MHS +// Created: Feb 2001 +// +// Description: This file contains the class definition for DispBeamColumnNL3d. +// The element displacement field gives rise to constant axial strain and +// linear curvature. + +#ifndef DispBeamColumnNL3d_h +#define DispBeamColumnNL3d_h + +#ifndef _bool_h +#include "bool.h" +#endif + +#include +#include +#include +#include +#include + +class Node; +class SectionForceDeformation; +class CrdTransf; +class Response; + +class DispBeamColumnNL3d : public Element +{ + public: + DispBeamColumnNL3d(int tag, int nd1, int nd2, + int numSections, SectionForceDeformation **s, + BeamIntegration &bi, CrdTransf &coordTransf, + double rho = 0.0); + DispBeamColumnNL3d(); + ~DispBeamColumnNL3d(); + + const char *getClassType(void) const {return "DispBeamColumnNL3d";}; + + 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); + void Print(OPS_Stream &s, int flag =0); + + Response *setResponse(const char **argv, int argc, OPS_Stream &s); + int getResponse(int responseID, Information &eleInfo); + 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 & getInitialStiffSensitivity(int gradNumber); + const Matrix & getMassSensitivity(int gradNumber); + int commitSensitivity(int gradNumber, int numGrads); + // AddingSensitivity:END /////////////////////////////////////////// + + protected: + + private: + const Matrix &getInitialBasicStiff(void); + void getBasicStiff(Matrix &kb, int initial = 0); + + 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 + double p0[5]; // Reactions in basic system + + double rho; // Mass density per unit length + + enum {maxNumSections = 20}; + + static double workArea[]; + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int parameterID; + // AddingSensitivity:END /////////////////////////////////////////// +}; + +#endif + diff --git a/SRC/element/dispBeamColumn/Makefile b/SRC/element/dispBeamColumn/Makefile index ea473f780..0b56f7c8a 100644 --- a/SRC/element/dispBeamColumn/Makefile +++ b/SRC/element/dispBeamColumn/Makefile @@ -5,9 +5,11 @@ OBJS = DispBeamColumn2d.o \ DispBeamColumn2dThermal.o \ DispBeamColumn3dThermal.o \ DispBeamColumnNL2d.o \ + DispBeamColumnNL3d.o \ DispBeamColumn2dWithSensitivity.o \ DispBeamColumn3dWithSensitivity.o \ DispBeamColumnWarping3d.o \ + DispBeamColumnAsym3d.o \ AxEqDispBeamColumn2d.o \ TimoshenkoBeamColumn2d.o \ DispBeamColumn3dID.o diff --git a/SRC/element/dispBeamColumn/TimoshenkoBeamColumn2d.cpp b/SRC/element/dispBeamColumn/TimoshenkoBeamColumn2d.cpp index f1fc9c8a0..a4396059f 100644 --- a/SRC/element/dispBeamColumn/TimoshenkoBeamColumn2d.cpp +++ b/SRC/element/dispBeamColumn/TimoshenkoBeamColumn2d.cpp @@ -1315,6 +1315,9 @@ TimoshenkoBeamColumn2d::setResponse(const char **argv, int argc, else if (strcmp(argv[0],"integrationWeights") == 0) return new ElementResponse(this, 8, Vector(numSections)); + + else if (strcmp(argv[0],"sectionTags") == 0) + theResponse = new ElementResponse(this, 110, ID(numSections)); output.endTag(); return theResponse; @@ -1431,6 +1434,13 @@ TimoshenkoBeamColumn2d::getResponse(int responseID, Information &eleInfo) return eleInfo.setVector(weights); } + else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = theSections[i]->getTag(); + return eleInfo.setID(tags); + } + else return -1; } diff --git a/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp b/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp index 70faceae6..ac3e3e2b7 100644 --- a/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp +++ b/SRC/element/elasticBeamColumn/ElasticBeam2d.cpp @@ -66,7 +66,7 @@ void *OPS_ElasticBeam2d(const ID &info) { */ int iData[3]; bool section = false; - int sectionTag; + int sectionTag = -1; double data[3]; int transfTag; double mass = 0.0, alpha = 0.0, depth = 0.0; @@ -216,6 +216,10 @@ to get element data depth = mdata(8); cMass = (int) mdata(9); release = (int) mdata(10); + + iData[0] = info(2); + iData[1] = info(3); + iData[2] = info(4); } // check transf diff --git a/SRC/element/forceBeamColumn/ChebyshevBeamIntegration.cpp b/SRC/element/forceBeamColumn/ChebyshevBeamIntegration.cpp new file mode 100755 index 000000000..3f74836c1 --- /dev/null +++ b/SRC/element/forceBeamColumn/ChebyshevBeamIntegration.cpp @@ -0,0 +1,213 @@ +/* ****************************************************************** ** +** 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.1 $ +// $Date: 2006-01-17 21:12:56 $ +// $Source: /usr/local/cvs/OpenSees/SRC/element/forceBeamColumn/ChebyshevBeamIntegration.cpp,v $ + +#include +#include +#include +#include + +void* OPS_ChebyshevBeamIntegration(int& integrationTag, ID& secTags) +{ + if(OPS_GetNumRemainingInputArgs() < 3) { + opserr<<"insufficient arguments:integrationTag,secTag,N,\n"; + return 0; + } + + // inputs: integrationTag,secTag,N, + int iData[3]; + int numData = 3; + if(OPS_GetIntInput(&numData,&iData[0]) < 0) { + opserr << "WARNING: failed to read inputs\n"; + return 0; + } + + integrationTag = iData[0]; + if(iData[2] > 0) { + secTags.resize(iData[2]); + } else { + secTags = ID(); + } + for(int i=0; i 0) { + numData = 1; + if(OPS_GetIntInput(&numData,&iData[0]) < 0) { + opserr << "WARNING: failed to read inputs\n"; + return 0; + } + return new ChebyshevBeamIntegration(iData[0]); + } else + return new ChebyshevBeamIntegration(); + + +} + +ChebyshevBeamIntegration::ChebyshevBeamIntegration(int t): + BeamIntegration(BEAM_INTEGRATION_TAG_Chebyshev), type(t) +{ + if (type < 0 || type > 2) + type = 0; +} + +ChebyshevBeamIntegration::~ChebyshevBeamIntegration() +{ + // Nothing to do +} + +BeamIntegration* +ChebyshevBeamIntegration::getCopy(void) +{ + return new ChebyshevBeamIntegration(type); +} + +void +ChebyshevBeamIntegration::getSectionLocations(int numSections, + double L, + double *xi) +{ + double pi = acos(-1.0); + + if (type == 0) { + for (int i = 0; i < numSections; i++) + xi[i] = 0.0; + switch (numSections) { + case 2: + xi[0] = -0.5773502692; + xi[1] = 0.5773502692; + break; + case 3: + xi[0] = -0.7071067812; + xi[1] = 0.0; + xi[2] = 0.7071067812; + break; + case 4: + xi[0] = -0.7946544723; + xi[1] = -0.1875924741; + xi[2] = 0.1875924741; + xi[3] = 0.7946544723; + break; + case 5: + xi[0] = -0.8324974870; + xi[1] = -0.3745414096; + xi[2] = 0.0; + xi[3] = 0.3745414096; + xi[4] = 0.8324974870; + break; + case 6: + xi[0] = -0.8662468181; + xi[1] = -0.4225186538; + xi[2] = -0.2666354015; + xi[3] = 0.2666354015; + xi[4] = 0.4225186538; + xi[5] = 0.8662468181; + break; + case 7: + xi[0] = -0.8838617008; + xi[1] = -0.5296567753; + xi[2] = -0.3239118105; + xi[3] = 0.0; + xi[4] = 0.3239118105; + xi[5] = 0.5296567753; + xi[6] = 0.8838617008; + break; + case 8: + // complex values + break; + case 9: + xi[0] = -0.9115893077; + xi[1] = -0.6010186554; + xi[2] = -0.5287617831; + xi[3] = -0.1679061842; + xi[4] = 0.0; + xi[5] = 0.1679061842; + xi[6] = 0.5287617831; + xi[7] = 0.6010186554; + xi[8] = 0.9115893077; + break; + case 10: + // complex values + break; + default: + break; + } + } + + if (type == 1) { + for (int i = 0; i < numSections; i++) + xi[i] = cos((2*i+1)*pi/(2*numSections)); + } + + if (type == 2) { + for (int i = 0; i < numSections; i++) + xi[i] = cos((i+1)*pi/(numSections+1)); + } + + for (int i = 0; i < numSections; i++) + xi[i] = 0.5*(xi[i] + 1.0); +} + +void +ChebyshevBeamIntegration::getSectionWeights(int numSections, double L, + double *wt) +{ + double pi = acos(-1.0); + + if (type == 0) { + double w = 2.0/numSections; + for (int i = 0; i < numSections; i++) + wt[i] = w; + } + if (type == 1) { + double w = pi/numSections; + //w = 2.0/numSections; + for (int i = 0; i < numSections; i++) + wt[i] = w; + } + + if (type == 2) { + for (int i = 0; i < numSections; i++) { + double s = sin((i+1)*pi/(numSections+1)); + wt[i] = pi/(numSections+1)*s*s; + //wt[i] *= 4/pi; + } + } + + for (int i = 0; i < numSections; i++) { + wt[i] *= 0.5; + } +} + +void +ChebyshevBeamIntegration::Print(OPS_Stream &s, int flag) +{ + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << "{\"type\": \"Chebyshev\"}"; + } + + else { + s << "Chebyshev, type=" << type << endln; + } +} diff --git a/SRC/element/forceBeamColumn/ChebyshevBeamIntegration.h b/SRC/element/forceBeamColumn/ChebyshevBeamIntegration.h new file mode 100644 index 000000000..fa731f6bc --- /dev/null +++ b/SRC/element/forceBeamColumn/ChebyshevBeamIntegration.h @@ -0,0 +1,59 @@ +/* ****************************************************************** ** +** 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$ + +#ifndef ChebyshevBeamIntegration_h +#define ChebyshevBeamIntegration_h + +#include + +class Matrix; +class ElementalLoad; +class Channel; +class FEM_ObjectBroker; + +#define BEAM_INTEGRATION_TAG_Chebyshev 1234 + +class ChebyshevBeamIntegration : public BeamIntegration +{ + public: + ChebyshevBeamIntegration(int type = 1); + virtual ~ChebyshevBeamIntegration(); + + void getSectionLocations(int nIP, double L, double *xi); + void getSectionWeights(int nIP, double L, double *wt); + + BeamIntegration *getCopy(void); + + // These two methods do nothing + int sendSelf(int cTag, Channel &theChannel) {return 0;} + int recvSelf(int cTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) {return 0;} + + void Print(OPS_Stream &s, int flag = 0); + + private: + int type; +}; + +#endif diff --git a/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp b/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp index b08e6bb87..a97390fd4 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp +++ b/SRC/element/forceBeamColumn/ForceBeamColumn2d.cpp @@ -2606,6 +2606,9 @@ 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],"sectionTags") == 0) + theResponse = new ElementResponse(this, 110, ID(numSections)); + else if (strcmp(argv[0],"sectionDisplacements") == 0) theResponse = new ElementResponse(this, 111, Matrix(numSections,3)); @@ -2887,6 +2890,13 @@ ForceBeamColumn2d::getResponse(int responseID, Information &eleInfo) return eleInfo.setVector(weights); } + else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = sections[i]->getTag(); + return eleInfo.setID(tags); + } + else if (responseID == 111) { double L = crdTransf->getInitialLength(); double pts[maxNumSections]; diff --git a/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp b/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp index 88846b700..14d7adcde 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp +++ b/SRC/element/forceBeamColumn/ForceBeamColumn3d.cpp @@ -2727,6 +2727,9 @@ ForceBeamColumn3d::getInitialDeformations(Vector &v0) else if (strcmp(argv[0],"integrationWeights") == 0) theResponse = new ElementResponse(this, 11, Vector(numSections)); + else if (strcmp(argv[0],"sectionTags") == 0) + theResponse = new ElementResponse(this, 110, ID(numSections)); + else if (strcmp(argv[0],"sectionDisplacements") == 0) { if (argc > 1 && strcmp(argv[1],"local") == 0) theResponse = new ElementResponse(this, 1111, Matrix(numSections,3)); @@ -2900,6 +2903,13 @@ ForceBeamColumn3d::getResponse(int responseID, Information &eleInfo) return eleInfo.setVector(weights); } + else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = sections[i]->getTag(); + return eleInfo.setID(tags); + } + else if (responseID == 111 || responseID == 1111) { double L = crdTransf->getInitialLength(); double pts[maxNumSections]; diff --git a/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.cpp b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.cpp index b1d6de5ce..539705eea 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.cpp +++ b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI2d.cpp @@ -2967,6 +2967,9 @@ 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],"sectionTags") == 0) + theResponse = new ElementResponse(this, 110, ID(numSections)); + else if (strcmp(argv[0],"sectionDisplacements") == 0) theResponse = new ElementResponse(this, 111, Matrix(numSections,3)); @@ -3230,6 +3233,13 @@ ForceBeamColumnCBDI2d::getResponse(int responseID, Information &eleInfo) return eleInfo.setVector(weights); } + else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = sections[i]->getTag(); + return eleInfo.setID(tags); + } + else if (responseID == 111) { double L = crdTransf->getInitialLength(); double pts[maxNumSections]; diff --git a/SRC/element/forceBeamColumn/ForceBeamColumnCBDI3d.cpp b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI3d.cpp index fe8e25aba..94f90f0d8 100644 --- a/SRC/element/forceBeamColumn/ForceBeamColumnCBDI3d.cpp +++ b/SRC/element/forceBeamColumn/ForceBeamColumnCBDI3d.cpp @@ -3481,6 +3481,9 @@ ForceBeamColumnCBDI3d::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],"sectionTags") == 0) + theResponse = new ElementResponse(this, 110, ID(numSections)); + else if (strcmp(argv[0],"sectionDisplacements") == 0) theResponse = new ElementResponse(this, 111, Matrix(numSections,3)); @@ -3755,6 +3758,13 @@ ForceBeamColumnCBDI3d::getResponse(int responseID, Information &eleInfo) return eleInfo.setVector(weights); } + else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = sections[i]->getTag(); + return eleInfo.setID(tags); + } + else if (responseID == 111) { double L = crdTransf->getInitialLength(); double pts[maxNumSections]; diff --git a/SRC/element/forceBeamColumn/Makefile b/SRC/element/forceBeamColumn/Makefile index 2ff640614..5a3a0c687 100644 --- a/SRC/element/forceBeamColumn/Makefile +++ b/SRC/element/forceBeamColumn/Makefile @@ -27,6 +27,7 @@ OBJS = ForceBeamColumn2d.o ForceBeamColumn3d.o \ LowOrderBeamIntegration.o \ MidDistanceBeamIntegration.o \ GaussQBeamIntegration.o \ + ChebyshevBeamIntegration.o \ gaussq.o d1mach.o # Compilation control diff --git a/SRC/element/forceBeamColumn/SimpsonBeamIntegration.cpp b/SRC/element/forceBeamColumn/SimpsonBeamIntegration.cpp index fe9e8ee87..8bcc9323d 100644 --- a/SRC/element/forceBeamColumn/SimpsonBeamIntegration.cpp +++ b/SRC/element/forceBeamColumn/SimpsonBeamIntegration.cpp @@ -1,85 +1,112 @@ -/* ****************************************************************** ** -** 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) ** -** ** -** ****************************************************************** */ - -/* Created: 7/19 -** Written by: Mohammad Salehi (mohammad.salehi@tamu.edu) -*/ - -#include - -SimpsonBeamIntegration::SimpsonBeamIntegration() : -BeamIntegration(BEAM_INTEGRATION_TAG_Simpson) -{ - // Nothing to do -} - -SimpsonBeamIntegration::~SimpsonBeamIntegration() -{ - // Nothing to do -} - -BeamIntegration* -SimpsonBeamIntegration::getCopy(void) -{ - return new SimpsonBeamIntegration(); -} - -void -SimpsonBeamIntegration::getSectionLocations(int numSections, double L, -double *xi) -{ - if (numSections > 1) { - xi[0] = -1.0; - xi[numSections - 1] = 1.0; - - double dxi = 2.0 / (numSections - 1); - - for (int i = 1; i < numSections - 1; i++) - xi[i] = -1.0 + dxi*i; - } - - for (int i = 0; i < numSections; i++) - xi[i] = 0.5*(xi[i] + 1.0); -} - -void -SimpsonBeamIntegration::getSectionWeights(int numSections, double L, -double *wt) -{ - if (numSections > 1) { - wt[0] = 1.0 / 6.0; - wt[numSections - 1] = 1.0 / 6.0; - - for (int i = 1; i < numSections; i += 2) - wt[i] = 2.0 / 3.0; - - for (int i = 2; i < (numSections - 1); i += 2) - wt[i] = 1.0 / 3.0; - - for (int i = 0; i < numSections; i++) - wt[i] /= ((numSections - 1.0) / 2.0); - } -} - -void -SimpsonBeamIntegration::Print(OPS_Stream &s, int flag) -{ - s << "Simpson" << endln; -} +/* ****************************************************************** ** +** 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) ** +** ** +** ****************************************************************** */ + +/* Created: 7/19 +** Written by: Mohammad Salehi (mohammad.salehi@tamu.edu) +*/ + +#include +#include +#include + +void* OPS_SimpsonBeamIntegration(int& integrationTag, ID& secTags) +{ + if(OPS_GetNumRemainingInputArgs() < 3) { + opserr<<"insufficient arguments:integrationTag,secTag,N\n"; + return 0; + } + + // inputs: integrationTag,secTag,N + int iData[3]; + int numData = 3; + if(OPS_GetIntInput(&numData,&iData[0]) < 0) return 0; + + integrationTag = iData[0]; + if(iData[2] > 0) { + secTags.resize(iData[2]); + } else { + secTags = ID(); + } + for(int i=0; i 1) { + xi[0] = -1.0; + xi[numSections - 1] = 1.0; + + double dxi = 2.0 / (numSections - 1); + + for (int i = 1; i < numSections - 1; i++) + xi[i] = -1.0 + dxi*i; + } + + for (int i = 0; i < numSections; i++) + xi[i] = 0.5*(xi[i] + 1.0); +} + +void +SimpsonBeamIntegration::getSectionWeights(int numSections, double L, +double *wt) +{ + if (numSections > 1) { + wt[0] = 1.0 / 6.0; + wt[numSections - 1] = 1.0 / 6.0; + + for (int i = 1; i < numSections; i += 2) + wt[i] = 2.0 / 3.0; + + for (int i = 2; i < (numSections - 1); i += 2) + wt[i] = 1.0 / 3.0; + + for (int i = 0; i < numSections; i++) + wt[i] /= ((numSections - 1.0) / 2.0); + } +} + +void +SimpsonBeamIntegration::Print(OPS_Stream &s, int flag) +{ + s << "Simpson" << endln; +} diff --git a/SRC/element/fourNodeQuad/EightNodeQuad.h b/SRC/element/fourNodeQuad/EightNodeQuad.h index a87debf66..81f3d9da8 100644 --- a/SRC/element/fourNodeQuad/EightNodeQuad.h +++ b/SRC/element/fourNodeQuad/EightNodeQuad.h @@ -95,6 +95,7 @@ class EightNodeQuad : public Element { // stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: private: diff --git a/SRC/element/fourNodeQuad/FourNodeQuad.h b/SRC/element/fourNodeQuad/FourNodeQuad.h index f14d9f1e8..35d1db44f 100644 --- a/SRC/element/fourNodeQuad/FourNodeQuad.h +++ b/SRC/element/fourNodeQuad/FourNodeQuad.h @@ -101,6 +101,7 @@ class FourNodeQuad : public Element // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/element/fourNodeQuad/FourNodeQuad3d.h b/SRC/element/fourNodeQuad/FourNodeQuad3d.h index 8dc8e7112..89425a4c7 100644 --- a/SRC/element/fourNodeQuad/FourNodeQuad3d.h +++ b/SRC/element/fourNodeQuad/FourNodeQuad3d.h @@ -100,6 +100,7 @@ class FourNodeQuad3d : public Element // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/element/fourNodeQuad/FourNodeQuadWithSensitivity.h b/SRC/element/fourNodeQuad/FourNodeQuadWithSensitivity.h index 1feee8c72..e74d1848d 100644 --- a/SRC/element/fourNodeQuad/FourNodeQuadWithSensitivity.h +++ b/SRC/element/fourNodeQuad/FourNodeQuadWithSensitivity.h @@ -106,6 +106,7 @@ class FourNodeQuadWithSensitivity : public Element // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/element/fourNodeQuad/NineNodeQuad.h b/SRC/element/fourNodeQuad/NineNodeQuad.h index 3beac28e3..deb51a521 100644 --- a/SRC/element/fourNodeQuad/NineNodeQuad.h +++ b/SRC/element/fourNodeQuad/NineNodeQuad.h @@ -95,6 +95,7 @@ class NineNodeQuad : public Element { // stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: private: diff --git a/SRC/element/fourNodeQuad/SixNodeTri.h b/SRC/element/fourNodeQuad/SixNodeTri.h index bcae2bf2d..beff9925f 100644 --- a/SRC/element/fourNodeQuad/SixNodeTri.h +++ b/SRC/element/fourNodeQuad/SixNodeTri.h @@ -95,6 +95,7 @@ class SixNodeTri : public Element { // stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: private: diff --git a/SRC/element/frictionBearing/SingleFPSimple2d.cpp b/SRC/element/frictionBearing/SingleFPSimple2d.cpp index 8de116281..519f0c580 100755 --- a/SRC/element/frictionBearing/SingleFPSimple2d.cpp +++ b/SRC/element/frictionBearing/SingleFPSimple2d.cpp @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include @@ -1162,3 +1164,29 @@ double SingleFPSimple2d::sgn(double x) else return 0.0; } + +int +SingleFPSimple2d::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc < 1) + return -1; + + if (strcmp(argv[0],"R") == 0 || strcmp(argv[0],"Reff") == 0) { + param.setValue(Reff); + return param.addObject(1,this); + } + else + return theFrnMdl->setParameter(argv, argc, param); +} + +int +SingleFPSimple2d::updateParameter(int parameterID, Information &info) +{ + switch (parameterID) { + case 1: + Reff = info.theDouble; + return 0; + default: + return -1; + } +} diff --git a/SRC/element/frictionBearing/SingleFPSimple2d.h b/SRC/element/frictionBearing/SingleFPSimple2d.h index 48eedaeb4..a6acb35a5 100755 --- a/SRC/element/frictionBearing/SingleFPSimple2d.h +++ b/SRC/element/frictionBearing/SingleFPSimple2d.h @@ -92,7 +92,10 @@ class SingleFPSimple2d : public Element 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); + protected: private: diff --git a/SRC/element/frictionBearing/SingleFPSimple3d.cpp b/SRC/element/frictionBearing/SingleFPSimple3d.cpp index 053566813..95c8c93ff 100755 --- a/SRC/element/frictionBearing/SingleFPSimple3d.cpp +++ b/SRC/element/frictionBearing/SingleFPSimple3d.cpp @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include @@ -1310,3 +1312,29 @@ void SingleFPSimple3d::setUp() Tlb(2,4) = -Tlb(1,5); Tlb(2,10) = -Tlb(1,11); } + +int +SingleFPSimple3d::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc < 1) + return -1; + + if (strcmp(argv[0],"R") == 0 || strcmp(argv[0],"Reff") == 0) { + param.setValue(Reff); + return param.addObject(1,this); + } + else + return theFrnMdl->setParameter(argv, argc, param); +} + +int +SingleFPSimple3d::updateParameter(int parameterID, Information &info) +{ + switch (parameterID) { + case 1: + Reff = info.theDouble; + return 0; + default: + return -1; + } +} diff --git a/SRC/element/frictionBearing/SingleFPSimple3d.h b/SRC/element/frictionBearing/SingleFPSimple3d.h index 85de84d7d..a1f356900 100755 --- a/SRC/element/frictionBearing/SingleFPSimple3d.h +++ b/SRC/element/frictionBearing/SingleFPSimple3d.h @@ -92,7 +92,10 @@ class SingleFPSimple3d : public Element 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); + protected: private: diff --git a/SRC/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn2d.cpp b/SRC/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn2d.cpp index fda9f13ae..959693b01 100644 --- a/SRC/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn2d.cpp +++ b/SRC/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn2d.cpp @@ -61,9 +61,9 @@ void* OPS_GradientInelasticBeamColumn2d() { // Necessary Arguments - if (OPS_GetNumRemainingInputArgs() < 11) { + if (OPS_GetNumRemainingInputArgs() < 8) { opserr << "WARNING! gradientInelasticBeamColumn2d - insufficient arguments\n" << - " Want: eleTag? iNode? jNode? transfTag? integrationTag? lc?\n" << + " Want: eleTag? iNode? jNode? transfTag? integrationTag? lambda1? lambda2? lc?\n" << " <-constH> <-iter maxIter? minTol? maxTol?> <-corControl maxEpsInc? maxPhiInc?>\n"; return 0; } @@ -89,13 +89,17 @@ void* OPS_GradientInelasticBeamColumn2d() int transfTag = iData[3]; int integrTag = iData[4]; - double LC; - numData = 1; - if (OPS_GetDoubleInput(&numData, &LC) < 0) { - opserr << "WARNING! gradientInelasticBeamColumn2d - invalid lc\n"; + double ddata[3]; + numData = 3; + if (OPS_GetDoubleInput(&numData, ddata) < 0) { + opserr << "WARNING! gradientInelasticBeamColumn2d - invalid double input\n"; return 0; } + double lam1 = ddata[0]; + double lam2 = ddata[1]; + double lc = ddata[2]; + // Optional Arguments int maxIter = 50; double minTol = 1E-10, maxTol = 1E-8; @@ -173,7 +177,7 @@ void* OPS_GradientInelasticBeamColumn2d() int numIntegrPoints = secTags.Size(); for (int i = 2; i < numIntegrPoints; i++) { - if (secTags(i) == secTags(i - 1)) { + if (secTags(i) != secTags(i - 1)) { opserr << "WARNING! gradientInelasticBeamColumn2d - internal integration points should have identical tags\n" << "continued using section tag of integration point 2 for all internal integration points\n"; return 0; @@ -199,7 +203,7 @@ void* OPS_GradientInelasticBeamColumn2d() } Element* theEle = new GradientInelasticBeamColumn2d(eleTag, nodeTagI, nodeTagJ, numIntegrPoints, &endSection1, &intSection, &endSection2, - 0.01, 0.01, *beamIntegr, *theTransf, LC, minTol, maxTol, maxIter, constH, correctionControl, maxEpsInc, maxPhiInc); + lam1, lam2, *beamIntegr, *theTransf, lc, minTol, maxTol, maxIter, constH, correctionControl, maxEpsInc, maxPhiInc); return theEle; } diff --git a/SRC/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn3d.cpp b/SRC/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn3d.cpp index b94bdef0a..981a3b94d 100644 --- a/SRC/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn3d.cpp +++ b/SRC/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn3d.cpp @@ -61,9 +61,9 @@ void* OPS_GradientInelasticBeamColumn3d() { // Necessary Arguments - if (OPS_GetNumRemainingInputArgs() < 11) { + if (OPS_GetNumRemainingInputArgs() < 8) { opserr << "WARNING! gradientInelasticBeamColumn3d - insufficient arguments\n" << - " Want: eleTag? iNode? jNode? transfTag? integrationTag? lc?\n" << + " Want: eleTag? iNode? jNode? transfTag? integrationTag? lambda1? lambda2? lc?\n" << " <-constH> <-iter maxIter? minTol? maxTol?> <-corControl maxEpsInc? maxPhiInc?>\n"; return 0; } @@ -89,13 +89,16 @@ void* OPS_GradientInelasticBeamColumn3d() int transfTag = iData[3]; int integrTag = iData[4]; - double LC; - numData = 1; - if (OPS_GetDoubleInput(&numData, &LC) < 0) { + double ddata[3]; + numData = 3; + if (OPS_GetDoubleInput(&numData, ddata) < 0) { opserr << "WARNING! gradientInelasticBeamColumn3d - invalid lc\n"; return 0; } - + double lam1 = ddata[0]; + double lam2 = ddata[1]; + double lc = ddata[2]; + // Optional Arguments int maxIter = 50; double minTol = 1E-10, maxTol = 1E-8; @@ -173,7 +176,7 @@ void* OPS_GradientInelasticBeamColumn3d() int numIntegrPoints = secTags.Size(); for (int i = 2; i < numIntegrPoints; i++) { - if (secTags(i) == secTags(i - 1)) { + if (secTags(i) != secTags(i - 1)) { opserr << "WARNING! gradientInelasticBeamColumn3d - internal integration points should have identical tags\n" << "continued using section tag of integration point 2 for all internal integration points\n"; return 0; @@ -199,7 +202,7 @@ void* OPS_GradientInelasticBeamColumn3d() } Element* theEle = new GradientInelasticBeamColumn3d(eleTag, nodeTagI, nodeTagJ, numIntegrPoints, &endSection1, &intSection, &endSection2, - 0.01, 0.01, *beamIntegr, *theTransf, LC, minTol, maxTol, maxIter, constH, correctionControl, maxEpsInc, maxPhiInc); + lam1, lam2, *beamIntegr, *theTransf, lc, minTol, maxTol, maxIter, constH, correctionControl, maxEpsInc, maxPhiInc); return theEle; } @@ -807,8 +810,8 @@ GradientInelasticBeamColumn3d::revertToLastCommit(void) sections[i]->setTrialSectionDeformation(d_sec[i]); } - d_tot = d_tot_commit; - d_nl_tot = d_nl_tot_commit; + *d_tot = *d_tot_commit; + *d_nl_tot = *d_nl_tot_commit; // Revert Coordinate Transformation Object to Last Committed State if ((err = crdTransf->revertToLastCommit())) diff --git a/SRC/element/masonry/BeamGT.cpp b/SRC/element/masonry/BeamGT.cpp new file mode 100644 index 000000000..92e9d903d --- /dev/null +++ b/SRC/element/masonry/BeamGT.cpp @@ -0,0 +1,1283 @@ +/* ****************************************************************** ** +** 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 by: Gonzalo Torrisi, Universidad Nacional de Cuyo + +// we specify what header files we need +#include "BeamGT.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// initialise the class wide variables +Matrix BeamGT::BeamK(6,6); +Vector BeamGT::BeamR(6); + +void* OPS_BeamGT() + +{ + // print out a message about who wrote this element & any copyright info wanted + //if (numMyBeam == 0) { +// opserr << " \n"; +// opserr << " Beam with Flexure and Shear Hinges\n"; +// opserr << " Written by Gonzalo Torrisi UNCuyo Copyright 2016\n"; +// opserr << " Only in plane X-Y \n"; +// opserr << " Use at your Own Peril\n"; + + // numMyBeam++; + //} + + Element *theBeam = 0; + + int numRemainingArgs = OPS_GetNumRemainingInputArgs(); + if (numRemainingArgs == 0) { // parallel processing + theBeam = new BeamGT(); + return theBeam; + } + + if (numRemainingArgs != 14) { + opserr << "ERROR - BeamGT not enough args provided, want: element BeamGT tag? Node1? Node2? matTag? matTag2? matTag3? E? G? A? I? Lp1? Lp2? Lr? fc?\n"; + // numMyBeam++; + } + + // get the id and end nodes + int iData[6]; + double dData[8]; + int numData; + + numData = 3; + if (OPS_GetIntInput(&numData, iData) != 0) { + opserr << "WARNING invalid element data\n"; + return 0; + } + int eleTag = iData[0]; + + numData =1; + if (OPS_GetIntInput(&numData, &iData[3]) != 0) { + opserr << "WARNING error reading element material 1 tag for element " << eleTag << endln; + return 0; + } + numData =1; + if (OPS_GetIntInput(&numData, &iData[4]) != 0) { + opserr << "WARNING error reading element material 2 tag for element " << eleTag << endln; + return 0; + } + numData =1; + if (OPS_GetIntInput(&numData, &iData[5]) != 0) { + opserr << "WARNING error reading element material 3 tag for element " << eleTag << endln; + return 0; + } + int matID = iData[3]; + int matID2 = iData[4]; + int matID3 = iData[5]; + + numData =8 ; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING error reading Elastic properties for element" << eleTag << endln; + return 0; + } + + + UniaxialMaterial *theMaterial = OPS_GetUniaxialMaterial(matID); + UniaxialMaterial *theMaterial2 =OPS_GetUniaxialMaterial(matID2); + UniaxialMaterial *theMaterial3 =OPS_GetUniaxialMaterial(matID3); + + if (theMaterial == 0) { + opserr << "WARNING material with tag " << matID << "not found for element " << eleTag << endln; + return 0; + } + + if (theMaterial2 == 0) { + opserr << "WARNING material with tag " << matID2 << "not found for element " << eleTag << endln; + return 0; + } + if (theMaterial3 == 0) { + opserr << "WARNING material with tag " << matID3 << "not found for element " << eleTag << endln; + return 0; + } + // now create the truss and add it to the Domain + + theBeam = new BeamGT(eleTag, iData[1], iData[2], *theMaterial, *theMaterial2, *theMaterial3, dData[0],dData[1],dData[2],dData[3],dData[4],dData[5],dData[6],dData[7] ); + + if (theBeam == 0) { + opserr << "WARNING ran out of memory creating element with tag " << eleTag << endln; + delete theMaterial; + delete theMaterial2; + delete theMaterial3; + return 0; + } + + return theBeam; +} + + +// typical constructor +BeamGT::BeamGT(int tag, + int Nd1, int Nd2, + UniaxialMaterial &theMat, UniaxialMaterial &theMat2, UniaxialMaterial &theMat3, + double e, double g, double a, double i, double lp1, double lp2, double lr, double fc) +:Element(tag, ELE_TAG_BeamGT), + externalNodes(2), + trans(4,4),E(e), G(g), A(a), I(i), LP1(lp1),LP2(lp2),LR(lr),FC(fc), theMaterial(0),theMaterial2(0),theMaterial3(0),Tm(6,6),TTm(6,6),Cdefor(3),Tdefor(3),Cdespla(6),Tdespla(6),Stifloc(6,6),Stif0(6,6),Cesf(3),Tesf(3),RR(3) + //L1(0.0),L2(0.0),L3(0.0),L4(0.0),L5(0.0),L6(0.0) +{ + // allocate memory for numMaterials1d uniaxial material models + theMaterial = new UniaxialMaterial *[2]; + theMaterial2= 0; + theMaterial3= 0; + + + if ( theMaterial == 0 ) { + opserr << "FATAL BeamGT::BeamGT - failed to create a 1d material or direction array\n"; + exit(-1); + } + + // get a copy of the material and check we obtained a valid copy + + theMaterial[0]= theMat.getCopy(); + theMaterial[1]= theMat.getCopy(); + theMaterial2= theMat2.getCopy(); + theMaterial3= theMat3.getCopy(); + + for (int i=0; i<2; i++) { + if (theMaterial[i] == 0) { + opserr << "FATAL BeamGT::BeamGT - failed to get a copy of material\n" ; + exit(-1); + } + } + + if (theMaterial2== 0){ + opserr << "FATAL BeamGT::BeamGT - failed to get a copy of material2\n"; + } + + if (theMaterial3== 0){ + opserr << "FATAL BeamGT::BeamGT - failed to get a copy of material3\n"; + } + + + // fill in the ID containing external node info with node id's + if (externalNodes.Size() != 2) { + opserr << "FATAL BeamGT::BeamGT() - out of memory, could not create an ID of size 2\n"; + exit(-1); + } + + externalNodes(0) = Nd1; + externalNodes(1) = Nd2; + + + theNodes[0] = 0; + theNodes[1] = 0; +} + +// constructor which should be invoked by an FE_ObjectBroker only +BeamGT::BeamGT() +:Element(0, ELE_TAG_BeamGT), + theMaterial(0), + theMaterial2(0), + theMaterial3(0), + externalNodes(2), + trans(4,4), E(0.0),A(0.0),G(0.0),I(0.0),LP1(0.0),LP2(0.0), LR(0.0),FC(0.0),Tm(6,6),TTm(6,6),Cdefor(3),Tdefor(3),Cdespla(6),Tdespla(6),Stifloc(6,6),Stif0(6,6),Cesf(3),Tesf(3),RR(3) +{ + theNodes[0] = 0; + theNodes[1] = 0; +} + +// destructor - provided to clean up any memory +BeamGT::~BeamGT() +{ + // clean up the memory associated with the element, this is + // memory the Truss2D objects allocates and memory allocated + // by other objects that the Truss2D object is responsible for + // cleaning up, i.e. the MaterialObject. + for (int i=0; i<2; i++) { + if (theMaterial[i] != 0) + delete theMaterial[i]; + } + delete [] theMaterial; + delete theMaterial2; + delete theMaterial3; +} + +int +BeamGT::getNumExternalNodes(void) const +{ + return 2; +} + +const ID & +BeamGT::getExternalNodes(void) +{ + return externalNodes; +} + +Node ** +BeamGT::getNodePtrs(void) +{ + return theNodes; +} + +int +BeamGT::getNumDOF(void) { + return 6; +} + +// method: setDomain() +// to set a link to the enclosing Domain, ensure nodes exist in Domain +// and set pointers to these nodes, also determines the length and +// transformation Matrix. + +void +BeamGT::setDomain(Domain *theDomain) +{ + // check Domain is not null - invoked when object removed from a domain + if (theDomain == 0) { + return; + } + + // first ensure nodes exist in Domain and set the node pointers + Node *end1Ptr, *end2Ptr; + int Nd1 = externalNodes(0); + int Nd2 = externalNodes(1); + + end1Ptr = theDomain->getNode(Nd1); + end2Ptr = theDomain->getNode(Nd2); + + + if (end1Ptr == 0) { + opserr << "WARNING BeamGT::setDomain() - at Beam " << this->getTag() << " node " << + Nd1 << " does not exist in domain\n"; + + return; // don't go any further - otherwise segemntation fault + } + if (end2Ptr == 0) { + opserr << "WARNING BeamGT::setDomain() - at Beam " << this->getTag() << " node " << + Nd2 << " does not exist in domain\n"; + + return; // don't go any further - otherwise segemntation fault + } + + theNodes[0] = end1Ptr; + theNodes[1] = end2Ptr; + + + // call the DomainComponent class method THIS IS VERY IMPORTANT + this->DomainComponent::setDomain(theDomain); + + // ensure connected nodes have correct number of dof's + int dofNd1 = end1Ptr->getNumberDOF(); + int dofNd2 = end2Ptr->getNumberDOF(); + + + if ((dofNd1 != 3 || dofNd2 != 3)) { + opserr << "BeamGT::setDomain(): 3 dof required at nodes\n"; + return; + } + + // now determine the length & transformation matrix + const Vector &end1Crd = end1Ptr->getCrds(); + const Vector &end2Crd = end2Ptr->getCrds(); + + + double dx = end2Crd(0)-end1Crd(0); + double dy = end2Crd(1)-end1Crd(1); + double L = sqrt(dx*dx + dy*dy); + if (L == 0.0) { + opserr << "WARNING BeamGT::setDomain() - BeamGT " << this->getTag() <<" has zero length\n"; + return; // don't go any further - otherwise divide by 0 error + } + + // cosenos de las diagonales + double coseno=dx/L; + double seno=dy/L; + trans(0,0)=L; + trans(0,1)=coseno; + trans(0,2)=seno; + this->revertToStart(); + this->revertToLastCommit(); + +} + +int +BeamGT::commitState() +{ + int ecode=0; + //commit material models + for (int i=0; i<2; i++) { + ecode += theMaterial[i]->commitState(); + } + //commit the base class + ecode += theMaterial2->commitState(); + ecode += theMaterial3->commitState(); + Cdeltares=Tdeltares; + for (int i=0; i<3; i++) { + Cdefor[i]=Tdefor[i]; + } + for (int i=0; i<6; i++) { + Cdespla[i]=Tdespla[i]; + } + for (int i=0; i<3; i++) { + Cesf[i]=Tesf[i]; + } + + RR[0]=dcur1c; + RR[1]=dcur2c; + RR[2]=dgamc; + RR[3]=daxc; + + return ecode; +} + +int +BeamGT::revertToLastCommit() +{ +// return theMaterial->revertToLastCommit(); + int code=0; + + // revert state for 1d materials + for (int i=0; i<2; i++) { + code += theMaterial[i]->revertToLastCommit(); + } + code += theMaterial2->revertToLastCommit(); + code += theMaterial3->revertToLastCommit(); + Tdeltares=Cdeltares; + for (int i=0; i<3; i++) { + Tdefor[i]=Cdefor[i]; + } + for (int i=0; i<6; i++) { + Tdespla[i]=Cdespla[i]; + } + for (int i=0; i<3; i++) { + Tesf[i]=Cesf[i]; + } + + dcur1c=RR[0]; + dcur2c=RR[1]; + dgamc=RR[2]; + daxc = RR[3]; + + return code; +} + +int +BeamGT::revertToStart() +{ + // return theMaterial->revertToStart(); + int code=0; + + // revert state for 1d materials + for (int i=0; i<2; i++) { + code += theMaterial[i]->revertToStart(); + } + code += theMaterial2->revertToStart(); + code += theMaterial3->revertToStart(); + for (int i=0; i<3; i++) { + Cdefor[i]=0.0; + Tdefor[i]=0.0; + } + for (int i=0; i<6; i++) { + Cdespla[i]=0.0; + Tdespla[i]=0.0; + } + for (int i=0; i<3; i++) { + Cesf[i]=0.0; + Tesf[i]=0.0; + } + + for (int i=0; i<6; i++){ + for (int j=0; j<6; j++){ + Stifloc(i,j)=0.0; + Stif0(i,j)=0.0; + } + } + for (int i=0; i<3; i++){ + RR(i)=0.0; + } + + return code; +} + +int +BeamGT::update() +{ + // determine the current strain given trial displacements at nodes + // double strain = this->computeCurrentStrain(); + + // set the strain in the materials + //theMaterial->setTrialStrain(strain); + + // compute strain and rate; set as current trial for material + // strain = this->computeCurrentStrain(mat ); + // strainRate = this->computeCurrentStrain(); + + + // opserr << "Material for Axial :" << *theMaterial3<< "\n"; + double str[3]; + + // determine the strain + const Vector &disp1 = theNodes[0]->getTrialDisp(); + const Vector &disp2 = theNodes[1]->getTrialDisp(); + const Vector &Idisp1 =theNodes[0]->getIncrDisp(); + const Vector &Idisp2 =theNodes[1]->getIncrDisp(); + + //double r1c=RR[0]; + //double r2c=RR[1]; + + double L=trans(0,0); + double c1=trans(0,1); + double s1=trans(0,2); + //global displacements + // double cur1=0.0; + // double cur2=0.0; + // double dg=0.0; + // double gam=0.0; + // double dcur1=0.0; + // double dcur2=0.0; + // double dgam=0.0; + // displacements at the ends of the beam + double dx1=Idisp1(0); + double dy1=Idisp1(1); + double r1=Idisp1(2); + double dx2=Idisp2(0); + double dy2=Idisp2(1); + double r2=Idisp2(2); + double x1=disp1(0); + double x2=disp2(0); + double y1=disp1(1); + double y2=disp2(1); + + + //Displacements at the ends of the beam in local coordinates + double u1 = dx1*c1+dy1*s1; + double v1 = -dx1*s1+dy1*c1; + double u2 = dx2*c1+dy2*s1; + double v2 = -dx2*s1+dy2*c1; + double xnorm = 1.0; + double du1 = x1*c1+y1*s1; + double du2 = x2*c1+y2*s1; + + + //CURVATURES + //incremento de esfuerzos de extremo y curvaturas + double DM1=0.0; + double DM2=0.0; + double DV=0.0; + double DN = 0.0; + + //tengo que traer la matriz de rigidez convergida + + //matriz de rigidez en locales + double a1=theMaterial[0]->getTangent(); + double b1=theMaterial[0]->getInitialTangent(); + double re1=a1/b1; + double f1=(1.0-re1)*LP1/(re1*E*I); + + double a2=theMaterial[1]->getTangent(); + double b2=theMaterial[1]->getInitialTangent(); + double re2=a2/b2; + double f2=(1.0-re2)*LP2/(re2*E*I); + + double a3=theMaterial2->getTangent(); + double b3=theMaterial2->getInitialTangent(); + double re3=a3/b3; + double f3=(1.0-re3)*LR/(re3*G*A*L*L); + // Tangent Flexibility matrix + double f11=L/(3.0*E*I)+f1+FC*1.2/(L*A*G)+f3; + double f22=L/(3.0*E*I)+f2+FC*1.2/(L*A*G)+f3; + double f12=-L/(6.0*E*I)+FC*1.2/(L*A*G)+f3; + + double det=f11*f22-f12*f12; + double fa1=f22/det; + double fb1=-f12/det; + double fc1=-f12/det; + double fd1=f11/det; + double x=1.0/L; + double Am=(fa1+2*fb1+fd1)*x*x; + double B=(fa1+fb1)*x; + double C=(fb1+fd1)*x; + + DV=Am*(v1-v2)+B*r1+C*r2; + DM1=B*(v1-v2)+fa1*r1+fb1*r2; + DM2=C*(v1-v2)+fb1*r1+fd1*r2; + + double dcur1=DM1/theMaterial[0]->getTangent(); + double dcur2=DM2/theMaterial[1]->getTangent(); + double dgam=DV/theMaterial2->getTangent(); + double dax=(du2-du1)/L; + + double ret=0; + dcur1c=dcur1c+dcur1; + dcur2c=dcur2c+dcur2; + dgamc=dgamc+dgam; + daxc = 0.0; + daxc = daxc + dax; + ret=theMaterial3->setTrialStrain(daxc); + double N=1.0*theMaterial3->getStress(); + ret=theMaterial[0]->setTrialStrain(dcur1c,N); + ret=theMaterial[1]->setTrialStrain(dcur2c,N); + ret=theMaterial2->setTrialStrain(dgamc,N); + + return ret; +} + +const Matrix & +BeamGT::getTangentStiff(void) +{ + double L=trans(0,0); + double c1=trans(0,1); + double s1=trans(0,2); + + //Tangent Flexibility matrix + double a1=theMaterial[0]->getTangent(); + double b1=theMaterial[0]->getInitialTangent(); + double re1=a1/b1; + + double f1=(1.0-re1)*LP1/(re1*b1); + double a2=theMaterial[1]->getTangent(); + double b2=theMaterial[1]->getInitialTangent(); + double re2=a2/b2; + double f2=(1.0-re2)*LP2/(re2*b2); + double a3=theMaterial2->getTangent(); + double b3=theMaterial2->getInitialTangent(); + double re3=a3/b3; + double f3=(1.0-re3)*LR/(re3*b3*L*L); + double EA=theMaterial3->getTangent(); + + if(re3>1.0){ + re3=1.0; + } + + double f11=L/(3.0*b2)+f1+FC*1.2/(L*A*G)+f3; + double f22=L/(3.0*b2)+f2+FC*1.2/(L*A*G)+f3; + double f12=-L/(6.0*b2)+FC*1.2/(L*A*G)+f3; + + + //TAngent stiffness + double det=f11*f22-f12*f12; + double fa1=f22/det; + double fb1=-f12/det; + double fc1=-f12/det; + double fd1=f11/det; + double x=1.0/L; + + double Am=(fa1+2*fb1+fd1)*x*x; + double B=(fa1+fb1)*x; + double C=(fb1+fd1)*x; + + //Beam tangent stiffness matrix in global coordinates + BeamK(0,0)=EA/L*c1*c1+Am*s1*s1; + BeamK(0,1)=EA/L*c1*s1-Am*c1*s1; + BeamK(0,2)=-B*s1; + BeamK(0,3)=-EA/L*c1*c1-Am*s1*s1; + BeamK(0,4)=-EA/L*c1*s1+Am*s1*c1; + BeamK(0,5)=-C*s1; + + BeamK(1,0)=BeamK(0,1); + BeamK(1,1)=EA/L*s1*s1+Am*c1*c1; + BeamK(1,2)=B*c1; + BeamK(1,3)=-EA/L*s1*c1+Am*s1*c1; + BeamK(1,4)=-EA/L*s1*s1-Am*c1*c1; + BeamK(1,5)=C*c1; + + BeamK(2,0)=BeamK(0,2); + BeamK(2,1)=BeamK(1,2); + BeamK(2,2)=fa1; + BeamK(2,3)=B*s1; + BeamK(2,4)=-B*c1; + BeamK(2,5)=fb1; + + BeamK(3,0)=-EA/L*c1*c1-Am*s1*s1; + BeamK(3,1)=-EA/L*c1*s1+Am*s1*c1; + BeamK(3,2)=B*s1; + BeamK(3,3)=EA/L*c1*c1+Am*s1*s1; + BeamK(3,4)=EA/L*s1*c1-Am*s1*c1; + BeamK(3,5)=C*s1; + + BeamK(4,0)=-EA/L*c1*s1+Am*c1*s1; + BeamK(4,1)=-EA/L*s1*s1-Am*c1*c1; + BeamK(4,2)=-B*c1; + BeamK(4,3)=EA/L*c1*s1-Am*s1*c1; + BeamK(4,4)=EA/L*s1*s1+Am*c1*c1; + BeamK(4,5)=-C*c1; + + BeamK(5,0)=-C*s1; + BeamK(5,1)=C*c1; + BeamK(5,2)=fb1; + BeamK(5,3)=C*s1; + BeamK(5,4)=-C*c1; + BeamK(5,5)=fd1; + return BeamK; +} + +const Matrix & +BeamGT::getInitialStiff(void) +{ + //Calculo la flexibilidad y luego la invierto + double L=trans(0,0); + double c1=trans(0,1); + double s1=trans(0,2); + + + double f11=L/(3.0*E*I)+FC*1.2/(L*A*G); + double f22=L/(3.0*E*I)+FC*1.2/(L*A*G); + double f12=-L/(6.0*E*I)+FC*1.2/(L*A*G); + double EA=theMaterial3->getInitialTangent(); + + double det=f11*f22-f12*f12; + double fa1=f22/det; + double fb1=-f12/det; + double fc1=-f12/det; + double fd1=f11/det; + double x=1.0/L; + + double Am=(fa1+2*fb1+fd1)*x*x; + double B=(fa1+fb1)*x; + double C=(fb1+fd1)*x; + + //Beam tangent stiffness matrix in global coordinates + BeamK(0,0)=EA/L*c1*c1+Am*s1*s1; + BeamK(0,1)=EA/L*c1*s1-Am*c1*s1; + BeamK(0,2)=-B*s1; + BeamK(0,3)=-EA/L*c1*c1-Am*s1*s1; + BeamK(0,4)=-EA/L*c1*s1+Am*s1*c1; + BeamK(0,5)=-C*s1; + + BeamK(1,0)=BeamK(0,1); + BeamK(1,1)=EA/L*s1*s1+Am*c1*c1; + BeamK(1,2)=B*c1; + BeamK(1,3)=-EA/L*s1*c1+Am*s1*c1; + BeamK(1,4)=-EA/L*s1*s1-Am*c1*c1; + BeamK(1,5)=C*c1; + + BeamK(2,0)=BeamK(0,2); + BeamK(2,1)=BeamK(1,2); + BeamK(2,2)=fa1; + BeamK(2,3)=B*s1; + BeamK(2,4)=-B*c1; + BeamK(2,5)=fb1; + + BeamK(3,0)=-EA/L*c1*c1-Am*s1*s1; + BeamK(3,1)=-EA/L*c1*s1+Am*s1*c1; + BeamK(3,2)=B*s1; + BeamK(3,3)=EA/L*c1*c1+Am*s1*s1; + BeamK(3,4)=EA/L*s1*c1-Am*s1*c1; + BeamK(3,5)=C*s1; + + BeamK(4,0)=-EA/L*c1*s1+Am*c1*s1; + BeamK(4,1)=-EA/L*s1*s1-Am*c1*c1; + BeamK(4,2)=-B*c1; + BeamK(4,3)=EA/L*c1*s1-Am*s1*c1; + BeamK(4,4)=EA/L*s1*s1+Am*c1*c1; + BeamK(4,5)=-C*c1; + + BeamK(5,0)=-C*s1; + BeamK(5,1)=C*c1; + BeamK(5,2)=fb1; + BeamK(5,3)=C*s1; + BeamK(5,4)=-C*c1; + BeamK(5,5)=fd1; + + // opserr<<" initial stiffness "<< "\n"; + return BeamK; +} + +const Vector & +BeamGT::getResistingForce() +{ + + const Vector &disp1 = theNodes[0]->getTrialDisp(); + const Vector &disp2 = theNodes[1]->getTrialDisp(); + double L=trans(0,0); + double c1=trans(0,1); + double s1=trans(0,2); + + double dx1=disp1(0); + double dy1=disp1(1); + double dr1=disp1(2); + double dx2=disp2(0); + double dy2=disp2(1); + double dr2=disp2(2); + double du1=dx1*c1+dy1*s1; + double dv1=-dx1*s1+dy1*c1; + double du2=dx2*c1+dy2*s1; + double dv2=-dx2*s1+dy2*c1; + + + +// double N=E*A*(du1-du2)/L; +// double V1=theMaterial2->getStress(); + double M1=theMaterial[0]->getStress(); + double M2=theMaterial[1]->getStress(); + double V1=theMaterial2->getStress(); + double N=-1.0*theMaterial3->getStress(); +//double V1=(M1+M2)/L; + double V2=-V1; + double N2=-N; + BeamR(0)=1.0*(N*c1-V1*s1); + BeamR(1)=1.0*(N*s1+V1*c1); + BeamR(2)=1.0*M1; + BeamR(3)=(N2*c1-V2*s1); + BeamR(4)=(N2*s1+V2*c1); + BeamR(5)=1.0*M2; +// opserr<<" N= "<getDbTag(); + + // Truss2D packs it's data into a Vector and sends this to theChannel + // along with it's dbTag and the commitTag passed in the arguments + + Vector data(16); + data(0)=this->getTag(); + data(1)=A; + data(2)=I; + data(3)=E; + data(4)=G; + data(5)=LP1; + data(6)=LP2; + data(7)=LR; + data(8)=theMaterial[0]->getClassTag(); + data(9)=theMaterial[1]->getClassTag(); + data(10)=theMaterial2->getClassTag(); + data(14)=theMaterial3->getClassTag(); + int matDbTag1=theMaterial[0]->getDbTag(); + int matDbTag2=theMaterial[1]->getDbTag(); + int matDbTag3=theMaterial2->getDbTag(); + int matDbTag4=theMaterial3->getDbTag(); + + if (matDbTag1==0){ + matDbTag1=theChannel.getDbTag(); + if (matDbTag1 !=0) + theMaterial[0]->setDbTag(matDbTag1); + } + data(11)=matDbTag1; + + if (matDbTag2==0){ + matDbTag2=theChannel.getDbTag(); + if (matDbTag2 !=0) + theMaterial[1]->setDbTag(matDbTag2); + } + data(12)=matDbTag2; + + if (matDbTag3==0){ + matDbTag3=theChannel.getDbTag(); + if (matDbTag3 !=0) + theMaterial2->setDbTag(matDbTag3); + } + data(13)=matDbTag3; + + + + if (matDbTag4==0){ + matDbTag4=theChannel.getDbTag(); + if (matDbTag4 !=0) + theMaterial3->setDbTag(matDbTag4); + } + data(15)=matDbTag4; + + + res=0; + res = theChannel.sendVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING BeamGT::sendSelf() - failed to send Vector\n"; + return -1; + } + + // Truss2D then sends the tags of it's two end nodes + res = theChannel.sendID(dataTag, commitTag, externalNodes); + if (res < 0) { + opserr << "WARNING BeamGT::sendSelf() - failed to send ID\n"; + return -2; + } + + // finally Truss2D asks it's material object to send itself + res = theMaterial[0]->sendSelf(commitTag, theChannel); + if (res < 0) { + opserr << "WARNING BeamGT::sendSelf() - failed to send the Material\n"; + return -3; + } + res = theMaterial[1]->sendSelf(commitTag, theChannel); + if (res < 0) { + opserr << "WARNING BeamGT::sendSelf() - failed to send the Material\n"; + return -3; + } + res = theMaterial2->sendSelf(commitTag, theChannel); + if (res < 0) { + opserr << "WARNING BeamGT::sendSelf() - failed to send the Material\n"; + return -3; + } + + res = theMaterial3->sendSelf(commitTag, theChannel); + if (res < 0) { + opserr << "WARNING BeamGT::sendSelf() - failed to send the Material\n"; + return -3; + } + + return 0; +} + +int +BeamGT::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +{ + + + int res; + int dataTag = this->getDbTag(); + + // Truss2D creates a Vector, receives the Vector and then sets the + // internal data with the data in the Vector + + Vector data(16); + res = theChannel.recvVector(dataTag, commitTag, data); + res=-1; + if (res < 0) { + opserr << "WARNING BeamGT::recvSelf() - failed to receive Vector\n"; + return -1; + } + + this->setTag((int)data(0)); + + + A=data(1); + I=data(2); + E=data(3); + G=data(4); + LP1=data(5); + LP2=data(6); + LR=data(7); + + + // Truss2D now receives the tags of it's two external nodes + res = theChannel.recvID(dataTag, commitTag, externalNodes); + if (res < 0) { + opserr << "WARNING BeamGT::recvSelf() - failed to receive ID\n"; + return -2; + } + + // we create a material object of the correct type, + // sets its database tag and asks this new object to recveive itself. + int matClass1 = data(8); + int matClass2 = data(9); + int matClass3 = data(10); + int matDb1 = data(11); + int matDb2 = data(12); + int matDb3 = data(13); + int matClass4 = data(14); + int matDb4 = data(15); + theMaterial[0] = theBroker.getNewUniaxialMaterial(matClass1); + if (theMaterial[0] == 0) { + opserr << "WARNING BeamGT::recvSelf() - failed to create a Material[0]\n"; + return -3; + } + + + theMaterial[1] = theBroker.getNewUniaxialMaterial(matClass2); + if (theMaterial[1] == 0) { + opserr << "WARNING BeamGT::recvSelf() - failed to create a Material[1]\n"; + return -3; + } + theMaterial2 = theBroker.getNewUniaxialMaterial(matClass3); + if (theMaterial2 == 0) { + opserr << "WARNING BeamGT::recvSelf() - failed to create a Material2\n"; + return -3; + } + theMaterial3 = theBroker.getNewUniaxialMaterial(matClass4); + if (theMaterial3 == 0) { + opserr << "WARNING BeamGT::recvSelf() - failed to create a Material3\n"; + return -3; + } + + + + + // we set the dbTag before we receive the material - this is important + theMaterial[0]->setDbTag(matDb1); + res = theMaterial[0]->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "WARNING BeamGT::recvSelf() - failed to receive the Material\n"; + return -3; + } + theMaterial[1]->setDbTag(matDb2); + res = theMaterial[1]->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "WARNING BeamGT::recvSelf() - failed to receive the Material\n"; + return -3; + } + + theMaterial2->setDbTag(matDb3); + res = theMaterial2->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "WARNING BeamGT::recvSelf() - failed to receive the Material\n"; + return -3; + } + + + theMaterial3->setDbTag(matDb4); + res = theMaterial2->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "WARNING BeamGT::recvSelf() - failed to receive the Material\n"; + return -3; + } + + return 0; +} + +void +BeamGT::Print(OPS_Stream &s, int flag) +{ + + s << " " << "\n"; + s << " " << "\n"; + s << "Element: " << this->getTag(); + s << " type: BeamGT " << "\n"; + s << " " << "\n"; + s << "+--------------------------------------------------------+"<< "\n"; + s << "| Beam with Flexure and Shear Hinges |\n"; + s << "| Written by Gonzalo Torrisi UNCuyo Copyright 2016 |\n"; + s << "| Only in plane X-Y |\n"; + s << "| Use at your Own Peril |\n"; + s << "+--------------------------------------------------------+"<<"\n"; + s << " Nodes: " << "\n"; + s << "Nodo 1 :"<< externalNodes(0)<< "\n"; + s << "Nodo 2 :"<< externalNodes(1)<< "\n"; + s << " BeamGT Elastic properties: " << "\n"; + s << "Beam Area :"<< A<< "\n"; + s << "Beam I :"<< I<< "\n"; + s << "Beam E :"<< E<< "\n"; + s << "Beam G :"<< G<< "\n"; + s << " BeamGT Materials: " << "\n"; + s << "Material for Flexure 1 :" << *theMaterial[0]<< "\n"; + s << "Material for Flexure 2 :" << *theMaterial[1]<< "\n"; + s << "Material for Shear :" << *theMaterial2<< "\n"; + s << "Material for Axial :" << *theMaterial3<< "\n"; + s << " " << "\n"; +} + +Response* +BeamGT::setResponse(const char **argv, int argc, OPS_Stream &output) +{ + Response *theResponse = 0; +// opserr<<"En setResponse"<<"\n"; + + output.tag("ElementOutput"); + output.attr("eleType","BeamGT"); + output.attr("eleTag",this->getTag()); + output.attr("node1 ",externalNodes[0]); + output.attr("node2 ",externalNodes[1]); + + char outputData[10]; + + if ((strcmp(argv[0],"force") == 0) || (strcmp(argv[0],"forces") == 0) + || (strcmp(argv[0],"globalForces") == 0) || (strcmp(argv[0],"globalforces") == 0)) { + + char outputData[10]; +// int numDOFperNode = numDOF/2; + for (int i=0; i<4; i++) { + sprintf(outputData,"P1_%d", i+1); + output.tag("ResponseType", outputData); + } + for (int j=0; j<4; j++) { + sprintf(outputData,"P2_%d", j+1); + output.tag("ResponseType", outputData); + } + theResponse = new ElementResponse(this, 1, Vector(3)); + + + + } else if ((strcmp(argv[0],"basicForce") == 0 || strcmp(argv[0],"basicForces") == 0) || + (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)) { + + for (int i=0; i<4; i++) { + sprintf(outputData,"P%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 2, Vector(4)); + + + } else if (strcmp(argv[0],"defo") == 0 || strcmp(argv[0],"deformations") == 0 || + strcmp(argv[0],"deformation") == 0 || strcmp(argv[0],"basicDeformation") == 0) { + + for (int i=0; i<6; i++) { + sprintf(outputData,"e%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 3, Vector(4)); + + + + + } else if (strcmp(argv[0],"basicStiffness") == 0) { + + for (int i=0; i<6; i++) { + sprintf(outputData,"e%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 13, Matrix(6,6)); + + } else if ((strcmp(argv[0],"defoANDforce") == 0) || + (strcmp(argv[0],"deformationANDforces") == 0) || + (strcmp(argv[0],"deformationsANDforces") == 0)) { + + int i; + for (i=0; i<4; i++) { + sprintf(outputData,"e%d",i+1); + output.tag("ResponseType",outputData); + } + for (i=0; i<4; i++) { + sprintf(outputData,"P%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 4, Vector(2*4)); + + // a material quantity + } else if (strcmp(argv[0],"material") == 0) { + if (argc > 2) { + int matNum = atoi(argv[1]); + if (matNum >= 1 && matNum <= 2) + theResponse = theMaterial[matNum-1]->setResponse(&argv[2], argc-2, output); + } + theResponse = theMaterial2->setResponse(&argv[2], argc-2, output); + } + + + output.endTag(); + + return theResponse; +} + +int +BeamGT::getResponse(int responseID, Information &eleInformation) +{ + const Vector& disp1 = theNodes[0]->getTrialDisp(); + const Vector& disp2 = theNodes[1]->getTrialDisp(); + + const Vector diff = disp2-disp1; +// opserr<<"En getResponse"<<"\n"; + switch (responseID) { + case -1: + return -1; + + case 1: + return eleInformation.setVector(this->getResistingForce()); + + case 2: + if (eleInformation.theVector != 0) { + for (int i = 0; i < 2; i++) + (*(eleInformation.theVector))(i) = theMaterial[i]->getStress(); + (*(eleInformation.theVector))(2) = theMaterial2->getStress(); + (*(eleInformation.theVector))(3) = theMaterial3->getStress(); + } + return 0; + + case 3: + if (eleInformation.theVector != 0) { + for (int i = 0; i < 2; i++) + (*(eleInformation.theVector))(i) = theMaterial[i]->getStrain(); + (*(eleInformation.theVector))(2) = theMaterial2->getStrain(); + (*(eleInformation.theVector))(3) = theMaterial3->getStrain(); + } + return 0; + + case 13: + if (eleInformation.theMatrix != 0) { + for (int i = 0; i < 2; i++){ + (*(eleInformation.theMatrix))(i,i) = theMaterial[i]->getTangent(); + } + (*(eleInformation.theMatrix))(2,2) = theMaterial2->getTangent(); + (*(eleInformation.theMatrix))(3,3) = theMaterial3->getTangent(); + } + return 0; + + case 4: + if (eleInformation.theVector != 0) { + for (int i = 0; i < 2; i++) { + (*(eleInformation.theVector))(i) = theMaterial[i]->getStrain(); + (*(eleInformation.theVector))(i+4) = theMaterial[i]->getStress(); + } + (*(eleInformation.theVector))(2) = theMaterial2->getStrain(); + (*(eleInformation.theVector))(6) = theMaterial2->getStress(); + + (*(eleInformation.theVector))(3) = theMaterial3->getStrain(); + (*(eleInformation.theVector))(7) = theMaterial3->getStress(); + + } + return 0; + + default: + return -1; + } +} + + +double +BeamGT::computeCurrentStrain(int mat) const +//BeamGT::computeCurrentStrain(void) const +{ + // NOTE this method will never be called with L == 0.0 + double str[6]; + double strain; + // determine the strain + const Vector &disp1 = theNodes[0]->getTrialDisp(); + const Vector &disp2 = theNodes[1]->getTrialDisp(); + + + double L=trans(0,0); + double c1=trans(0,1); + double s1=trans(0,2); + + //deformaciones en locales del elemento. + double dx1=disp1(0); + double dy1=disp1(1); + double dr1=disp1(2); + double dx2=disp2(0); + double dy2=disp2(1); + double dr2=disp2(2); + + double du1=dx1*c1+dy1*s1; + double dv1=-dx1*s1+dy1*c1; + double du2=dx2*c1+dy2*s1; + double dv2=-dx2*s1+dy2*s1; + + double ro1=dr1+(dv2-dv1)/L; + double ro2=dr2+(dv2-dv1)/L; + double dg=(dv2-dv1)/L; + + str[0]=du1; + str[1]=dv1; + str[2]=dr1; + str[3]=du2; + str[4]=dv2; + str[5]=dr2; + strain=str[mat]; + return strain; +} + +int +BeamGT::displaySelf(Renderer &theViewer, int displayMode, float fact, const char **modes, int numMode) +//BeamGT::displaySelf(Renderer &theViewer, int displayMode, float fact) +{ + int code=0; + // first determine the two end points of the CorotTruss2 based on + // the display factor (a measure of the distorted image) + // store this information in 2 3d vectors v1 and v2 + const Vector &end1Crd = theNodes[0]->getCrds(); + const Vector &end2Crd = theNodes[1]->getCrds(); + +// + const Vector &end1Disp = theNodes[0]->getDisp(); + const Vector &end2Disp = theNodes[1]->getDisp(); + + static Vector v1(3); + static Vector v2(3); + static Vector rgb(3); + static Vector v3(3); + static Vector v4(3); + + + theNodes[0]->getDisplayCrds(v3, fact, displayMode); + theNodes[1]->getDisplayCrds(v4, fact, displayMode); + + for (int i = 0; i < 2; i++) { + v1(i) = end1Crd(i)+end1Disp(i)*fact; + v2(i) = end2Crd(i)+end2Disp(i)*fact; + } + + // compute the strain and axial force in the member + double strain[6], force[6]; + + double L=trans(0,0); + double c1=trans(0,1); + double s1=trans(0,2); + + //deformaciones en locales del elemento. + + for (int i = 0; i < 1; i++) { + + strain[i] = this->computeCurrentStrain(i); + } + double ro1=strain[2]+(strain[4]-strain[1])/L; + double ro2=strain[5]+(strain[4]-strain[1])/L; + double dg=(strain[4]-strain[1])/L; + + // theMaterial[0]->setTrialStrain(ro1); + // theMaterial[1]->setTrialStrain(ro2); + // theMaterial2->setTrialStrain(dg); + force[0]=E*A/L*(strain[3]-strain[0]); + force[1]=theMaterial2->getStress(); + force[2]=theMaterial[0]->getStress(); + force[3]=force[0]; + force[4]=force[1]; + force[5]=theMaterial[1]->getStress(); + + // + if (displayMode == 2) // use the strain as the drawing measure + { + code=0; + //code +=theViewer.drawLine(v1,v2,(float)strain[2],(float)strain[5],0,0,2,1); + code += theViewer.drawLine(v1, v2, (float)strain[2], (float)strain[5]); + return code; +} + else if(displayMode < 0) + { + code = 0; + code += theViewer.drawLine(v3, v4, 1.0, 1.0, this->getTag(), 0); + return code; + } + + + else { // otherwise use the axial force as measure + code=0; + //code +=theViewer.drawLine(v1,v2,(float)force[2],(float)force[5],0,0,2,1); + code += theViewer.drawLine(v1, v2, (float)force[2], (float)force[5]); + + return code; + } + + + + return 0; +} + + diff --git a/SRC/element/masonry/BeamGT.h b/SRC/element/masonry/BeamGT.h new file mode 100644 index 000000000..f2a0b0380 --- /dev/null +++ b/SRC/element/masonry/BeamGT.h @@ -0,0 +1,137 @@ +/* ****************************************************************** ** +** 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: 2008/12/10 00:05:21 $ +// $Source: /usr/local/cvs/OpenSees/PACKAGES/NewElement/cpp/Truss2D.h,v $ + +// Written by: Gonzalo Torrisi, Universidad Nacional de Cuyo + +#ifndef BeamGT_h +#define BeamGT_h + +#include +#include +#include + +class UniaxialMaterial; + +class BeamGT : public Element +{ + public: + // constructors + BeamGT(int tag, + int Nd1, int Nd2, + UniaxialMaterial &theMaterial, UniaxialMaterial &theMaterial2, UniaxialMaterial &theMaterial3, + double E, double G, double A, double I, double LP1, double LP2, double LR, double FC); + + + + BeamGT(); + + // destructor + ~BeamGT(); + + + // public methods to obtain inforrmation about dof & connectivity + 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 + const Matrix &getTangentStiff(void); + const Matrix &getInitialStiff(void); + + // public method to obtain resisting force + const Vector &getResistingForce(void); + + // public methods for 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 **modes, int numMode); + //int displaySelf(Renderer &theViewer, int displayMode, float fact); + void Print(OPS_Stream &s, int flag =0); + + Response *setResponse(const char **argv, int argc, OPS_Stream &s); + int getResponse(int responseID, Information &eleInformation); + + protected: + + private: + // private member functions - only available to objects of the class + double computeCurrentStrain(int mat) const; + + // private attributes - a copy for each object of the class + UniaxialMaterial **theMaterial; // pointer to a material + UniaxialMaterial *theMaterial2; + UniaxialMaterial *theMaterial3; + ID externalNodes; // contains the id's of end nodes + Matrix trans; // hold the transformation matrix + Matrix Tm; + Matrix TTm; + Vector Cdefor; + Vector Tdefor; + Vector Cdespla; + Vector Tdespla; + Vector Cesf; + Vector Tesf; + Matrix Stifloc; + Matrix Stif0; + Vector RR; + double E; + double A; + double G; + double I; + double LP1; + double LP2; + double LR; + double FC; + double L; + double Cdeltares; + double Tdeltares; + double seno; + double coseno; + double Mom1C; + double Mom2C; + double V1C; + double r1c; + double r2c; + double dcur1c; + double dcur2c; + double dgamc; + double daxc; + + + Node *theNodes[2]; // node pointers + + // static data - single copy for all objects of the class + static Matrix BeamK; // class wide matrix for returning stiffness + static Vector BeamR; // class wide vector for returning residual +}; +#endif + diff --git a/SRC/element/masonry/Makefile b/SRC/element/masonry/Makefile new file mode 100644 index 000000000..c3119fac9 --- /dev/null +++ b/SRC/element/masonry/Makefile @@ -0,0 +1,20 @@ +include ../../../Makefile.def + +OBJS = MasonPan12.o \ + MasonPan3D.o \ + BeamGT.o + +all: $(OBJS) + +# Miscellaneous +tidy: + @$(RM) $(RMFLAGS) Makefile.bak *~ #*# core + +clean: tidy + @$(RM) $(RMFLAGS) $(OBJS) *.o + +spotless: clean + +wipe: spotless + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/SRC/element/masonry/MasonPan12.cpp b/SRC/element/masonry/MasonPan12.cpp new file mode 100644 index 000000000..62b267cd0 --- /dev/null +++ b/SRC/element/masonry/MasonPan12.cpp @@ -0,0 +1,1564 @@ +/* ****************************************************************** ** +** 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 by: Gonzalo Torrisi, Universidad Nacional de Cuyo + +// we specify what header files we need +#include "MasonPan12.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// initialise the class wide variables +Matrix MasonPan12::PanelK(36,36); +Vector MasonPan12::PanelR(36); + +void* OPS_MasonPan12() + +//#define OPS_Export + +//OPS_Export void * +//OPS_MasonPan12element() +{ + // print out a message about who wrote this element & any copyright info wanted + //if (numMyPanel == 0) { + // opserr << " \n"; + // opserr << " REFINED MASONRY PANEL\n"; + // opserr << " Written by Gonzalo Torrisi UNCuyo Copyright 2015\n"; + // opserr << " Model with 6 compression struts-36 dof\n"; + // opserr << " Only in plane X-Y \n"; + // opserr << " Use at your Own Peril\n"; + +// numMyPanel++; +// } + + Element *thePanel = 0; + + int numRemainingArgs = OPS_GetNumRemainingInputArgs(); + if (numRemainingArgs == 0) { // parallel processing + thePanel = new MasonPan12(); + return thePanel; + } + + if (numRemainingArgs != 18) { + opserr << "ERROR - Masonry Panel not enough args provided, want: element MasonryPanel tag? Node1? Node2? Node3? Node4? Node5? Node6? Node7? Node8? Node9? Node10? Node11? Node12? matTag? matTag2? thick? wfactor? w1?\n"; +// numMyPanel++; + } + + // get the id and end nodes + int iData[15]; + double dData[3]; + int numData; + + numData = 13; + if (OPS_GetIntInput(&numData, iData) != 0) { + opserr << "WARNING invalid element data\n"; + return 0; + } + int eleTag = iData[0]; + + numData =1; + if (OPS_GetIntInput(&numData, &iData[13]) != 0) { + opserr << "WARNING error reading element material 1 tag for element " << eleTag << endln; + return 0; + } + numData =1; + if (OPS_GetIntInput(&numData, &iData[14]) != 0) { + opserr << "WARNING error reading element material 2 tag for element " << eleTag << endln; + return 0; + } + + int matID = iData[13]; + int matID2 = iData[14]; + + numData =3 ; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING error reading element areas, thickness and properties for element" << eleTag << endln; + return 0; + } + + UniaxialMaterial *theMaterial = OPS_GetUniaxialMaterial(matID); + UniaxialMaterial *theMaterial2 =OPS_GetUniaxialMaterial(matID2); + + if (theMaterial == 0) { + opserr << "WARNING material with tag " << matID << "not found for element " << eleTag << endln; + return 0; + } + + // now create the truss and add it to the Domain + + thePanel= new MasonPan12(eleTag, iData[1], iData[2], iData[3], iData[4], iData[5], iData[6], iData[7], iData[8], iData[9], iData[10], iData[11], iData[12], *theMaterial, *theMaterial2, dData[0], dData[1], dData[2]); + + if (thePanel == 0) { + opserr << "WARNING ran out of memory creating element with tag " << eleTag << endln; + delete theMaterial; + delete theMaterial2; + return 0; + } + + return thePanel; +} + + +// typical constructor +MasonPan12::MasonPan12(int tag, + int Nd1, int Nd2, int Nd3, int Nd4, int Nd5, int Nd6, + int Nd7, int Nd8, int Nd9, int Nd10, int Nd11, int Nd12, + UniaxialMaterial &theMat, UniaxialMaterial &theMat2, + double thick, double wr,double w1) +:Element(tag, ELE_TAG_MasonPan12), + externalNodes(12), + trans(8,4),rig1(6),rig2(6),rig3(6), TH(thick), W1(w1), WR(wr), theMaterial(0),theMaterial2(0) + //L1(0.0),L2(0.0),L3(0.0),L4(0.0),L5(0.0),L6(0.0) +{ + // get a copy of the material object for our own use + // theMaterial = theMat.getCopy(); + //if (theMaterial == 0) { + // opserr << "FATAL MassonPan::MasonPan12() - out of memory, could not get a copy of the Material\n"; + // exit(-1); + // } + + // allocate memory for numMaterials1d uniaxial material models + theMaterial = new UniaxialMaterial *[6]; + theMaterial2= 0; + + + if ( theMaterial == 0 ) { + opserr << "FATAL MasonPan12::MasonPan12 - failed to create a 1d material or direction array\n"; + exit(-1); + } + + // get a copy of the material and check we obtained a valid copy + //for (int i=0; i<6; i++) { + + theMaterial[0] = theMat.getCopy(); + theMaterial[3] = theMat.getCopy(); + + if (theMaterial[0] == 0) { + opserr << "FATAL MasonPan12::MasonPan12 - failed to get a copy of material\n" ; + exit(-1); + } + if (theMaterial[3] == 0) { + opserr << "FATAL MasonPan12::MasonPan12 - failed to get a copy of material\n" ; + exit(-1); + } + + theMaterial[1] = theMat2.getCopy(); + theMaterial[2] = theMat2.getCopy(); + theMaterial[4] = theMat2.getCopy(); + theMaterial[5] = theMat2.getCopy(); + + // if (theMaterial2== 0){ +// opserr << "FATAL MasonPan12::MasonPan12 - failed to get a copy of material2\n"; +// } + + // fill in the ID containing external node info with node id's + if (externalNodes.Size() != 12) { + opserr << "FATAL MassonPan::MasonPan12() - out of memory, could not create an ID of size 12\n"; + exit(-1); + } + + externalNodes(0) = Nd1; + externalNodes(1) = Nd2; + externalNodes(2) = Nd3; + externalNodes(3) = Nd4; + externalNodes(4) = Nd5; + externalNodes(5) = Nd6; + externalNodes(6) = Nd7; + externalNodes(7) = Nd8; + externalNodes(8) = Nd9; + externalNodes(9) = Nd10; + externalNodes(10) = Nd11; + externalNodes(11) = Nd12; + + + 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; + theNodes[9] = 0; + theNodes[10] = 0; + theNodes[11] = 0; +} + +// constructor which should be invoked by an FE_ObjectBroker only +MasonPan12::MasonPan12() +:Element(0, ELE_TAG_MasonPan12), + theMaterial(0), theMaterial2(0), + externalNodes(12), + trans(8,4),rig1(6),rig2(6),rig3(6), TH(0.0),W1(0.0),WR(0.0) +{ + 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; + theNodes[9] = 0; + theNodes[10] = 0; + theNodes[11] = 0; +} + +// destructor - provided to clean up any memory +MasonPan12::~MasonPan12() +{ + // clean up the memory associated with the element, this is + // memory the Truss2D objects allocates and memory allocated + // by other objects that the Truss2D object is responsible for + // cleaning up, i.e. the MaterialObject. + for (int i=0; i<6; i++) { + if (theMaterial[i] != 0) + delete theMaterial[i]; +} + delete [] theMaterial; + delete theMaterial2; +} + +int +MasonPan12::getNumExternalNodes(void) const +{ + return 12; +} + +const ID & +MasonPan12::getExternalNodes(void) +{ + return externalNodes; +} + +Node ** +MasonPan12::getNodePtrs(void) +{ + return theNodes; +} + +int +MasonPan12::getNumDOF(void) { + return 36; +} + +// method: setDomain() +// to set a link to the enclosing Domain, ensure nodes exist in Domain +// and set pointers to these nodes, also determines the length and +// transformation Matrix. + +void +MasonPan12::setDomain(Domain *theDomain) +{ + // check Domain is not null - invoked when object removed from a domain + if (theDomain == 0) { + return; + } + + // first ensure nodes exist in Domain and set the node pointers + Node *end1Ptr, *end2Ptr, *end3Ptr, *end4Ptr, *end5Ptr, *end6Ptr, *end7Ptr, *end8Ptr, *end9Ptr, *end10Ptr, *end11Ptr, *end12Ptr; + int Nd1 = externalNodes(0); + int Nd2 = externalNodes(1); + int Nd3 = externalNodes(2); + int Nd4 = externalNodes(3); + int Nd5 = externalNodes(4); + int Nd6 = externalNodes(5); + int Nd7 = externalNodes(6); + int Nd8 = externalNodes(7); + int Nd9 = externalNodes(8); + int Nd10= externalNodes(9); + int Nd11=externalNodes(10); + int Nd12= externalNodes(11); + + end1Ptr = theDomain->getNode(Nd1); + end2Ptr = theDomain->getNode(Nd2); + end3Ptr = theDomain->getNode(Nd3); + end4Ptr = theDomain->getNode(Nd4); + end5Ptr = theDomain->getNode(Nd5); + end6Ptr = theDomain->getNode(Nd6); + end7Ptr = theDomain->getNode(Nd7); + end8Ptr = theDomain->getNode(Nd8); + end9Ptr = theDomain->getNode(Nd9); + end10Ptr = theDomain->getNode(Nd10); + end11Ptr = theDomain->getNode(Nd11); + end12Ptr = theDomain->getNode(Nd12); + + if (end1Ptr == 0) { + opserr << "WARNING MasonPan12::setDomain() - at truss " << this->getTag() << " node " << + Nd1 << " does not exist in domain\n"; + + return; // don't go any further - otherwise segemntation fault + } + if (end12Ptr == 0) { + opserr << "WARNING MasonPan12::setDomain() - at truss " << this->getTag() << " node " << + Nd2 << " does not exist in domain\n"; + + return; // don't go any further - otherwise segemntation fault + } + + theNodes[0] = end1Ptr; + theNodes[1] = end2Ptr; + theNodes[2] = end3Ptr; + theNodes[3] = end4Ptr; + theNodes[4] = end5Ptr; + theNodes[5] = end6Ptr; + theNodes[6] = end7Ptr; + theNodes[7] = end8Ptr; + theNodes[8] = end9Ptr; + theNodes[9] = end10Ptr; + theNodes[10] = end11Ptr; + theNodes[11] = end12Ptr; + + + // call the DomainComponent class method THIS IS VERY IMPORTANT + this->DomainComponent::setDomain(theDomain); + + // ensure connected nodes have correct number of dof's + int dofNd1 = end1Ptr->getNumberDOF(); + int dofNd2 = end2Ptr->getNumberDOF(); + int dofNd3 = end3Ptr->getNumberDOF(); + int dofNd4 = end4Ptr->getNumberDOF(); + int dofNd5 = end5Ptr->getNumberDOF(); + int dofNd6 = end6Ptr->getNumberDOF(); + int dofNd7 = end7Ptr->getNumberDOF(); + int dofNd8 = end8Ptr->getNumberDOF(); + int dofNd9 = end9Ptr->getNumberDOF(); + int dofNd10 = end10Ptr->getNumberDOF(); + int dofNd11 = end11Ptr->getNumberDOF(); + int dofNd12 = end12Ptr->getNumberDOF(); + + if ((dofNd1 != 3 || dofNd2 != 3)) { + opserr << "MasonPan12::setDomain(): 2 dof required at nodes\n"; + return; + } + + // now determine the length & transformation matrix + const Vector &end1Crd = end1Ptr->getCrds(); + const Vector &end2Crd = end2Ptr->getCrds(); + const Vector &end3Crd = end3Ptr->getCrds(); + const Vector &end4Crd = end4Ptr->getCrds(); + const Vector &end5Crd = end5Ptr->getCrds(); + const Vector &end6Crd = end6Ptr->getCrds(); + const Vector &end7Crd = end7Ptr->getCrds(); + const Vector &end8Crd = end8Ptr->getCrds(); + const Vector &end9Crd = end9Ptr->getCrds(); + const Vector &end10Crd = end10Ptr->getCrds(); + const Vector &end11Crd = end11Ptr->getCrds(); + const Vector &end12Crd = end12Ptr->getCrds(); + + double dx = end4Crd(0)-end1Crd(0); + double dy = end10Crd(1)-end1Crd(1); + + if (dx == 0.0) { + opserr << "WARNING MasonPan12::setDomain() - MasonPan12 " << this->getTag() << + " has zero length\n"; + return; // don't go any further - otherwise divide by 0 error + } + if (dy == 0.0) { + opserr << "WARNING MasonPan12::setDomain() - MasonPan12 " << this->getTag() << + " has zero height\n"; + return; // don't go any further - otherwise divide by 0 error + } + + // cosenos de las diagonales + double dx1 =end4Crd(0)-end10Crd(0); + double dy1= end4Crd(1)-end10Crd(1); + double L1=sqrt(dx1*dx1+dy1*dy1); + double dx2 =end3Crd(0)-end11Crd(0); + double dy2= end3Crd(1)-end11Crd(1); + double L2=sqrt(dx2*dx2+dy2*dy2); + double dx3 =end5Crd(0)-end9Crd(0); + double dy3= end5Crd(1)-end9Crd(1); + double L3=sqrt(dx3*dx3+dy3*dy3); + + double dx4 =end7Crd(0)-end1Crd(0); + double dy4= end7Crd(1)-end1Crd(1); + double L4=sqrt(dx4*dx4+dy4*dy4); + double dx5 =end6Crd(0)-end2Crd(0); + double dy5= end6Crd(1)-end2Crd(1); + double L5=sqrt(dx5*dx5+dy5*dy5); + double dx6 =end8Crd(0)-end12Crd(0); + double dy6= end8Crd(1)-end12Crd(1); + double L6=sqrt(dx6*dx6+dy6*dy6); + double Area1=L1*WR*TH*W1; + double Area2=L1*WR*TH*(1-W1)/2; + double Area3=L1*WR*TH*(1-W1)/2; + double Area4=L1*WR*TH*W1; + double Area5=L1*WR*TH*(1-W1)/2; + double Area6=L1*WR*TH*(1-W1)/2; + double Lpan=end4Crd(0)-end1Crd(0); + double Apan=Lpan*TH; + + //rigidez del resorte + //suma de cosenos l cuadrado + // double coef=(dx1/L1*dx1/L1)/(L1)+(dx2/L2*dx2/L2)/(L2)+(dx3/L3*dx3/L3)/(L3)+(dx4/L4*dx4/L4)/(L4)+(dx5/L5*dx5/L5)/(L5)+(dx6/L6*dx6/L6)/(L6); + // rigidez de las bielas + double Emam=0.0; + Emam= theMaterial[0]->getInitialTangent(); + //double Gcor=theMaterial2->getInitialTangent(); + + //double coef2=Emam*(Area1+Area2+Area3)*coef; + //rigidez del resorte + // double Rigspring0=WS*coef2; + //modulo de corte equivalente + // double Gspr=Rigspring0*fabs(dy1)/Apan; + //rigidez relativa + //double Rigspring=fabs(dy1)/Apan; + // double Rigspring=Rigspring0/Emam; + + // double coef3=1.0-WS; + trans(0,0)=L1; + trans(0,1)=dx1/L1; + trans(0,2)=dy1/L1; + trans(0,3)=Area1; + trans(1,0)=L2; + trans(1,1)=dx2/L2; + trans(1,2)=dy2/L2; + trans(1,3)=Area2; + trans(2,0)=L3; + trans(2,1)=dx3/L3; + trans(2,2)=dy3/L3; + trans(2,3)=Area3; + trans(3,0)=L4; + trans(3,1)=dx4/L4; + trans(3,2)=dy4/L4; + trans(3,3)=Area4; + trans(4,0)=L5; + trans(4,1)=dx5/L5; + trans(4,2)=dy5/L5; + trans(4,3)=Area5; + trans(5,0)=L6; + trans(5,1)=dx6/L6; + trans(5,2)=dy6/L6; + trans(5,3)=Area6; + trans(6,0)=Apan; + trans(6,1)=0.0; + trans(6,2)=0.0; + trans(6,3)=0.0; + trans(7,0)=dy; + for (int im=0; im<6; im++) { + rig1(im) = trans(im,1)*trans(im,1)*trans(im,3)/trans(im,0); + rig2(im) = trans(im,1)*trans(im,2)*trans(im,3)/trans(im,0); + rig3(im) = trans(im,2)*trans(im,2)*trans(im,3)/trans(im,0); + } + +} + +int +MasonPan12::commitState() +{ + int ecode=0; + //commit material models + for (int i=0; i<6; i++) + ecode += theMaterial[i]->commitState(); + //commit the base class + // ecode += theMaterial2->commitState(); + + ecode += this->Element::commitState(); + Cdeltares=Tdeltares; + + return ecode; +} + +int +MasonPan12::revertToLastCommit() +{ +// return theMaterial->revertToLastCommit(); + int code=0; + + // revert state for 1d materials + for (int i=0; i<6; i++) + code += theMaterial[i]->revertToLastCommit(); + // code += theMaterial2->revertToLastCommit(); + Tdeltares=Cdeltares; + return code; +} + +int +MasonPan12::revertToStart() +{ + // return theMaterial->revertToStart(); + int code=0; + + // revert state for 1d materials + for (int i=0; i<6; i++) + code += theMaterial[i]->revertToStart(); + // code += theMaterial2->revertToStart(); + + return code; +} + +int +MasonPan12::update() +{ + // determine the current strain given trial displacements at nodes + // double strain = this->computeCurrentStrain(); + + // set the strain in the materials + //theMaterial->setTrialStrain(strain); + + // compute strain and rate; set as current trial for material + ////////////////////////////////////// strain = this->computeCurrentStrain(mat ); + // strainRate = this->computeCurrentStrain(); + double str[7]; + + // determine the strain + 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(); + const Vector &disp10 = theNodes[9]->getTrialDisp(); + const Vector &disp11 = theNodes[10]->getTrialDisp(); + const Vector &disp12 = theNodes[11]->getTrialDisp(); + + + double c1=trans(0,1); + double s1=trans(0,2); + double L1=trans(0,0); + double A1=trans(0,3); + double du1=((disp4(0)-disp10(0))*c1+(disp4(1)-disp10(1))*s1)/L1; + c1=trans(1,1); + double s2=trans(1,2); + double L2=trans(1,0); + double A2=trans(1,3); + double du2=((disp3(0)-disp11(0))*c1+(disp3(1)-disp11(1))*s2)/L2; + c1=trans(2,1); + double s3=trans(2,2); + double L3=trans(2,0); + double A3=trans(2,3); + double du3=((disp5(0)-disp9(0))*c1+(disp5(1)-disp9(1))*s3)/L3; + c1=trans(3,1); + double s4=trans(3,2); + double L4=trans(3,0); + double A4=trans(3,3); + double du4=((disp7(0)-disp1(0))*c1+(disp7(1)-disp1(1))*s4)/L4; + c1=trans(4,1); + double s5=trans(4,2); + double L5=trans(4,0); + double A5=trans(4,3); + double du5=((disp6(0)-disp2(0))*c1+(disp6(1)-disp2(1))*s5)/L5; + c1=trans(5,1); + double s6=trans(5,2); + double L6=trans(5,0); + double A6=trans(5,3); + double du6=((disp8(0)-disp12(0))*c1+(disp8(1)-disp12(1))*s6)/L6; + //resorte + + double deltares=((disp7(0)+disp10(0))-(disp1(0)+disp4(0)))/trans(7,0); + + str[0]=du1; + str[1]=du2; + str[2]=du3; + str[3]=du4; + str[4]=du5; + str[5]=du6; + str[6]=deltares; + + int idir; + if (deltares>=0) { + idir=1; + } + else + { + idir=2; + } + Tdeltares=deltares; + + int ret = 0; + for (int mat=0; mat<6; mat++) { + + double strain=0; + strain=str[mat]; + ret+= theMaterial[mat]->setTrialStrain(strain); + } + + //double Axial = 0.0; + //double FAxial = 0.0; + // double force1 = A1*theMaterial[0]->getStress(); + // double force2 = A2*theMaterial[1]->getStress(); + // double force3 = A3*theMaterial[2]->getStress(); + // double force4 = A4*theMaterial[3]->getStress(); + // double force5 = A5*theMaterial[4]->getStress(); + // double force6 = A6*theMaterial[5]->getStress(); + // FAxial=force1*abs(s1)+force2*abs(s2)+force3*abs(s3)+force4*abs(s4)+force5*abs(s5)+force6*abs(s6); + // Axial=FAxial/trans(6,0); + // Axial=FAxial/(TH*WR*L1); + // if (WS == 0.0) + // Axial=0.0; + + // double FFAXIAL=FAxial; + // ret+=theMaterial2->setTrialStrain(deltares,Axial); + + return ret; + + +// return 0; +} + +const Matrix & +MasonPan12::getTangentStiff(void) +{ + + double Et; + +//diagonal 1 + Et=theMaterial[0]->getTangent(); + PanelK(9,9)=rig1(0)*Et; + PanelK(9,10)=rig2(0)*Et; + PanelK(10,9)=rig2(0)*Et; + PanelK(10,10)=rig3(0)*Et; + PanelK(27,27)=rig1(0)*Et; + PanelK(27,28)=rig2(0)*Et; + PanelK(28,27)=rig2(0)*Et; + PanelK(28,28)=rig3(0)*Et; + PanelK(9,27)=-rig1(0)*Et; + PanelK(9,28)=-rig2(0)*Et; + PanelK(10,27)=-rig2(0)*Et; + PanelK(10,28)=-rig3(0)*Et; + PanelK(27,9)=-rig1(0)*Et; + PanelK(27,10)=-rig2(0)*Et; + PanelK(28,9)=-rig2(0)*Et; + PanelK(28,10)=-rig3(0)*Et; + +//diagonal 2 + Et=theMaterial[1]->getTangent(); + PanelK(6,6)=rig1(1)*Et; + PanelK(6,7)=rig2(1)*Et; + PanelK(7,6)=rig2(1)*Et; + PanelK(7,7)=rig3(1)*Et; + PanelK(30,30)=rig1(1)*Et; + PanelK(30,31)=rig2(1)*Et; + PanelK(31,30)=rig2(1)*Et; + PanelK(31,31)=rig3(1)*Et; + PanelK(6,30)=-rig1(1)*Et; + PanelK(6,31)=-rig2(1)*Et; + PanelK(7,30)=-rig2(1)*Et; + PanelK(7,31)=-rig3(1)*Et; + PanelK(30,6)=-rig1(1)*Et; + PanelK(30,7)=-rig2(1)*Et; + PanelK(31,6)=-rig2(1)*Et; + PanelK(31,7)=-rig3(1)*Et; + +//diagonal 3 + Et=theMaterial[2]->getTangent(); + PanelK(12,12)=rig1(2)*Et; + PanelK(12,13)=rig2(2)*Et; + PanelK(13,12)=rig2(2)*Et; + PanelK(13,13)=rig3(2)*Et; + PanelK(24,24)=rig1(2)*Et; + PanelK(24,25)=rig2(2)*Et; + PanelK(25,24)=rig2(2)*Et; + PanelK(25,25)=rig3(2)*Et; + PanelK(12,24)=-rig1(2)*Et; + PanelK(12,25)=-rig2(2)*Et; + PanelK(13,24)=-rig2(2)*Et; + PanelK(13,25)=-rig3(2)*Et; + PanelK(24,12)=-rig1(2)*Et; + PanelK(24,13)=-rig2(2)*Et; + PanelK(25,12)=-rig2(2)*Et; + PanelK(25,13)=-rig3(2)*Et; + +//diagonal 4 + Et=theMaterial[3]->getTangent(); + PanelK(0,0)=rig1(3)*Et; + PanelK(0,1)=rig2(3)*Et; + PanelK(1,0)=rig2(3)*Et; + PanelK(1,1)=rig3(3)*Et; + PanelK(18,18)=rig1(3)*Et; + PanelK(18,19)=rig2(3)*Et; + PanelK(19,18)=rig2(3)*Et; + PanelK(19,19)=rig3(3)*Et; + PanelK(0,18)=-rig1(3)*Et; + PanelK(0,19)=-rig2(3)*Et; + PanelK(1,18)=-rig2(3)*Et; + PanelK(1,19)=-rig3(3)*Et; + PanelK(18,0)=-rig1(3)*Et; + PanelK(18,1)=-rig2(3)*Et; + PanelK(19,0)=-rig2(3)*Et; + PanelK(19,1)=-rig3(3)*Et; + +//diagonal 5 + Et=theMaterial[4]->getTangent(); + PanelK(3,3)=rig1(4)*Et; + PanelK(3,4)=rig2(4)*Et; + PanelK(4,3)=rig2(4)*Et; + PanelK(4,4)=rig3(4)*Et; + PanelK(15,15)=rig1(4)*Et; + PanelK(15,16)=rig2(4)*Et; + PanelK(16,15)=rig2(4)*Et; + PanelK(16,16)=rig3(4)*Et; + PanelK(3,15)=-rig1(4)*Et; + PanelK(3,16)=-rig2(4)*Et; + PanelK(4,15)=-rig2(4)*Et; + PanelK(4,16)=-rig3(4)*Et; + PanelK(15,3)=-rig1(4)*Et; + PanelK(15,4)=-rig2(4)*Et; + PanelK(16,3)=-rig2(4)*Et; + PanelK(16,4)=-rig3(4)*Et; + +//diagonal 6 + Et=theMaterial[5]->getTangent(); + PanelK(21,21)=rig1(5)*Et; + PanelK(21,22)=rig2(5)*Et; + PanelK(22,21)=rig2(5)*Et; + PanelK(22,22)=rig3(5)*Et; + PanelK(33,33)=rig1(5)*Et; + PanelK(33,34)=rig2(5)*Et; + PanelK(34,33)=rig2(5)*Et; + PanelK(34,34)=rig3(5)*Et; + PanelK(21,33)=-rig1(5)*Et; + PanelK(21,34)=-rig2(5)*Et; + PanelK(22,33)=-rig2(5)*Et; + PanelK(22,34)=-rig3(5)*Et; + PanelK(33,21)=-rig1(5)*Et; + PanelK(33,22)=-rig2(5)*Et; + PanelK(34,21)=-rig2(5)*Et; + PanelK(34,22)=-rig3(5)*Et; + + + // double Et2= theMaterial2->getInitialTangent(); + // Et= theMaterial2->getTangent(); +// double Rigsp=trans(6,3)*Et; +// if (WS==0) +// Rigsp=0; + +// const Vector &disp1 = theNodes[0]->getTrialDisp(); +// const Vector &disp4 = theNodes[3]->getTrialDisp(); +// const Vector &disp7 = theNodes[6]->getTrialDisp(); +// const Vector &disp10 = theNodes[9]->getTrialDisp(); + +// double deltares=((disp7(0)+disp10(0))-(disp1(0)+disp4(0)))/trans(7,0); + +// int idir; +// if (deltares-Cdeltares>=0) { +// idir=1; +// } +// else +// { +// idir=2; +// } +// +// if (idir==1) +// { +// +// PanelK(27,27)+=Rigsp; +// PanelK(9,9)+=Rigsp; +// PanelK(27,9)-=Rigsp; +// PanelK(9,27)-=Rigsp; +// } +// else +// { +// PanelK(0,0)+=Rigsp; +// PanelK(18,18)+=Rigsp; +// PanelK(0,18)-=Rigsp; +// PanelK(18,0)-=Rigsp; + // } + // return the matrix + return PanelK; +} + +const Matrix & +MasonPan12::getInitialStiff(void) +{ + double E; + E = theMaterial[0]->getInitialTangent(); +//diagonal 1 + PanelK(9,9)=rig1(0)*E; + PanelK(9,10)=rig2(0)*E; + PanelK(10,9)=rig2(0)*E; + PanelK(10,10)=rig3(0)*E; + PanelK(27,27)=rig1(0)*E; + PanelK(27,28)=rig2(0)*E; + PanelK(28,27)=rig2(0)*E; + PanelK(28,28)=rig3(0)*E; + PanelK(9,27)=-rig1(0)*E; + PanelK(9,28)=-rig2(0)*E; + PanelK(10,27)=-rig2(0)*E; + PanelK(10,28)=-rig3(0)*E; + PanelK(27,9)=-rig1(0)*E; + PanelK(27,10)=-rig2(0)*E; + PanelK(28,9)=-rig2(0)*E; + PanelK(28,10)=-rig3(0)*E; + E = theMaterial[1]->getInitialTangent(); +//diagonal 2 + PanelK(6,6)=rig1(1)*E; + PanelK(6,7)=rig2(1)*E; + PanelK(7,6)=rig2(1)*E; + PanelK(7,7)=rig3(1)*E; + PanelK(30,30)=rig1(1)*E; + PanelK(30,31)=rig2(1)*E; + PanelK(31,30)=rig2(1)*E; + PanelK(31,31)=rig3(1)*E; + PanelK(6,30)=-rig1(1)*E; + PanelK(6,31)=-rig2(1)*E; + PanelK(7,30)=-rig2(1)*E; + PanelK(7,31)=-rig3(1)*E; + PanelK(30,6)=-rig1(1)*E; + PanelK(30,7)=-rig2(1)*E; + PanelK(31,6)=-rig2(1)*E; + PanelK(31,7)=-rig3(1)*E; + E = theMaterial[2]->getInitialTangent(); +//diagonal 3 + PanelK(12,12)=rig1(2)*E; + PanelK(12,13)=rig2(2)*E; + PanelK(13,12)=rig2(2)*E; + PanelK(13,13)=rig3(2)*E; + PanelK(24,24)=rig1(2)*E; + PanelK(24,25)=rig2(2)*E; + PanelK(25,24)=rig2(2)*E; + PanelK(25,25)=rig3(2)*E; + PanelK(12,24)=-rig1(2)*E; + PanelK(12,25)=-rig2(2)*E; + PanelK(13,24)=-rig2(2)*E; + PanelK(13,25)=-rig3(2)*E; + PanelK(24,12)=-rig1(2)*E; + PanelK(24,13)=-rig2(2)*E; + PanelK(25,12)=-rig2(2)*E; + PanelK(25,13)=-rig3(2)*E; + E = theMaterial[3]->getInitialTangent(); +//diagonal 4 + PanelK(0,0)=rig1(3)*E; + PanelK(0,1)=rig2(3)*E; + PanelK(1,0)=rig2(3)*E; + PanelK(1,1)=rig3(3)*E; + PanelK(18,18)=rig1(3)*E; + PanelK(18,19)=rig2(3)*E; + PanelK(19,18)=rig2(3)*E; + PanelK(19,19)=rig3(3)*E; + PanelK(0,18)=-rig1(3)*E; + PanelK(0,19)=-rig2(3)*E; + PanelK(1,18)=-rig2(3)*E; + PanelK(1,19)=-rig3(3)*E; + PanelK(18,0)=-rig1(3)*E; + PanelK(18,1)=-rig2(3)*E; + PanelK(19,0)=-rig2(3)*E; + PanelK(19,1)=-rig3(3)*E; + E = theMaterial[4]->getInitialTangent(); +//diagonal 5 + PanelK(3,3)=rig1(4)*E; + PanelK(3,4)=rig2(4)*E; + PanelK(4,3)=rig2(4)*E; + PanelK(4,4)=rig3(4)*E; + PanelK(15,15)=rig1(4)*E; + PanelK(15,16)=rig2(4)*E; + PanelK(16,15)=rig2(4)*E; + PanelK(16,16)=rig3(4)*E; + PanelK(3,15)=-rig1(4)*E; + PanelK(3,16)=-rig2(4)*E; + PanelK(4,15)=-rig2(4)*E; + PanelK(4,16)=-rig3(4)*E; + PanelK(15,3)=-rig1(4)*E; + PanelK(15,4)=-rig2(4)*E; + PanelK(16,3)=-rig2(4)*E; + PanelK(16,4)=-rig3(4)*E; + E = theMaterial[5]->getInitialTangent(); +//diagonal 6 + PanelK(21,21)=rig1(5)*E; + PanelK(21,22)=rig2(5)*E; + PanelK(22,21)=rig2(5)*E; + PanelK(22,22)=rig3(5)*E; + PanelK(33,33)=rig1(5)*E; + PanelK(33,34)=rig2(5)*E; + PanelK(34,33)=rig2(5)*E; + PanelK(34,34)=rig3(5)*E; + PanelK(21,33)=-rig1(5)*E; + PanelK(21,34)=-rig2(5)*E; + PanelK(22,33)=-rig2(5)*E; + PanelK(22,34)=-rig3(5)*E; + PanelK(33,21)=-rig1(5)*E; + PanelK(33,22)=-rig2(5)*E; + PanelK(34,21)=-rig2(5)*E; + PanelK(34,22)=-rig3(5)*E; + +// double Et2= theMaterial2->getInitialTangent(); +// double Rigsp=trans(6,3)*Et2; +// if (WS==0) +// Rigsp=0; +// +// PanelK(0,0)+=Rigsp/2; +// PanelK(18,18)+=Rigsp/2; +// PanelK(9,9)+=Rigsp/2; +// PanelK(27,27)+=Rigsp/2; +// PanelK(0,18)-=Rigsp/2; +// PanelK(18,0)-=Rigsp/2; +// PanelK(9,27)-=Rigsp/2; +// PanelK(27,9)-=Rigsp/2; + // return the matrix + return PanelK; +} + +const Vector & +MasonPan12::getResistingForce() +{ + + double Area1=trans(0,3); + double c1=trans(0,1); + double s1=trans(0,2); + double force = Area1*theMaterial[0]->getStress(); + PanelR(9)=force*c1; + PanelR(10)=force*s1; + PanelR(27)=-force*c1; + PanelR(28)=-force*s1; + + double Area2=trans(1,3); + c1=trans(1,1); + s1=trans(1,2); + force = Area2*theMaterial[1]->getStress(); + PanelR(6)=force*c1; + PanelR(7)=force*s1; + PanelR(30)=-force*c1; + PanelR(31)=-force*s1; + double Area3=trans(2,3); + c1=trans(2,1); + s1=trans(2,2); + force = Area3*theMaterial[2]->getStress(); + PanelR(12)=force*c1; + PanelR(13)=force*s1; + PanelR(24)=-force*c1; + PanelR(25)=-force*s1; + double Area4=trans(3,3); + c1=trans(3,1); + s1=trans(3,2); + force = Area4*theMaterial[3]->getStress(); + + PanelR(18)=force*c1; + PanelR(19)=force*s1; + PanelR(0)=-force*c1; + PanelR(1)=-force*s1; + double Area5=trans(4,3); + c1=trans(4,1); + s1=trans(4,2); + force = Area5*theMaterial[4]->getStress(); + PanelR(3)=-force*c1; + PanelR(4)=-force*s1; + PanelR(15)=force*c1; + PanelR(16)=force*s1; + + double Area6=trans(5,3); + c1=trans(5,1); + s1=trans(5,2); + force = Area6*theMaterial[5]->getStress(); + PanelR(21)=force*c1; + PanelR(22)=force*s1; + PanelR(33)=-force*c1; + PanelR(34)=-force*s1; + +// double shear; +// shear=trans(6,0)*theMaterial2->getStress(); +// if (WS==0) +// shear=0; +// +// const Vector &disp1 = theNodes[0]->getTrialDisp(); +// const Vector &disp4 = theNodes[3]->getTrialDisp(); +// const Vector &disp7 = theNodes[6]->getTrialDisp(); + // const Vector &disp10 = theNodes[9]->getTrialDisp(); +// +// double deltares=((disp7(0)+disp10(0))-(disp1(0)+disp4(0)))/trans(7,0); +// +// int idir; +// if ((deltares-Cdeltares)>=0) { +// idir=1; +// } +// else +// { +// idir=2; +// } +// +// if ((deltares-Cdeltares)>=0) { +// PanelR(9) -= shear; +// PanelR(27) += shear; +// } +// else +// { +// PanelR(0) += shear; +// PanelR(18) -= shear; +// } + return PanelR; +} + +int +MasonPan12::sendSelf(int commitTag, Channel &theChannel) +{ + int res; + + + // 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(); + + // Truss2D packs it's data into a Vector and sends this to theChannel + // along with it's dbTag and the commitTag passed in the arguments + + //Vector data(5); + //data(0) = this->getTag(); + //data(1) = A; + //data(2) = theMaterial->getClassTag(); + //int matDbTag = theMaterial->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->setDbTag(matDbTag); + // } + //data(3) = matDbTag; + res=0; + // res = theChannel.sendVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING MasonPan12::sendSelf() - failed to send Vector\n"; + return -1; + } + + // Truss2D then sends the tags of it's two end nodes + // res = theChannel.sendID(dataTag, commitTag, externalNodes); + if (res < 0) { + opserr << "WARNING MasonPan12::sendSelf() - failed to send ID\n"; + return -2; + } + + // finally Truss2D asks it's material object to send itself + //res = theMaterial->sendSelf(commitTag, theChannel); + if (res < 0) { + opserr << "WARNING MasonPan12::sendSelf() - failed to send the Material\n"; + return -3; + } + + return 0; +} + +int +MasonPan12::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +{ + int res; + + + // int dataTag = this->getDbTag(); + + // Truss2D creates a Vector, receives the Vector and then sets the + // internal data with the data in the Vector + + //Vector data(5); + //res = theChannel.recvVector(dataTag, commitTag, data); + res=-1; + if (res < 0) { + opserr << "WARNING MasonPan12::recvSelf() - failed to receive Vector\n"; + return -1; + } + + // this->setTag((int)data(0)); + // A = data(1); + + // Truss2D now receives the tags of it's two external nodes + //res = theChannel.recvID(dataTag, commitTag, externalNodes); + if (res < 0) { + opserr << "WARNING MasonPan12::recvSelf() - failed to receive ID\n"; + return -2; + } + + // we create a material object of the correct type, + // sets its database tag and asks this new object to recveive itself. + //int matClass = data(2); + //int matDb = data(3); + + //theMaterial = theBroker.getNewUniaxialMaterial(matClass); + if (theMaterial == 0) { + opserr << "WARNING MasonPan12::recvSelf() - failed to create a Material\n"; + return -3; + } + + // we set the dbTag before we receive the material - this is important + //theMaterial->setDbTag(matDb); + //res = theMaterial->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "WARNING MasonPan12::recvSelf() - failed to receive the Material\n"; + return -3; + } + + return 0; +} + +void +MasonPan12::Print(OPS_Stream &s, int flag) +{ + + s << " " << "\n"; + s << " " << "\n"; + s << "Element: " << this->getTag(); + s << " type: MasonPan12 " << "\n"; + s << " " << "\n"; + s << "+--------------------------------------------------------+"<< "\n"; + s << "| REFINED MASONRY PANEL |\n"; + s << "| Written by Gonzalo Torrisi UNCuyo Copyright 2015 |\n"; + s << "| Model with 6 compression struts-36 dof |\n"; + s << "| Only in plane X-Y |\n"; + s << "| Use at your Own Peril |\n"; + s << "+--------------------------------------------------------+"<<"\n"; + s << " Nodes: " << "\n"; + s << "Nodo 1 :"<< externalNodes(0)<< "\n"; + s << "Nodo 2 :"<< externalNodes(1)<< "\n"; + s << "Nodo 3 :"<< externalNodes(2)<< "\n"; + s << "Nodo 4 :"<< externalNodes(3)<< "\n"; + s << "Nodo 5 :"<< externalNodes(4)<< "\n"; + s << "Nodo 6 :"<< externalNodes(5)<< "\n"; + s << "Nodo 7 :"<< externalNodes(6)<< "\n"; + s << "Nodo 8 :"<< externalNodes(7)<< "\n"; + s << "Nodo 9 :"<< externalNodes(8)<< "\n"; + s << "Nodo 10 :"<< externalNodes(9)<< "\n"; + s << "Nodo 11 :"<< externalNodes(10)<< "\n"; + s << "Nodo 12 :"<< externalNodes(11)<< "\n"; + s << " MasonPan12 Factors: " << "\n"; + s << "Panel Thickness :"<< TH<< "\n"; + s << "Factor wd (total strut width) :"<< WR<< "\n"; + s << "Factor w1 (percent to strut 1) :"<< W1<< "\n"; +// s << "Factor Gs (percent to shear spring) :"<< WS<< "\n"; + s << " MasonPan12 Areas: " << "\n"; + s << "Area 1-4 :"<< trans(0,3)<< "\n"; + s << "Area 2-5 :"<< trans(1,3)<< "\n"; + s << "Area 3-6 :"<< trans(2,3)<< "\n"; + s << "Area panel :" << trans(6,0)<< "\n"; + s << " MasonPan12 Materials: " << "\n"; + s << "Material for central struts :" << *theMaterial[0]<< "\n"; + s << "Material for lateral struts :" << *theMaterial[1]<< "\n"; +// s << "Material for spring :" << *theMaterial2<< "\n"; + s << " " << "\n"; +} + +Response* +MasonPan12::setResponse(const char **argv, int argc, OPS_Stream &output) +{ + Response *theResponse = 0; + + output.tag("ElementOutput"); + output.attr("eleType","Masonpan"); + output.attr("eleTag",this->getTag()); + output.attr("node1 ",externalNodes[0]); + output.attr("node2 ",externalNodes[1]); + output.attr("node3 ",externalNodes[2]); + output.attr("node4 ",externalNodes[3]); + output.attr("node5 ",externalNodes[4]); + output.attr("node6 ",externalNodes[5]); + output.attr("node7 ",externalNodes[6]); + output.attr("node8 ",externalNodes[7]); + output.attr("node9 ",externalNodes[8]); + output.attr("node10",externalNodes[9]); + output.attr("node11",externalNodes[10]); + output.attr("node12",externalNodes[11]); + char outputData[10]; + + if ((strcmp(argv[0],"force") == 0) || (strcmp(argv[0],"forces") == 0) + || (strcmp(argv[0],"globalForces") == 0) || (strcmp(argv[0],"globalforces") == 0)) { + + char outputData[10]; + // int numDOFperNode = numDOF/2; + for (int i=0; i<3; i++) { + sprintf(outputData,"P1_%d", i+1); + output.tag("ResponseType", outputData); + } + for (int j=0; j<3; j++) { + sprintf(outputData,"P2_%d", j+1); + output.tag("ResponseType", outputData); + } + theResponse = new ElementResponse(this, 1, Vector(36)); + + } else if ((strcmp(argv[0],"basicForce") == 0 || strcmp(argv[0],"basicForces") == 0) || + (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)) { + + for (int i=0; i<6; i++) { + sprintf(outputData,"P%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 2, Vector(6)); + + } else if (strcmp(argv[0],"defo") == 0 || strcmp(argv[0],"deformations") == 0 || + strcmp(argv[0],"deformation") == 0 || strcmp(argv[0],"basicDeformation") == 0) { + + for (int i=0; i<6; i++) { + sprintf(outputData,"e%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 3, Vector(6)); + + } else if (strcmp(argv[0],"basicStiffness") == 0) { + + for (int i=0; i<6; i++) { + sprintf(outputData,"e%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 13, Matrix(6,6)); + + } else if ((strcmp(argv[0],"defoANDforce") == 0) || + (strcmp(argv[0],"deformationANDforces") == 0) || + (strcmp(argv[0],"deformationsANDforces") == 0)) { + + int i; + for (i=0; i<6; i++) { + sprintf(outputData,"e%d",i+1); + output.tag("ResponseType",outputData); + } + for (i=0; i<6; i++) { + sprintf(outputData,"P%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 4, Vector(2*6)); + + // a material quantity + } else if (strcmp(argv[0],"material") == 0) { + if (argc > 2) { + int matNum = atoi(argv[1]); + if (matNum >= 1 && matNum <= 6) + theResponse = theMaterial[matNum-1]->setResponse(&argv[2], argc-2, output); + theResponse = theMaterial2->setResponse(&argv[2], argc-2, output); + } + + } + + + output.endTag(); + + return theResponse; +} + +int +MasonPan12::getResponse(int responseID, Information &eleInformation) +{ + 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(); + const Vector& disp10 = theNodes[9]->getTrialDisp(); + const Vector& disp11 = theNodes[10]->getTrialDisp(); + const Vector& disp12 = theNodes[11]->getTrialDisp(); + + const Vector diff = disp2-disp1; + + switch (responseID) { + case -1: + return -1; + + case 1: + return eleInformation.setVector(this->getResistingForce()); + + case 2: + if (eleInformation.theVector != 0) { + for (int i = 0; i < 6; i++) + (*(eleInformation.theVector))(i) = trans(i,3)*theMaterial[i]->getStress(); + // (*(eleInformation.theVector))(6) = trans(6,0)*theMaterial2->getStress(); + } + return 0; + + case 3: + if (eleInformation.theVector != 0) { + for (int i = 0; i < 6; i++) + (*(eleInformation.theVector))(i) = theMaterial[i]->getStrain(); + // (*(eleInformation.theVector))(6) = theMaterial2->getStrain(); + } + return 0; + + case 13: + if (eleInformation.theMatrix != 0) { + for (int i = 0; i < 6; i++) + (*(eleInformation.theMatrix))(i,i) = theMaterial[i]->getTangent(); + } + return 0; + + case 4: + if (eleInformation.theVector != 0) { + for (int i = 0; i < 6; i++) { + (*(eleInformation.theVector))(i) = theMaterial[i]->getStrain(); + (*(eleInformation.theVector))(i+6) = trans(i,3)*theMaterial[i]->getStress(); + } + // (*(eleInformation.theVector))(6) = theMaterial2->getStrain(); + // (*(eleInformation.theVector))(13) = trans(6,0)*theMaterial2->getStress(); + } + return 0; + + default: + return -1; + } +} + + +double +MasonPan12::computeCurrentStrain(int mat) const +//MasonPan12::computeCurrentStrain(void) const +{ + // NOTE this method will never be called with L == 0.0 + double str[6]; + double strain; + // determine the strain + 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(); + const Vector &disp10 = theNodes[9]->getTrialDisp(); + const Vector &disp11 = theNodes[10]->getTrialDisp(); + const Vector &disp12 = theNodes[11]->getTrialDisp(); + + double c1=trans(0,1); + double s1=trans(0,2); + double L1=trans(0,0); + double du1=((disp4(0)-disp10(0))*c1+(disp4(1)-disp10(1))*s1)/L1; + c1=trans(1,1); + s1=trans(1,2); + double L2=trans(1,0); + double du2=((disp3(0)-disp11(0))*c1+(disp3(1)-disp11(1))*s1)/L2; + c1=trans(2,1); + s1=trans(2,2); + double L3=trans(2,0); + double du3=((disp5(0)-disp9(0))*c1+(disp5(1)-disp9(1))*s1)/L3; + c1=trans(3,1); + s1=trans(3,2); + double L4=trans(3,0); + double du4=((disp7(0)-disp1(0))*c1+(disp7(1)-disp1(1))*s1)/L4; + c1=trans(4,1); + s1=trans(4,2); + double L5=trans(4,0); + double du5=((disp6(0)-disp2(0))*c1+(disp6(1)-disp2(1))*s1)/L5; + c1=trans(5,1); + s1=trans(5,2); + double L6=trans(5,0); + double du6=((disp8(0)-disp12(0))*c1+(disp8(1)-disp12(1))*s1)/L6; + + str[0]=du1; + str[1]=du2; + str[2]=du3; + str[3]=du4; + str[4]=du5; + str[5]=du6; + strain=str[mat]; + return strain; +} + +int +//MasonPan12::displaySelf(Renderer &theViewer, int displayMode, float fact) +MasonPan12::displaySelf(Renderer &theViewer, int displayMode, float fact, const char **modes, int numMode) +{ + + int code=0; + // first determine the two end points of the CorotTruss2 based on + // the display factor (a measure of the distorted image) + // store this information in 2 3d vectors v1 and v2 + 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(); + const Vector &end10Crd = theNodes[9]->getCrds(); + const Vector &end11Crd = theNodes[10]->getCrds(); + const Vector &end12Crd = theNodes[11]->getCrds(); + + + 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(); + const Vector &end10Disp = theNodes[9]->getDisp(); + const Vector &end11Disp = theNodes[10]->getDisp(); + const Vector &end12Disp = theNodes[11]->getDisp(); + + static Vector v1(3); + static Vector v2(3); + static Vector v3(3); + static Vector v4(3); + static Vector v5(3); + static Vector v6(3); + static Vector v7(3); + static Vector v8(3); + static Vector v9(3); + static Vector v10(3); + static Vector v11(3); + static Vector v12(3); + static Vector v13(3); + static Vector v14(3); + + static Vector v1a(3); + static Vector v2a(3); + static Vector v3a(3); + static Vector v4a(3); + static Vector v5a(3); + static Vector v6a(3); + static Vector v7a(3); + static Vector v8a(3); + static Vector v9a(3); + static Vector v10a(3); + static Vector v11a(3); + static Vector v12a(3); + + + + + static Vector rgb(3); + + theNodes[3]->getDisplayCrds(v1a, fact, displayMode); + theNodes[9]->getDisplayCrds(v2a, fact, displayMode); + theNodes[2]->getDisplayCrds(v3a, fact, displayMode); + theNodes[10]->getDisplayCrds(v4a, fact, displayMode); + theNodes[4]->getDisplayCrds(v5a, fact, displayMode); + theNodes[8]->getDisplayCrds(v6a, fact, displayMode); + theNodes[6]->getDisplayCrds(v7a, fact, displayMode); + theNodes[0]->getDisplayCrds(v8a, fact, displayMode); + theNodes[5]->getDisplayCrds(v9a, fact, displayMode); + theNodes[1]->getDisplayCrds(v10a, fact, displayMode); + theNodes[7]->getDisplayCrds(v11a, fact, displayMode); + theNodes[11]->getDisplayCrds(v12a, fact, displayMode); + + + for (int i = 0; i < 2; i++) { + v1(i) = end4Crd(i)+end4Disp(i)*fact; + v2(i) = end10Crd(i)+end10Disp(i)*fact; + v3(i) = end3Crd(i)+end3Disp(i)*fact; + v4(i) = end11Crd(i)+end11Disp(i)*fact; + v5(i) = end5Crd(i)+end5Disp(i)*fact; + v6(i) = end9Crd(i)+end9Disp(i)*fact; + + v7(i) = end7Crd(i)+end7Disp(i)*fact; + v8(i) = end1Crd(i)+end1Disp(i)*fact; + v9(i) = end6Crd(i)+end6Disp(i)*fact; + v10(i) = end2Crd(i)+end2Disp(i)*fact; + v11(i) = end8Crd(i)+end8Disp(i)*fact; + v12(i) = end12Crd(i)+end12Disp(i)*fact; + +// v13(0)=(v10(0)+v6(0))/2; +// v14(0)=(v3(0)+v11(0))/2; +// +// v13(1)=(v8(1)+v2(1))/2; +// v14(1)=(v1(1)+v7(1))/2; +// v13(2)=0.0; +// v14(2)=0.0; + } + + // compute the strain and axial force in the member + double strain[7], force[7]; + + for (int i = 0; i < 6; i++) { + + strain[i] = this->computeCurrentStrain(i); + theMaterial[i]->setTrialStrain(strain[i]); + force[i] = theMaterial[i]->getStress(); + + } +// strain[6]=(end10Disp(0)+end7Disp(0))-(end1Disp(0)+end4Disp(0)); +// theMaterial2->setrialStrain(strain[6],FFAXIAL); +// force[6]=theMaterial2->getStress(); + + +// code=0; +// code +=theViewer.drawLine(v1,v2,1.0,1.0); +// code +=theViewer.drawLine(v3,v4,1.0,1.0); +// code +=theViewer.drawLine(v5,v6,1.0,1.0); +// code +=theViewer.drawLine(v7,v8,1.0,1.0); +// code +=theViewer.drawLine(v9,v10,1.0,1.0); +// code +=theViewer.drawLine(v11,v12,1.0,1.0); +// code +=theViewer.drawLine(v13,v14,(float)strain[6],(float)strain[65]); +// return code; + + + + if (displayMode == 2) // use the strain as the drawing measure + { + code=0; + code +=theViewer.drawLine(v1,v2,(float)strain[0],(float)strain[0]); + code +=theViewer.drawLine(v3,v4,(float)strain[1],(float)strain[1]); + code +=theViewer.drawLine(v5,v6,(float)strain[2],(float)strain[2]); + code +=theViewer.drawLine(v7,v8,(float)strain[3],(float)strain[3]); + code +=theViewer.drawLine(v9,v10,(float)strain[4],(float)strain[4]); + code +=theViewer.drawLine(v11,v12,(float)strain[5],(float)strain[5]); + + return code; +} + + else if (displayMode < 0) + { + code = 0; + code += theViewer.drawLine(v1a, v2a, 1.0, 1.0, this->getTag(), 0); + code += theViewer.drawLine(v3a, v4a, 1.0, 1.0, this->getTag(), 0); + code += theViewer.drawLine(v5a, v6a, 1.0, 1.0, this->getTag(), 0); + code += theViewer.drawLine(v7a, v8a, 1.0, 1.0, this->getTag(), 0); + code += theViewer.drawLine(v9a, v10a, 1.0, 1.0, this->getTag(), 0); + code += theViewer.drawLine(v11a, v12a, 1.0, 1.0, this->getTag(), 0); + return code; + + } + + + + else { // otherwise use the axial force as measure + code=0; + //code +=theViewer.drawLine(v1,v2,(float)force[0],(float)force[0],0,0,2,0); + code += theViewer.drawLine(v1, v2, (float)force[0], (float)force[0]); + code +=theViewer.drawLine(v3,v4,(float)force[1],(float)force[1]); + code +=theViewer.drawLine(v5,v6,(float)force[2],(float)force[2]); + //code +=theViewer.drawLine(v7,v8,(float)force[3],(float)force[3],0,0,2,0); + code += theViewer.drawLine(v7, v8, (float)force[3], (float)force[3]); + code +=theViewer.drawLine(v9,v10,(float)force[4],(float)force[4]); + code +=theViewer.drawLine(v11,v12,(float)force[5],(float)force[5]); + + + return code; + } + + return 0; +} + + diff --git a/SRC/element/masonry/MasonPan12.h b/SRC/element/masonry/MasonPan12.h new file mode 100644 index 000000000..1a7c0b4fa --- /dev/null +++ b/SRC/element/masonry/MasonPan12.h @@ -0,0 +1,112 @@ +/* ****************************************************************** ** +** 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: 2008/12/10 00:05:21 $ +// $Source: /usr/local/cvs/OpenSees/PACKAGES/NewElement/cpp/Truss2D.h,v $ + +// Written by: Gonzalo Torrisi, Universidad Nacional de Cuyo + +#ifndef MasonPan12_h +#define MasonPan12_h + +#include +#include +#include + +class UniaxialMaterial; + +class MasonPan12 : public Element +{ + public: + // constructors + MasonPan12(int tag, + int Nd1, int Nd2, int Nd3, int Nd4, int Nd5, int Nd6, + int Nd7, int Nd8, int Nd9, int Nd10, int Nd11, int Nd12, + UniaxialMaterial &theMaterial, UniaxialMaterial &theMaterial2, + double thick, double wr,double w1); + + + + MasonPan12(); + + // destructor + ~MasonPan12(); + + + // public methods to obtain inforrmation about dof & connectivity + 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 + const Matrix &getTangentStiff(void); + const Matrix &getInitialStiff(void); + + // public method to obtain resisting force + const Vector &getResistingForce(void); + + // public methods for 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 **modes, int numMode); + void Print(OPS_Stream &s, int flag =0); + + Response *setResponse(const char **argv, int argc, OPS_Stream &s); + int getResponse(int responseID, Information &eleInformation); + + protected: + + private: + // private member functions - only available to objects of the class + double computeCurrentStrain(int mat) const; + + // private attributes - a copy for each object of the class + UniaxialMaterial **theMaterial; // pointer to a material + UniaxialMaterial *theMaterial2; + ID externalNodes; // contains the id's of end nodes + Matrix trans; // hold the transformation matrix + Vector rig1; + Vector rig2; + Vector rig3; + double TH; + double W1; + double WR; + + double Cdeltares; + double Tdeltares; + int numDOF; // number of dof for truss + + Node *theNodes[12]; // node pointers + + // static data - single copy for all objects of the class + static Matrix PanelK; // class wide matrix for returning stiffness + static Vector PanelR; // class wide vector for returning residual +}; +#endif + diff --git a/SRC/element/masonry/MasonPan3D.cpp b/SRC/element/masonry/MasonPan3D.cpp new file mode 100644 index 000000000..449401e5b --- /dev/null +++ b/SRC/element/masonry/MasonPan3D.cpp @@ -0,0 +1,1676 @@ +/* ****************************************************************** ** +** 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 by: Gonzalo Torrisi, Universidad Nacional de Cuyo + +// we specify what header files we need +#include "MasonPan3D.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// initialise the class wide variables +Matrix MasonPan3D::PanelK(72,72); +Vector MasonPan3D::PanelR(72); + +static int numMyPanel = 0; + +void * +OPS_MasonPan3D() +{ + // print out a message about who wrote this element & any copyright info wanted + if (numMyPanel == 0) { + opserr << " \n"; + opserr << " REFINED MASONRY PANEL\n"; + opserr << " Written by Gonzalo Torrisi UNCuyo Copyright 2016\n"; + opserr << " Model with 6 compression struts\n"; + opserr << " 3D VERSION \n"; + opserr << " Use at your Own Peril\n"; + + numMyPanel++; + } + + Element *thePanel = 0; + + int numRemainingArgs = OPS_GetNumRemainingInputArgs(); + if (numRemainingArgs == 0) { // parallel processing + thePanel = new MasonPan3D(); + return thePanel; + } + + if (numRemainingArgs !=18) { + opserr << "ERROR - Masonry Panel not enough args provided, want: element MasonryPanel tag? Node1? Node2? Node3? Node4? Node5? Node6? Node7? Node8? Node9? Node10? Node11? Node12? matTag? matTag2? thick? wfactor? w1?\n"; + numMyPanel++; + } + + // get the id and end nodes + int iData[15]; + double dData[3]; + int numData; + + numData = 13; + if (OPS_GetIntInput(&numData, iData) != 0) { + opserr << "WARNING invalid element data\n"; + return 0; + } + int eleTag = iData[0]; + + numData =1; + if (OPS_GetIntInput(&numData, &iData[13]) != 0) { + opserr << "WARNING error reading element material 1 tag for element " << eleTag << endln; + return 0; + } + numData =1; + if (OPS_GetIntInput(&numData, &iData[14]) != 0) { + opserr << "WARNING error reading element material 2 tag for element " << eleTag << endln; + return 0; + } + + int matID = iData[13]; + int matID2 = iData[14]; + + numData =3 ; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING error reading element areas, thickness and properties for element" << eleTag << endln; + return 0; + } + + + + UniaxialMaterial *theMaterial = OPS_GetUniaxialMaterial(matID); + UniaxialMaterial *theMaterial2 =OPS_GetUniaxialMaterial(matID2); + + if (theMaterial == 0) { + opserr << "WARNING material with tag " << matID << "not found for element " << eleTag << endln; + return 0; + } + + // now create the truss and add it to the Domain + + thePanel = new MasonPan3D(eleTag, iData[1], iData[2], iData[3], iData[4], iData[5], iData[6], iData[7], iData[8], iData[9], iData[10], iData[11], iData[12], *theMaterial, *theMaterial2, dData[0], dData[1], dData[2]); + + if (thePanel == 0) { + opserr << "WARNING ran out of memory creating element with tag " << eleTag << endln; + delete theMaterial; + delete theMaterial2; + return 0; + } + + return thePanel; +} + + +// typical constructor +MasonPan3D::MasonPan3D(int tag, + int Nd1, int Nd2, int Nd3, int Nd4, int Nd5, int Nd6, + int Nd7, int Nd8, int Nd9, int Nd10, int Nd11, int Nd12, + UniaxialMaterial &theMat, UniaxialMaterial &theMat2, + double thick, double wr,double w1) +:Element(tag, ELE_TAG_MasonPan3D), + externalNodes(12), + trans(8,4),rig1(6),rig2(6),rig3(6), TH(thick), W1(w1), WR(wr), theMaterial(0),theMaterial2(0) + +{ + + // allocate memory for numMaterials1d uniaxial material models + theMaterial = new UniaxialMaterial *[6]; + theMaterial2= 0; + + + if ( theMaterial == 0 ) { + opserr << "FATAL MasonPan3D::MasonPan3D - failed to create a 1d material or direction array\n"; + exit(-1); + } + + // get a copy of the material and check we obtained a valid copy + + + theMaterial[0] = theMat.getCopy(); + theMaterial[3] = theMat.getCopy(); + + if (theMaterial[0] == 0) { + opserr << "FATAL MasonPan3D::MasonPan3D - failed to get a copy of material\n" ; + exit(-1); + } + if (theMaterial[3] == 0) { + opserr << "FATAL MasonPan3D::MasonPan3D - failed to get a copy of material\n" ; + exit(-1); + } + + theMaterial[1] = theMat2.getCopy(); + theMaterial[2] = theMat2.getCopy(); + theMaterial[4] = theMat2.getCopy(); + theMaterial[5] = theMat2.getCopy(); + + + + // fill in the ID containing external node info with node id's + if (externalNodes.Size() != 12) { + opserr << "FATAL MassonPan::MasonPan3D() - out of memory, could not create an ID of size 12\n"; + exit(-1); + } + + externalNodes(0) = Nd1; + externalNodes(1) = Nd2; + externalNodes(2) = Nd3; + externalNodes(3) = Nd4; + externalNodes(4) = Nd5; + externalNodes(5) = Nd6; + externalNodes(6) = Nd7; + externalNodes(7) = Nd8; + externalNodes(8) = Nd9; + externalNodes(9) = Nd10; + externalNodes(10) = Nd11; + externalNodes(11) = Nd12; + + + 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; + theNodes[9] = 0; + theNodes[10] = 0; + theNodes[11] = 0; +} + +// constructor which should be invoked by an FE_ObjectBroker only +MasonPan3D::MasonPan3D() +:Element(0, ELE_TAG_MasonPan3D), + theMaterial(0), theMaterial2(0), + externalNodes(12), + trans(8,4),rig1(6),rig2(6),rig3(6), TH(0.0),W1(0.0),WR(0.0) +{ + 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; + theNodes[9] = 0; + theNodes[10] = 0; + theNodes[11] = 0; +} + +// destructor - provided to clean up any memory +MasonPan3D::~MasonPan3D() +{ + // clean up the memory associated with the element, this is + // memory the Truss2D objects allocates and memory allocated + // by other objects that the Truss2D object is responsible for + // cleaning up, i.e. the MaterialObject. + for (int i=0; i<6; i++) { + if (theMaterial[i] != 0) + delete theMaterial[i]; +} + delete [] theMaterial; + delete theMaterial2; +} + +int +MasonPan3D::getNumExternalNodes(void) const +{ + return 12; +} + +const ID & +MasonPan3D::getExternalNodes(void) +{ + return externalNodes; +} + +Node ** +MasonPan3D::getNodePtrs(void) +{ + return theNodes; +} + +int +MasonPan3D::getNumDOF(void) { + return 72; +} + +// method: setDomain() +// to set a link to the enclosing Domain, ensure nodes exist in Domain +// and set pointers to these nodes, also determines the length and +// transformation Matrix. + +void +MasonPan3D::setDomain(Domain *theDomain) +{ + // check Domain is not null - invoked when object removed from a domain + if (theDomain == 0) { + return; + } + int i1; + int i2; + + // first ensure nodes exist in Domain and set the node pointers + Node *end1Ptr, *end2Ptr, *end3Ptr, *end4Ptr, *end5Ptr, *end6Ptr, *end7Ptr, *end8Ptr, *end9Ptr, *end10Ptr, *end11Ptr, *end12Ptr; + int Nd1 = externalNodes(0); + int Nd2 = externalNodes(1); + int Nd3 = externalNodes(2); + int Nd4 = externalNodes(3); + int Nd5 = externalNodes(4); + int Nd6 = externalNodes(5); + int Nd7 = externalNodes(6); + int Nd8 = externalNodes(7); + int Nd9 = externalNodes(8); + int Nd10= externalNodes(9); + int Nd11=externalNodes(10); + int Nd12= externalNodes(11); + + end1Ptr = theDomain->getNode(Nd1); + end2Ptr = theDomain->getNode(Nd2); + end3Ptr = theDomain->getNode(Nd3); + end4Ptr = theDomain->getNode(Nd4); + end5Ptr = theDomain->getNode(Nd5); + end6Ptr = theDomain->getNode(Nd6); + end7Ptr = theDomain->getNode(Nd7); + end8Ptr = theDomain->getNode(Nd8); + end9Ptr = theDomain->getNode(Nd9); + end10Ptr = theDomain->getNode(Nd10); + end11Ptr = theDomain->getNode(Nd11); + end12Ptr = theDomain->getNode(Nd12); + + if (end1Ptr == 0) { + opserr << "WARNING MasonPan3D::setDomain() - at truss " << this->getTag() << " node " << + Nd1 << " does not exist in domain\n"; + + return; // don't go any further - otherwise segemntation fault + } + if (end12Ptr == 0) { + opserr << "WARNING MasonPan3D::setDomain() - at truss " << this->getTag() << " node " << + Nd2 << " does not exist in domain\n"; + + return; // don't go any further - otherwise segemntation fault + } + + theNodes[0] = end1Ptr; + theNodes[1] = end2Ptr; + theNodes[2] = end3Ptr; + theNodes[3] = end4Ptr; + theNodes[4] = end5Ptr; + theNodes[5] = end6Ptr; + theNodes[6] = end7Ptr; + theNodes[7] = end8Ptr; + theNodes[8] = end9Ptr; + theNodes[9] = end10Ptr; + theNodes[10] = end11Ptr; + theNodes[11] = end12Ptr; + + + // call the DomainComponent class method THIS IS VERY IMPORTANT + this->DomainComponent::setDomain(theDomain); + + // ensure connected nodes have correct number of dof's + int dofNd1 = end1Ptr->getNumberDOF(); + int dofNd2 = end2Ptr->getNumberDOF(); + int dofNd3 = end3Ptr->getNumberDOF(); + int dofNd4 = end4Ptr->getNumberDOF(); + int dofNd5 = end5Ptr->getNumberDOF(); + int dofNd6 = end6Ptr->getNumberDOF(); + int dofNd7 = end7Ptr->getNumberDOF(); + int dofNd8 = end8Ptr->getNumberDOF(); + int dofNd9 = end9Ptr->getNumberDOF(); + int dofNd10 = end10Ptr->getNumberDOF(); + int dofNd11 = end11Ptr->getNumberDOF(); + int dofNd12 = end12Ptr->getNumberDOF(); + + if ((dofNd1 != 6 || dofNd2 != 6)) { + opserr << "MasonPan3D::setDomain(): 6 dof required at nodes because the panel is genral-3D\n"; + return; + } + + // now determine the length & transformation matrix + const Vector &end1Crd = end1Ptr->getCrds(); + const Vector &end2Crd = end2Ptr->getCrds(); + const Vector &end3Crd = end3Ptr->getCrds(); + const Vector &end4Crd = end4Ptr->getCrds(); + const Vector &end5Crd = end5Ptr->getCrds(); + const Vector &end6Crd = end6Ptr->getCrds(); + const Vector &end7Crd = end7Ptr->getCrds(); + const Vector &end8Crd = end8Ptr->getCrds(); + const Vector &end9Crd = end9Ptr->getCrds(); + const Vector &end10Crd = end10Ptr->getCrds(); + const Vector &end11Crd = end11Ptr->getCrds(); + const Vector &end12Crd = end12Ptr->getCrds(); + + // double dx = end4Crd(0)-end1Crd(0); + // double dy = end10Crd(1)-end1Crd(1); + + double dy71=end7Crd(1)-end1Crd(1); + double dz71=end7Crd(2)-end1Crd(2); + double dx71=end7Crd(0)-end7Crd(0); + + + if (dy71 == 0.0) { + int iplan=1; + i1=0; + i2=2; + opserr << "MasonPan3D::Panel is in X-Z plane\n"; + } + else if (dz71 == 0.0) { + int iplan=2; + i1=0; + i2=1; + opserr << "MasonPan3D::Panel is in X-Y plane\n"; + } + else if (dx71 == 0.0) { + int iplan=3; + i1=1; + i2=2; + opserr << "MasonPan3D::Panel is in Y-Z plane\n"; + } + else { + i1=1; + i2=2; + opserr << "WARNING!!!! MasonPan3D::Panel has no defined plane!!!! \n"; + return; + } + +// opserr << "dz71 " << dz71 << endln; +// opserr << "dx71 " << dx71 << endln; +// opserr << "dy71 " << dy71 << endln; + // cosenos de las diagonales + double dx1 =end4Crd(i1)-end10Crd(i1); + double dy1= end4Crd(i2)-end10Crd(i2); + double L1=sqrt(dx1*dx1+dy1*dy1); + double dx2 =end3Crd(i1)-end11Crd(i1); + double dy2= end3Crd(i2)-end11Crd(i2); + double L2=sqrt(dx2*dx2+dy2*dy2); + double dx3 =end5Crd(i1)-end9Crd(i1); + double dy3= end5Crd(i2)-end9Crd(i2); + double L3=sqrt(dx3*dx3+dy3*dy3); + + double dx4 =end7Crd(i1)-end1Crd(i1); + double dy4= end7Crd(i2)-end1Crd(i2); + double L4=sqrt(dx4*dx4+dy4*dy4); + double dx5 =end6Crd(i1)-end2Crd(i1); + double dy5= end6Crd(i2)-end2Crd(i2); + double L5=sqrt(dx5*dx5+dy5*dy5); + double dx6 =end8Crd(i1)-end12Crd(i1); + double dy6= end8Crd(i2)-end12Crd(i2); + double L6=sqrt(dx6*dx6+dy6*dy6); + double Area1=L1*WR*TH*W1; + double Area2=L1*WR*TH*(1-W1)/2; + double Area3=L1*WR*TH*(1-W1)/2; + double Area4=L1*WR*TH*W1; + double Area5=L1*WR*TH*(1-W1)/2; + double Area6=L1*WR*TH*(1-W1)/2; + double Lpan=end4Crd(i1)-end1Crd(i1); + double Apan=Lpan*TH; + + //rigidez del resorte + //suma de cosenos l cuadrado + trans(0,0)=L1; + trans(0,1)=dx1/L1; + trans(0,2)=dy1/L1; + trans(0,3)=Area1; + trans(1,0)=L2; + trans(1,1)=dx2/L2; + trans(1,2)=dy2/L2; + trans(1,3)=Area2; + trans(2,0)=L3; + trans(2,1)=dx3/L3; + trans(2,2)=dy3/L3; + trans(2,3)=Area3; + trans(3,0)=L4; + trans(3,1)=dx4/L4; + trans(3,2)=dy4/L4; + trans(3,3)=Area4; + trans(4,0)=L5; + trans(4,1)=dx5/L5; + trans(4,2)=dy5/L5; + trans(4,3)=Area5; + trans(5,0)=L6; + trans(5,1)=dx6/L6; + trans(5,2)=dy6/L6; + trans(5,3)=Area6; + trans(6,0)=Apan; + trans(6,1)=0; + trans(6,2)=0; + trans(6,3)=0; + trans(7,0)=dy1; + trans(7,1)=i1; + trans(7,2)=i2; + for (int im=0; im<6; im++) { + rig1(im) = trans(im,1)*trans(im,1)*trans(im,3)/trans(im,0); + rig2(im) = trans(im,1)*trans(im,2)*trans(im,3)/trans(im,0); + rig3(im) = trans(im,2)*trans(im,2)*trans(im,3)/trans(im,0); + } + +} + +int +MasonPan3D::commitState() +{ + int ecode=0; + //commit material models + for (int i=0; i<6; i++) + ecode += theMaterial[i]->commitState(); + //commit the base class + + + ecode += this->Element::commitState(); + + + return ecode; +} + +int +MasonPan3D::revertToLastCommit() +{ +// return theMaterial->revertToLastCommit(); + int code=0; + + // revert state for 1d materials + for (int i=0; i<6; i++) + code += theMaterial[i]->revertToLastCommit(); + // code += theMaterial2->revertToLastCommit(); + + return code; +} + +int +MasonPan3D::revertToStart() +{ + // return theMaterial->revertToStart(); + int code=0; + + // revert state for 1d materials + for (int i=0; i<6; i++) + code += theMaterial[i]->revertToStart(); + // code += theMaterial2->revertToStart(); + + return code; +} + +int +MasonPan3D::update() +{ + // determine the current strain given trial displacements at nodes + // double strain = this->computeCurrentStrain(); + + // set the strain in the materials + //theMaterial->setTrialStrain(strain); + + // compute strain and rate; set as current trial for material + ////////////////////////////////////// strain = this->computeCurrentStrain(mat ); + // strainRate = this->computeCurrentStrain(); + double str[6]; + + // determine the strain + 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(); + const Vector &disp10 = theNodes[9]->getTrialDisp(); + const Vector &disp11 = theNodes[10]->getTrialDisp(); + const Vector &disp12 = theNodes[11]->getTrialDisp(); + + int i1=int(trans(7,1)); + int i2=int(trans(7,2)); + + double c1=trans(0,1); + double s1=trans(0,2); + double L1=trans(0,0); + double A1=trans(0,3); + double du1=((disp4(i1)-disp10(i1))*c1+(disp4(i2)-disp10(i2))*s1)/L1; + c1=trans(1,1); + double s2=trans(1,2); + double L2=trans(1,0); + double A2=trans(1,3); + double du2=((disp3(i1)-disp11(i1))*c1+(disp3(i2)-disp11(i2))*s2)/L2; + c1=trans(2,1); + double s3=trans(2,2); + double L3=trans(2,0); + double A3=trans(2,3); + double du3=((disp5(i1)-disp9(i1))*c1+(disp5(i2)-disp9(i2))*s3)/L3; + c1=trans(3,1); + double s4=trans(3,2); + double L4=trans(3,0); + double A4=trans(3,3); + double du4=((disp7(i1)-disp1(i1))*c1+(disp7(i2)-disp1(i2))*s4)/L4; + c1=trans(4,1); + double s5=trans(4,2); + double L5=trans(4,0); + double A5=trans(4,3); + double du5=((disp6(i1)-disp2(i1))*c1+(disp6(i2)-disp2(i2))*s5)/L5; + c1=trans(5,1); + double s6=trans(5,2); + double L6=trans(5,0); + double A6=trans(5,3); + double du6=((disp8(i1)-disp12(i1))*c1+(disp8(i2)-disp12(i2))*s6)/L6; + //resorte + + + str[0]=du1; + str[1]=du2; + str[2]=du3; + str[3]=du4; + str[4]=du5; + str[5]=du6; + + + + int ret = 0; + for (int mat=0; mat<6; mat++) { + + double strain=0; + strain=str[mat]; + ret+= theMaterial[mat]->setTrialStrain(strain); + } + + return ret; + + +// return 0; +} + +const Matrix & +MasonPan3D::getTangentStiff(void) +{ + for( int i=0; i<72; i++){ + for( int j=0; j<72; j++){ + PanelK(i,j)=0.0; + } + } + + int dj1; + int dj2; + int j1i; + int j2i; + int j1d; + int j2d; + double Et; + int i1=int(trans(7,1)); + int i2=int(trans(7,2)); + int i12=i1+i2; + if (i12==2){ + int ji=0; + int jj=2; + dj1=5; + dj2=3; + } + else if (i12==1){ + int ji=0; + int jj=1; + dj1=5; + dj2=4; + + } + else if (i12==3){ + int ji=1; + int jj=2; + dj1=4; + dj2=3; + } + +//diagonal 1 (nodo 10-4) + Et=theMaterial[0]->getTangent(); + j1i=6*4-dj1-1; + j2i=6*4-dj2-1; + j1d=6*10-dj1-1; + j2d=6*10-dj2-1; + + PanelK(j1i,j1i)=rig1(0)*Et; + PanelK(j1i,j2i)=rig2(0)*Et; + PanelK(j2i,j1i)=rig2(0)*Et; + PanelK(j2i,j2i)=rig3(0)*Et; + PanelK(j1d,j1d)=rig1(0)*Et; + PanelK(j1d,j2d)=rig2(0)*Et; + PanelK(j2d,j1d)=rig2(0)*Et; + PanelK(j2d,j2d)=rig3(0)*Et; + PanelK(j1i,j1d)=-rig1(0)*Et; + PanelK(j1i,j2d)=-rig2(0)*Et; + PanelK(j2i,j1d)=-rig2(0)*Et; + PanelK(j2i,j2d)=-rig3(0)*Et; + PanelK(j1d,j1i)=-rig1(0)*Et; + PanelK(j1d,j2i)=-rig2(0)*Et; + PanelK(j2d,j1i)=-rig2(0)*Et; + PanelK(j2d,j2i)=-rig3(0)*Et; + +//diagonal 2 nodos 11-3 + Et=theMaterial[1]->getTangent(); + j1i=6*3-dj1-1; + j2i=6*3-dj2-1; + j1d=6*11-dj1-1; + j2d=6*11-dj2-1; + + PanelK(j1i,j1i)=rig1(1)*Et; + PanelK(j1i,j2i)=rig2(1)*Et; + PanelK(j2i,j1i)=rig2(1)*Et; + PanelK(j2i,j2i)=rig3(1)*Et; + PanelK(j1d,j1d)=rig1(1)*Et; + PanelK(j1d,j2d)=rig2(1)*Et; + PanelK(j2d,j1d)=rig2(1)*Et; + PanelK(j2d,j2d)=rig3(1)*Et; + PanelK(j1i,j1d)=-rig1(1)*Et; + PanelK(j1i,j2d)=-rig2(1)*Et; + PanelK(j2i,j1d)=-rig2(1)*Et; + PanelK(j2i,j2d)=-rig3(1)*Et; + PanelK(j1d,j1i)=-rig1(1)*Et; + PanelK(j1d,j2i)=-rig2(1)*Et; + PanelK(j2d,j1i)=-rig2(1)*Et; + PanelK(j2d,j2i)=-rig3(1)*Et; + +//diagonal 3 nodos 9-5 + j1i=6*5-dj1-1; + j2i=6*5-dj2-1; + j1d=6*9-dj1-1; + j2d=6*9-dj2-1; + + Et=theMaterial[2]->getTangent(); + PanelK(j1i,j1i)=rig1(2)*Et; + PanelK(j1i,j2i)=rig2(2)*Et; + PanelK(j2i,j1i)=rig2(2)*Et; + PanelK(j2i,j2i)=rig3(2)*Et; + PanelK(j1d,j1d)=rig1(2)*Et; + PanelK(j1d,j2d)=rig2(2)*Et; + PanelK(j2d,j1d)=rig2(2)*Et; + PanelK(j2d,j2d)=rig3(2)*Et; + PanelK(j1i,j1d)=-rig1(2)*Et; + PanelK(j1i,j2d)=-rig2(2)*Et; + PanelK(j2i,j1d)=-rig2(2)*Et; + PanelK(j2i,j2d)=-rig3(2)*Et; + PanelK(j1d,j1i)=-rig1(2)*Et; + PanelK(j1d,j2i)=-rig2(2)*Et; + PanelK(j2d,j1i)=-rig2(2)*Et; + PanelK(j2d,j2i)=-rig3(2)*Et; + +//diagonal 4 nodos 1-7 + Et=theMaterial[3]->getTangent(); + j1i=6*1-dj1-1; + j2i=6*1-dj2-1; + j1d=6*7-dj1-1; + j2d=6*7-dj2-1; + + PanelK(j1i,j1i)=rig1(3)*Et; + PanelK(j1i,j2i)=rig2(3)*Et; + PanelK(j2i,j1i)=rig2(3)*Et; + PanelK(j2i,j2i)=rig3(3)*Et; + PanelK(j1d,j1d)=rig1(3)*Et; + PanelK(j1d,j2d)=rig2(3)*Et; + PanelK(j2d,j1d)=rig2(3)*Et; + PanelK(j2d,j2d)=rig3(3)*Et; + PanelK(j1i,j1d)=-rig1(3)*Et; + PanelK(j1i,j2d)=-rig2(3)*Et; + PanelK(j2i,j1d)=-rig2(3)*Et; + PanelK(j2i,j2d)=-rig3(3)*Et; + PanelK(j1d,j1i)=-rig1(3)*Et; + PanelK(j1d,j2i)=-rig2(3)*Et; + PanelK(j2d,j1i)=-rig2(3)*Et; + PanelK(j2d,j2i)=-rig3(3)*Et; + +//diagonal 5 nodos 2-6 + j1i=6*2-dj1-1; + j2i=6*2-dj2-1; + j1d=6*6-dj1-1; + j2d=6*6-dj2-1; + + Et=theMaterial[4]->getTangent(); + PanelK(j1i,j1i)=rig1(4)*Et; + PanelK(j1i,j2i)=rig2(4)*Et; + PanelK(j2i,j1i)=rig2(4)*Et; + PanelK(j2i,j2i)=rig3(4)*Et; + PanelK(j1d,j1d)=rig1(4)*Et; + PanelK(j1d,j2d)=rig2(4)*Et; + PanelK(j2d,j1d)=rig2(4)*Et; + PanelK(j2d,j2d)=rig3(4)*Et; + PanelK(j1i,j1d)=-rig1(4)*Et; + PanelK(j1i,j2d)=-rig2(4)*Et; + PanelK(j2i,j1d)=-rig2(4)*Et; + PanelK(j2i,j2d)=-rig3(4)*Et; + PanelK(j1d,j1i)=-rig1(4)*Et; + PanelK(j1d,j2i)=-rig2(4)*Et; + PanelK(j2d,j1i)=-rig2(4)*Et; + PanelK(j2d,j2i)=-rig3(4)*Et; + +//diagonal 6 nodos 12-8 + j1i=6*8-dj1-1; + j2i=6*8-dj2-1; + j1d=6*12-dj1-1; + j2d=6*12-dj2-1; + Et=theMaterial[5]->getTangent(); + PanelK(j1i,j1i)=rig1(5)*Et; + PanelK(j1i,j2i)=rig2(5)*Et; + PanelK(j2i,j1i)=rig2(5)*Et; + PanelK(j2i,j2i)=rig3(5)*Et; + PanelK(j1d,j1d)=rig1(5)*Et; + PanelK(j1d,j2d)=rig2(5)*Et; + PanelK(j2d,j1d)=rig2(5)*Et; + PanelK(j2d,j2d)=rig3(5)*Et; + PanelK(j1i,j1d)=-rig1(5)*Et; + PanelK(j1i,j2d)=-rig2(5)*Et; + PanelK(j2i,j1d)=-rig2(5)*Et; + PanelK(j2i,j2d)=-rig3(5)*Et; + PanelK(j1d,j1i)=-rig1(5)*Et; + PanelK(j1d,j2i)=-rig2(5)*Et; + PanelK(j2d,j1i)=-rig2(5)*Et; + PanelK(j2d,j2i)=-rig3(5)*Et; + + + + // return the matrix + return PanelK; +} + +const Matrix & +MasonPan3D::getInitialStiff(void) +{ + for( int i=0; i<72; i++){ + for( int j=0; j<72; j++){ + PanelK(i,j)=0.0; + } + } + double E; + int dj1; + int dj2; + int j1i; + int j2i; + int j1d; + int j2d; + int i1=int(trans(7,1)); + int i2=int(trans(7,2)); + int i12=i1+i2; + if (i12==2){ + int ji=0; + int jj=2; + dj1=5; + dj2=3; + } + if (i12==1){ + int ji=0; + int jj=1; + dj1=5; + dj2=4; + + } + if (i12==3){ + int ji=1; + int jj=2; + dj1=4; + dj2=3; + } + + + E = theMaterial[0]->getInitialTangent(); +//diagonal 1 + j1i=6*4-dj1-1; + j2i=6*4-dj2-1; + j1d=6*10-dj1-1; + j2d=6*10-dj2-1; + + PanelK(j1i,j1i)=rig1(0)*E; + PanelK(j1i,j2i)=rig2(0)*E; + PanelK(j2i,j1i)=rig2(0)*E; + PanelK(j2i,j2i)=rig3(0)*E; + PanelK(j1d,j1d)=rig1(0)*E; + PanelK(j1d,j2d)=rig2(0)*E; + PanelK(j2d,j1d)=rig2(0)*E; + PanelK(j2d,j2d)=rig3(0)*E; + PanelK(j1i,j1d)=-rig1(0)*E; + PanelK(j1i,j2d)=-rig2(0)*E; + PanelK(j2i,j1d)=-rig2(0)*E; + PanelK(j2i,j2d)=-rig3(0)*E; + PanelK(j1d,j1i)=-rig1(0)*E; + PanelK(j1d,j2i)=-rig2(0)*E; + PanelK(j2d,j1i)=-rig2(0)*E; + PanelK(j2d,j2i)=-rig3(0)*E; + + + E = theMaterial[1]->getInitialTangent(); +//diagonal 2 + j1i=6*3-dj1-1; + j2i=6*3-dj2-1; + j1d=6*11-dj1-1; + j2d=6*11-dj2-1; + + PanelK(j1i,j1i)=rig1(1)*E; + PanelK(j1i,j2i)=rig2(1)*E; + PanelK(j2i,j1i)=rig2(1)*E; + PanelK(j2i,j2i)=rig3(1)*E; + PanelK(j1d,j1d)=rig1(1)*E; + PanelK(j1d,j2d)=rig2(1)*E; + PanelK(j2d,j1d)=rig2(1)*E; + PanelK(j2d,j2d)=rig3(1)*E; + PanelK(j1i,j1d)=-rig1(1)*E; + PanelK(j1i,j2d)=-rig2(1)*E; + PanelK(j2i,j1d)=-rig2(1)*E; + PanelK(j2i,j2d)=-rig3(1)*E; + PanelK(j1d,j1i)=-rig1(1)*E; + PanelK(j1d,j2i)=-rig2(1)*E; + PanelK(j2d,j1i)=-rig2(1)*E; + PanelK(j2d,j2i)=-rig3(1)*E; + + E = theMaterial[2]->getInitialTangent(); +//diagonal 3 + j1i=6*5-dj1-1; + j2i=6*5-dj2-1; + j1d=6*9-dj1-1; + j2d=6*9-dj2-1; + + PanelK(j1i,j1i)=rig1(2)*E; + PanelK(j1i,j2i)=rig2(2)*E; + PanelK(j2i,j1i)=rig2(2)*E; + PanelK(j2i,j2i)=rig3(2)*E; + PanelK(j1d,j1d)=rig1(2)*E; + PanelK(j1d,j2d)=rig2(2)*E; + PanelK(j2d,j1d)=rig2(2)*E; + PanelK(j2d,j2d)=rig3(2)*E; + PanelK(j1i,j1d)=-rig1(2)*E; + PanelK(j1i,j2d)=-rig2(2)*E; + PanelK(j2i,j1d)=-rig2(2)*E; + PanelK(j2i,j2d)=-rig3(2)*E; + PanelK(j1d,j1i)=-rig1(2)*E; + PanelK(j1d,j2i)=-rig2(2)*E; + PanelK(j2d,j1i)=-rig2(2)*E; + PanelK(j2d,j2i)=-rig3(2)*E; + + E = theMaterial[3]->getInitialTangent(); +//diagonal 4 + j1i=6*1-dj1-1; + j2i=6*1-dj2-1; + j1d=6*7-dj1-1; + j2d=6*7-dj2-1; + + PanelK(j1i,j1i)=rig1(3)*E; + PanelK(j1i,j2i)=rig2(3)*E; + PanelK(j2i,j1i)=rig2(3)*E; + PanelK(j2i,j2i)=rig3(3)*E; + PanelK(j1d,j1d)=rig1(3)*E; + PanelK(j1d,j2d)=rig2(3)*E; + PanelK(j2d,j1d)=rig2(3)*E; + PanelK(j2d,j2d)=rig3(3)*E; + PanelK(j1i,j1d)=-rig1(3)*E; + PanelK(j1i,j2d)=-rig2(3)*E; + PanelK(j2i,j1d)=-rig2(3)*E; + PanelK(j2i,j2d)=-rig3(3)*E; + PanelK(j1d,j1i)=-rig1(3)*E; + PanelK(j1d,j2i)=-rig2(3)*E; + PanelK(j2d,j1i)=-rig2(3)*E; + PanelK(j2d,j2i)=-rig3(3)*E; + + E = theMaterial[4]->getInitialTangent(); +//diagonal 5 + j1i=6*2-dj1-1; + j2i=6*2-dj2-1; + j1d=6*6-dj1-1; + j2d=6*6-dj2-1; + + PanelK(j1i,j1i)=rig1(4)*E; + PanelK(j1i,j2i)=rig2(4)*E; + PanelK(j2i,j1i)=rig2(4)*E; + PanelK(j2i,j2i)=rig3(4)*E; + PanelK(j1d,j1d)=rig1(4)*E; + PanelK(j1d,j2d)=rig2(4)*E; + PanelK(j2d,j1d)=rig2(4)*E; + PanelK(j2d,j2d)=rig3(4)*E; + PanelK(j1i,j1d)=-rig1(4)*E; + PanelK(j1i,j2d)=-rig2(4)*E; + PanelK(j2i,j1d)=-rig2(4)*E; + PanelK(j2i,j2d)=-rig3(4)*E; + PanelK(j1d,j1i)=-rig1(4)*E; + PanelK(j1d,j2i)=-rig2(4)*E; + PanelK(j2d,j1i)=-rig2(4)*E; + PanelK(j2d,j2i)=-rig3(4)*E; + + + E = theMaterial[5]->getInitialTangent(); +//diagonal 6 + j1i=6*8-dj1-1; + j2i=6*8-dj2-1; + j1d=6*12-dj1-1; + j2d=6*12-dj2-1; + PanelK(j1i,j1i)=rig1(5)*E; + PanelK(j1i,j2i)=rig2(5)*E; + PanelK(j2i,j1i)=rig2(5)*E; + PanelK(j2i,j2i)=rig3(5)*E; + PanelK(j1d,j1d)=rig1(5)*E; + PanelK(j1d,j2d)=rig2(5)*E; + PanelK(j2d,j1d)=rig2(5)*E; + PanelK(j2d,j2d)=rig3(5)*E; + PanelK(j1i,j1d)=-rig1(5)*E; + PanelK(j1i,j2d)=-rig2(5)*E; + PanelK(j2i,j1d)=-rig2(5)*E; + PanelK(j2i,j2d)=-rig3(5)*E; + PanelK(j1d,j1i)=-rig1(5)*E; + PanelK(j1d,j2i)=-rig2(5)*E; + PanelK(j2d,j1i)=-rig2(5)*E; + PanelK(j2d,j2i)=-rig3(5)*E; + + // return the matrix + return PanelK; +} + +const Vector & +MasonPan3D::getResistingForce() +{ + for( int i=0; i<72; i++){ + + PanelR(i)=0.0; + } + + int dj1; + int dj2; + int j1i; + int j2i; + int j1d; + int j2d; + int i1=int(trans(7,1)); + int i2=int(trans(7,2)); + + + int i12=i1+i2; + if (i12==2){ + int ji=0; + int jj=2; + dj1=5; + dj2=3; + } + if (i12==1){ + int ji=0; + int jj=1; + dj1=5; + dj2=4; + + } + if (i12==3){ + int ji=1; + int jj=2; + dj1=4; + dj2=3; + } + + j1i=6*4-dj1-1; + j2i=6*4-dj2-1; + j1d=6*10-dj1-1; + j2d=6*10-dj2-1; + + double Area1=trans(0,3); + double c1=trans(0,1); + double s1=trans(0,2); + double force=0; + force = Area1*theMaterial[0]->getStress(); + PanelR(j1i)=force*c1; + PanelR(j2i)=force*s1; + PanelR(j1d)=-force*c1; + PanelR(j2d)=-force*s1; + + j1i=6*3-dj1-1; + j2i=6*3-dj2-1; + j1d=6*11-dj1-1; + j2d=6*11-dj2-1; + double Area2=trans(1,3); + c1=trans(1,1); + s1=trans(1,2); + force=0; + force = Area2*theMaterial[1]->getStress(); + PanelR(j1i)=force*c1; + PanelR(j2i)=force*s1; + PanelR(j1d)=-force*c1; + PanelR(j2d)=-force*s1; + + j1i=6*5-dj1-1; + j2i=6*5-dj2-1; + j1d=6*9-dj1-1; + j2d=6*9-dj2-1; + double Area3=trans(2,3); + c1=trans(2,1); + s1=trans(2,2); + force=0; + force = Area3*theMaterial[2]->getStress(); + PanelR(j1i)=force*c1; + PanelR(j2i)=force*s1; + PanelR(j1d)=-force*c1; + PanelR(j2d)=-force*s1; + + + j1i=6*7-dj1-1; + j2i=6*7-dj2-1; + j1d=6*1-dj1-1; + j2d=6*1-dj2-1; + double Area4=trans(3,3); + c1=trans(3,1); + s1=trans(3,2); + force=0; + force = Area4*theMaterial[3]->getStress(); + + PanelR(j1i)=force*c1; + PanelR(j2i)=force*s1; + PanelR(j1d)=-force*c1; + PanelR(j2d)=-force*s1; + + j1i=6*2-dj1-1; + j2i=6*2-dj2-1; + j1d=6*6-dj1-1; + j2d=6*6-dj2-1; + + double Area5=trans(4,3); + c1=trans(4,1); + s1=trans(4,2); + force=0; + force = Area5*theMaterial[4]->getStress(); + PanelR(j1i)=-force*c1; + PanelR(j2i)=-force*s1; + PanelR(j1d)=force*c1; + PanelR(j2d)=force*s1; + + j1i=6*8-dj1-1; + j2i=6*8-dj2-1; + j1d=6*12-dj1-1; + j2d=6*12-dj2-1; + double Area6=trans(5,3); + c1=trans(5,1); + s1=trans(5,2); + force=0; + force = Area6*theMaterial[5]->getStress(); + PanelR(j1i)=force*c1; + PanelR(j2i)=force*s1; + PanelR(j1d)=-force*c1; + PanelR(j2d)=-force*s1; + + + return PanelR; +} + +int +MasonPan3D::sendSelf(int commitTag, Channel &theChannel) +{ + int res; + + // 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(); + + // Truss2D packs it's data into a Vector and sends this to theChannel + // along with it's dbTag and the commitTag passed in the arguments + + //Vector data(5); + //data(0) = this->getTag(); + //data(1) = A; + //data(2) = theMaterial->getClassTag(); + //int matDbTag = theMaterial->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->setDbTag(matDbTag); + // } + //data(3) = matDbTag; + res=0; + // res = theChannel.sendVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING MasonPan3D::sendSelf() - failed to send Vector\n"; + return -1; + } + + // Truss2D then sends the tags of it's two end nodes + // res = theChannel.sendID(dataTag, commitTag, externalNodes); + if (res < 0) { + opserr << "WARNING MasonPan3D::sendSelf() - failed to send ID\n"; + return -2; + } + + // finally Truss2D asks it's material object to send itself + //res = theMaterial->sendSelf(commitTag, theChannel); + if (res < 0) { + opserr << "WARNING MasonPan3D::sendSelf() - failed to send the Material\n"; + return -3; + } + + return 0; +} + +int +MasonPan3D::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +{ + int res; + // int dataTag = this->getDbTag(); + + // Truss2D creates a Vector, receives the Vector and then sets the + // internal data with the data in the Vector + + //Vector data(5); + //res = theChannel.recvVector(dataTag, commitTag, data); + res=-1; + if (res < 0) { + opserr << "WARNING MasonPan3D::recvSelf() - failed to receive Vector\n"; + return -1; + } + + // this->setTag((int)data(0)); + // A = data(1); + + // Truss2D now receives the tags of it's two external nodes + //res = theChannel.recvID(dataTag, commitTag, externalNodes); + if (res < 0) { + opserr << "WARNING MasonPan3D::recvSelf() - failed to receive ID\n"; + return -2; + } + + // we create a material object of the correct type, + // sets its database tag and asks this new object to recveive itself. + //int matClass = data(2); + //int matDb = data(3); + + //theMaterial = theBroker.getNewUniaxialMaterial(matClass); + if (theMaterial == 0) { + opserr << "WARNING MasonPan3D::recvSelf() - failed to create a Material\n"; + return -3; + } + + // we set the dbTag before we receive the material - this is important + //theMaterial->setDbTag(matDb); + //res = theMaterial->recvSelf(commitTag, theChannel, theBroker); + if (res < 0) { + opserr << "WARNING MasonPan3D::recvSelf() - failed to receive the Material\n"; + return -3; + } + + return 0; +} + +void +MasonPan3D::Print(OPS_Stream &s, int flag) +{ + int i1=int(trans(7,1)); + int i2=int(trans(7,2)); + int i12=i1+i2; + + + s << " " << "\n"; + s << " " << "\n"; + s << "Element: " << this->getTag(); + s << " type: MasonPan3D " << "\n"; + s << " " << "\n"; + s << "+--------------------------------------------------------+"<< "\n"; + s << "| REFINED MASONRY PANEL |\n"; + s << "| Written by Gonzalo Torrisi UNCuyo Copyright 2016 |\n"; + s << "| Model with 6 compression struts |\n"; + s << "| 3D VERSION |\n"; + s << "| Use at your Own Peril |\n"; + s << "+--------------------------------------------------------+"<<"\n"; + s << " Nodes: " << "\n"; + s << "Nodo 1 :"<< externalNodes(0)<< "\n"; + s << "Nodo 2 :"<< externalNodes(1)<< "\n"; + s << "Nodo 3 :"<< externalNodes(2)<< "\n"; + s << "Nodo 4 :"<< externalNodes(3)<< "\n"; + s << "Nodo 5 :"<< externalNodes(4)<< "\n"; + s << "Nodo 6 :"<< externalNodes(5)<< "\n"; + s << "Nodo 7 :"<< externalNodes(6)<< "\n"; + s << "Nodo 8 :"<< externalNodes(7)<< "\n"; + s << "Nodo 9 :"<< externalNodes(8)<< "\n"; + s << "Nodo 10 :"<< externalNodes(9)<< "\n"; + s << "Nodo 11 :"<< externalNodes(10)<< "\n"; + s << "Nodo 12 :"<< externalNodes(11)<< "\n"; + if (i12==1){ + s << "The panel is in plane X-Y"<< "\n"; + } + else if(i12==2){ + s << "The panel is in plane X-Z"<< "\n"; + } + else if (i12==3){ + s << "The panel is in plane Y-Z"<< "\n"; + } + else + { + s << "The panel is in plane UNKNOWN!!!"<< "\n"; +} + s << " MasonPan3D Factors: " << "\n"; + s << "Panel Thickness :"<< TH<< "\n"; + s << "Factor wd (total strut width) :"<< WR<< "\n"; + s << "Factor w1 (percent to strut 1) :"<< W1<< "\n"; + s << " MasonPan3D Areas: " << "\n"; + s << "Area 1-4 :"<< trans(0,3)<< " -- "<getTag()); + output.attr("node1 ",externalNodes[0]); + output.attr("node2 ",externalNodes[1]); + output.attr("node3 ",externalNodes[2]); + output.attr("node4 ",externalNodes[3]); + output.attr("node5 ",externalNodes[4]); + output.attr("node6 ",externalNodes[5]); + output.attr("node7 ",externalNodes[6]); + output.attr("node8 ",externalNodes[7]); + output.attr("node9 ",externalNodes[8]); + output.attr("node10",externalNodes[9]); + output.attr("node11",externalNodes[10]); + output.attr("node12",externalNodes[11]); + char outputData[10]; + + if ((strcmp(argv[0],"force") == 0) || (strcmp(argv[0],"forces") == 0) + || (strcmp(argv[0],"globalForces") == 0) || (strcmp(argv[0],"globalforces") == 0)) { + + char outputData[10]; + // int numDOFperNode = numDOF/2; + for (int i=0; i<6; i++) { + sprintf(outputData,"P1_%d", i+1); + output.tag("ResponseType", outputData); + } + for (int j=0; j<6; j++) { + sprintf(outputData,"P2_%d", j+1); + output.tag("ResponseType", outputData); + } + theResponse = new ElementResponse(this, 1, Vector(36)); + + } else if ((strcmp(argv[0],"basicForce") == 0 || strcmp(argv[0],"basicForces") == 0) || + (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)) { + + for (int i=0; i<6; i++) { + sprintf(outputData,"P%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 2, Vector(6)); + + } else if (strcmp(argv[0],"defo") == 0 || strcmp(argv[0],"deformations") == 0 || + strcmp(argv[0],"deformation") == 0 || strcmp(argv[0],"basicDeformation") == 0) { + + for (int i=0; i<6; i++) { + sprintf(outputData,"e%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 3, Vector(6)); + + } else if (strcmp(argv[0],"basicStiffness") == 0) { + + for (int i=0; i<72; i++) { + sprintf(outputData,"e%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 13, Matrix(72,72)); + + } else if ((strcmp(argv[0],"defoANDforce") == 0) || + (strcmp(argv[0],"deformationANDforces") == 0) || + (strcmp(argv[0],"deformationsANDforces") == 0)) { + + int i; + for (i=0; i<6; i++) { + sprintf(outputData,"e%d",i+1); + output.tag("ResponseType",outputData); + } + for (i=0; i<6; i++) { + sprintf(outputData,"P%d",i+1); + output.tag("ResponseType",outputData); + } + theResponse = new ElementResponse(this, 4, Vector(2*6)); + + // a material quantity + } else if (strcmp(argv[0],"material") == 0) { + if (argc > 2) { + int matNum = atoi(argv[1]); + if (matNum >= 1 && matNum <= 6) + theResponse = theMaterial[matNum-1]->setResponse(&argv[2], argc-2, output); + + } + + } + + + output.endTag(); + + return theResponse; +} + +int +MasonPan3D::getResponse(int responseID, Information &eleInformation) +{ + 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(); + const Vector& disp10 = theNodes[9]->getTrialDisp(); + const Vector& disp11 = theNodes[10]->getTrialDisp(); + const Vector& disp12 = theNodes[11]->getTrialDisp(); + + const Vector diff = disp2-disp1; + + switch (responseID) { + case -1: + return -1; + + case 1: + return eleInformation.setVector(this->getResistingForce()); + + case 2: + if (eleInformation.theVector != 0) { + for (int i = 0; i < 6; i++) + (*(eleInformation.theVector))(i) = trans(i,3)*theMaterial[i]->getStress(); + + } + return 0; + + case 3: + if (eleInformation.theVector != 0) { + for (int i = 0; i < 6; i++) + (*(eleInformation.theVector))(i) = theMaterial[i]->getStrain(); + + } + return 0; + + case 13: + if (eleInformation.theMatrix != 0) { + for (int i = 0; i < 72; i++) + (*(eleInformation.theMatrix))(i,i) = theMaterial[i]->getTangent(); + } + return 0; + + case 4: + if (eleInformation.theVector != 0) { + for (int i = 0; i < 6; i++) { + (*(eleInformation.theVector))(i) = theMaterial[i]->getStrain(); + (*(eleInformation.theVector))(i+6) = trans(i,3)*theMaterial[i]->getStress(); + } + return 0; + + default: + return -1; + } + } + } + + +double +MasonPan3D::computeCurrentStrain(int mat) const +//MasonPan3D::computeCurrentStrain(void) const +{ + + int i1=int(trans(7,1)); + int i2=int(trans(7,2)); + + // NOTE this method will never be called with L == 0.0 + double str[6]; + double strain; + // determine the strain + 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(); + const Vector &disp10 = theNodes[9]->getTrialDisp(); + const Vector &disp11 = theNodes[10]->getTrialDisp(); + const Vector &disp12 = theNodes[11]->getTrialDisp(); + + double c1=trans(0,1); + double s1=trans(0,2); + double L1=trans(0,0); + double du1=((disp4(i1)-disp10(i1))*c1+(disp4(i2)-disp10(i2))*s1)/L1; + c1=trans(1,1); + s1=trans(1,2); + double L2=trans(1,0); + double du2=((disp3(i1)-disp11(i1))*c1+(disp3(i2)-disp11(i2))*s1)/L2; + c1=trans(2,1); + s1=trans(2,2); + double L3=trans(2,0); + double du3=((disp5(i1)-disp9(i1))*c1+(disp5(i2)-disp9(i2))*s1)/L3; + c1=trans(3,1); + s1=trans(3,2); + double L4=trans(3,0); + double du4=((disp7(i1)-disp1(i1))*c1+(disp7(i2)-disp1(i2))*s1)/L4; + c1=trans(4,1); + s1=trans(4,2); + double L5=trans(4,0); + double du5=((disp6(i1)-disp2(i1))*c1+(disp6(i2)-disp2(i2))*s1)/L5; + c1=trans(5,1); + s1=trans(5,2); + double L6=trans(5,0); + double du6=((disp8(i1)-disp12(i1))*c1+(disp8(i2)-disp12(i2))*s1)/L6; + + str[0]=du1; + str[1]=du2; + str[2]=du3; + str[3]=du4; + str[4]=du5; + str[5]=du6; + strain=str[mat]; + return strain; +} + +int +MasonPan3D::displaySelf(Renderer &theViewer, int displayMode, float fact, const char **modes, int numMode) +//MasonPan3D::displaySelf(Renderer &theViewer, int displayMode, float fact) +{ + int code = 0; + int error = 0; + int i1 = int(trans(7, 1)); + int i2 = int(trans(7, 2)); + + // first determine the two end points of the CorotTruss2 based on + // the display factor (a measure of the distorted image) + // store this information in 2 3d vectors v1 and v2 + 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(); + const Vector &end10Crd = theNodes[9]->getCrds(); + const Vector &end11Crd = theNodes[10]->getCrds(); + const Vector &end12Crd = theNodes[11]->getCrds(); + + + 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(); + const Vector &end10Disp = theNodes[9]->getDisp(); + const Vector &end11Disp = theNodes[10]->getDisp(); + const Vector &end12Disp = theNodes[11]->getDisp(); + + static Vector v1(3); + static Vector v2(3); + static Vector v3(3); + static Vector v4(3); + static Vector v5(3); + static Vector v6(3); + static Vector v7(3); + static Vector v8(3); + static Vector v9(3); + static Vector v10(3); + static Vector v11(3); + static Vector v12(3); + static Vector v13(3); + static Vector v14(3); + + static Vector rgb(3); + static Vector values(4); + + static Matrix coords(4, 3); + + static Vector v1a(3); + static Vector v2a(3); + static Vector v3a(3); + static Vector v4a(3); + static Vector v5a(3); + static Vector v6a(3); + static Vector v7a(3); + static Vector v8a(3); + static Vector v9a(3); + static Vector v10a(3); + static Vector v11a(3); + static Vector v12a(3); + + theNodes[3]->getDisplayCrds(v1a, fact, displayMode); + theNodes[9]->getDisplayCrds(v2a, fact, displayMode); + theNodes[2]->getDisplayCrds(v3a, fact, displayMode); + theNodes[10]->getDisplayCrds(v4a, fact, displayMode); + theNodes[4]->getDisplayCrds(v5a, fact, displayMode); + theNodes[8]->getDisplayCrds(v6a, fact, displayMode); + theNodes[6]->getDisplayCrds(v7a, fact, displayMode); + theNodes[0]->getDisplayCrds(v8a, fact, displayMode); + theNodes[5]->getDisplayCrds(v9a, fact, displayMode); + theNodes[1]->getDisplayCrds(v10a, fact, displayMode); + theNodes[7]->getDisplayCrds(v11a, fact, displayMode); + theNodes[11]->getDisplayCrds(v12a, fact, displayMode); + + for (int i = 0; i < 3; i++) { + v1(i) = end4Crd(i) + end4Disp(i)*fact; + v2(i) = end10Crd(i) + end10Disp(i)*fact; + v3(i) = end3Crd(i) + end3Disp(i)*fact; + v4(i) = end11Crd(i) + end11Disp(i)*fact; + v5(i) = end5Crd(i) + end5Disp(i)*fact; + v6(i) = end9Crd(i) + end9Disp(i)*fact; + + v7(i) = end7Crd(i) + end7Disp(i)*fact; + v8(i) = end1Crd(i) + end1Disp(i)*fact; + v9(i) = end6Crd(i) + end6Disp(i)*fact; + v10(i) = end2Crd(i) + end2Disp(i)*fact; + v11(i) = end8Crd(i) + end8Disp(i)*fact; + v12(i) = end12Crd(i) + end12Disp(i)*fact; + + } + + // compute the strain and axial force in the member + double strain[6], force[6]; + + for (int i = 0; i < 6; i++) { + + strain[i] = this->computeCurrentStrain(i); + theMaterial[i]->setTrialStrain(strain[i]); + force[i] = theMaterial[i]->getStress(); + } + + + + for (int i = 0; i < 3; i++) { + coords(0, i) = end1Crd(i) + end1Disp(i)*fact; + coords(1, i) = end4Crd(i) + end4Disp(i)*fact; + coords(2, i) = end7Crd(i) + end7Disp(i)*fact; + coords(3, i) = end10Crd(i) + end10Disp(i)*fact; + } + + + if (displayMode == 2) // use the strain as the drawing measure + { + code = 0; + // code +=theViewer.drawLine(v1,v2,(float)strain[0],(float)strain[0],0,0,2,1); + code += theViewer.drawLine(v1, v2, (float)strain[0], (float)strain[0]); + code += theViewer.drawLine(v3, v4, (float)strain[1], (float)strain[1]); + code += theViewer.drawLine(v5, v6, (float)strain[2], (float)strain[2]); + // code +=theViewer.drawLine(v7,v8,(float)strain[3],(float)strain[3],0,0,2,1); + code += theViewer.drawLine(v7, v8, (float)strain[3], (float)strain[3]); + code += theViewer.drawLine(v9, v10, (float)strain[4], (float)strain[4]); + code += theViewer.drawLine(v11, v12, (float)strain[5], (float)strain[5]); + for (int j = 0; j<4; j++) + values(j) = strain[j] * 100; + code += theViewer.drawPolygon(coords, values); + return code; + } + else if (displayMode < 0) + { + code = 0; + code += theViewer.drawLine(v1a, v2a, 1.0, 1.0, this->getTag(), 0); + code += theViewer.drawLine(v3a, v4a, 1.0, 1.0, this->getTag(), 0); + code += theViewer.drawLine(v5a, v6a, 1.0, 1.0, this->getTag(), 0); + code += theViewer.drawLine(v7a, v8a, 1.0, 1.0, this->getTag(), 0); + code += theViewer.drawLine(v9a, v10a, 1.0, 1.0, this->getTag(), 0); + code += theViewer.drawLine(v11a, v12a, 1.0, 1.0, this->getTag(), 0); + for (int j = 0; j<4; j++) + values(j) = force[j]; + code += theViewer.drawPolygon(coords, values); + return code; + + } + + + else { // otherwise use the axial force as measure + code = 0; + // code +=theViewer.drawLine(v1,v2,(float)force[0],(float)force[0],0,0,2,1); + code += theViewer.drawLine(v1, v2, (float)force[0], (float)force[0]); + code += theViewer.drawLine(v3, v4, (float)force[1], (float)force[1]); + code += theViewer.drawLine(v5, v6, (float)force[2], (float)force[2]); + code += theViewer.drawLine(v7, v8, (float)force[3], (float)force[3]); + // code += theViewer.drawLine(v7, v8, (float)force[3], (float)force[3], 0, 0, 2, 1); + code += theViewer.drawLine(v9, v10, (float)force[4], (float)force[4]); + code += theViewer.drawLine(v11, v12, (float)force[5], (float)force[5]); + // code +=theViewer.drawLine(v13,v14,(float)force[6],(float)force[6]); + for (int j = 0; j<4; j++) + values(j) = force[j]; + code += theViewer.drawPolygon(coords, values); + return code; + } + + return 0; +} + + diff --git a/SRC/element/masonry/MasonPan3D.h b/SRC/element/masonry/MasonPan3D.h new file mode 100644 index 000000000..c066b47d2 --- /dev/null +++ b/SRC/element/masonry/MasonPan3D.h @@ -0,0 +1,126 @@ +/* ****************************************************************** ** +** 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: 2008/12/10 00:05:21 $ +// $Source: /usr/local/cvs/OpenSees/PACKAGES/NewElement/cpp/Truss2D.h,v $ + +// Written by: Gonzalo Torrisi, Universidad Nacional de Cuyo + +#ifndef MasonPan3D_h +#define MasonPan3D_h + +#include +#include +#include + +class UniaxialMaterial; + +class MasonPan3D : public Element +{ + public: + // constructors + MasonPan3D(int tag, + int Nd1, int Nd2, int Nd3, int Nd4, int Nd5, int Nd6, + int Nd7, int Nd8, int Nd9, int Nd10, int Nd11, int Nd12, + UniaxialMaterial &theMaterial, UniaxialMaterial &theMaterial2, + double thick, double wr,double w1); + + + + MasonPan3D(); + + // destructor + ~MasonPan3D(); + + + // public methods to obtain inforrmation about dof & connectivity + 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 + const Matrix &getTangentStiff(void); + const Matrix &getInitialStiff(void); + + // public method to obtain resisting force + const Vector &getResistingForce(void); + + // public methods for 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 **modes, int numMode); + void Print(OPS_Stream &s, int flag =0); + + Response *setResponse(const char **argv, int argc, OPS_Stream &s); + int getResponse(int responseID, Information &eleInformation); + + protected: + + private: + // private member functions - only available to objects of the class + double computeCurrentStrain(int mat) const; + + // private attributes - a copy for each object of the class + UniaxialMaterial **theMaterial; // pointer to a material + UniaxialMaterial *theMaterial2; + ID externalNodes; // contains the id's of end nodes + Matrix trans; // hold the transformation matrix + Vector rig1; + Vector rig2; + Vector rig3; + //double L; // length of truss (undeformed configuration) - set in setDomain() + //double A; // area of truss + //double A1; + //double A2; + //double D1; + //double D2; + double TH; + double W1; + double WR; + //double idir; + //double Apan; + //double Gspr; + //double Rigspring; + //double L1; + //double L2; + //double L3; + //double L4; + //double L5; + //double L6; + + + + Node *theNodes[12]; // node pointers + + // static data - single copy for all objects of the class + static Matrix PanelK; // class wide matrix for returning stiffness + static Vector PanelR; // class wide vector for returning residual +}; +#endif + diff --git a/SRC/element/mixedBeamColumn/Makefile b/SRC/element/mixedBeamColumn/Makefile index d2b8f6587..c10cc840f 100644 --- a/SRC/element/mixedBeamColumn/Makefile +++ b/SRC/element/mixedBeamColumn/Makefile @@ -1,6 +1,6 @@ include ../../../Makefile.def -OBJS = MixedBeamColumn2d.o MixedBeamColumn3d.o +OBJS = MixedBeamColumn2d.o MixedBeamColumn3d.o MixedBeamColumnAsym3d.o # Compilation control diff --git a/SRC/element/mixedBeamColumn/MixedBeamColumn2d.cpp b/SRC/element/mixedBeamColumn/MixedBeamColumn2d.cpp index 799e6aefe..0d99e449d 100644 --- a/SRC/element/mixedBeamColumn/MixedBeamColumn2d.cpp +++ b/SRC/element/mixedBeamColumn/MixedBeamColumn2d.cpp @@ -241,6 +241,7 @@ void * OPS_MixedBeamColumn2d() { return 0; } + delete [] sections; return theElement; } @@ -1272,6 +1273,9 @@ Response* MixedBeamColumn2d::setResponse(const char **argv, int argc, } else if (strcmp(argv[0],"integrationWeights") == 0) { theResponse = new ElementResponse(this, 101, Vector(numSections)); + } else if (strcmp(argv[0],"sectionTags") == 0) { + theResponse = new ElementResponse(this, 110, ID(numSections)); + } else if (strcmp(argv[0],"connectedNodes") == 0) { theResponse = new ElementResponse(this, 102, Vector(2)); @@ -1279,7 +1283,7 @@ Response* MixedBeamColumn2d::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],"section") ==0) { if (argc > 2) { int sectionNum = atoi(argv[1]); @@ -1395,6 +1399,12 @@ int MixedBeamColumn2d::getResponse(int responseID, Information &eleInfo) { weights(i) = wts[i]*L; return eleInfo.setVector(weights); + } else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = sections[i]->getTag(); + return eleInfo.setID(tags); + } else if (responseID == 102) { // connected nodes Vector tempVector(2); tempVector(0) = connectedExternalNodes(0); diff --git a/SRC/element/mixedBeamColumn/MixedBeamColumn3d.cpp b/SRC/element/mixedBeamColumn/MixedBeamColumn3d.cpp index 3dca64679..6fde7eaef 100644 --- a/SRC/element/mixedBeamColumn/MixedBeamColumn3d.cpp +++ b/SRC/element/mixedBeamColumn/MixedBeamColumn3d.cpp @@ -224,6 +224,7 @@ void * OPS_MixedBeamColumn3d() { return 0; } + delete [] sections; return theElement; } @@ -1404,6 +1405,9 @@ Response* MixedBeamColumn3d::setResponse(const char **argv, int argc, } else if (strcmp(argv[0],"integrationWeights") == 0) { theResponse = new ElementResponse(this, 101, Vector(numSections)); + } else if (strcmp(argv[0],"sectionTags") == 0) { + theResponse = new ElementResponse(this, 110, ID(numSections)); + } else if (strcmp(argv[0],"connectedNodes") == 0) { theResponse = new ElementResponse(this, 102, Vector(2)); @@ -1544,6 +1548,12 @@ int MixedBeamColumn3d::getResponse(int responseID, Information &eleInfo) { weights(i) = wts[i]*L; return eleInfo.setVector(weights); + } else if (responseID == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = sections[i]->getTag(); + return eleInfo.setID(tags); + } else if (responseID == 102) { // connected nodes Vector tempVector(2); tempVector(0) = connectedExternalNodes(0); diff --git a/SRC/element/mixedBeamColumn/MixedBeamColumnAsym3d.cpp b/SRC/element/mixedBeamColumn/MixedBeamColumnAsym3d.cpp new file mode 100644 index 000000000..07e15af1b --- /dev/null +++ b/SRC/element/mixedBeamColumn/MixedBeamColumnAsym3d.cpp @@ -0,0 +1,2137 @@ +/* ****************************************************************** ** +** 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.1 $ +// $Date: 2010-05-04 17:14:45 $ +// $Source: /scratch/slocal/chroot/cvsroot/openseescomp/CompositePackages/MixedBeamColumnAsym3d/MixedBeamColumnAsym3d.cpp,v $ + +// Modified by: Xinlong Du and Jerome F. Hajjar, Northeastern University, USA; Year 2020 +// Description: Adapted for analysis of asymmetric sections with introducing +// high-order axial terms for the basic element formulation +// References: +// Du, X., & Hajjar, J. F. (2021). Three-dimensional nonlinear mixed 6-DOF beam element +// for thin-walled members. Thin-Walled Structures, 164, 107817. + +#include "MixedBeamColumnAsym3d.h" +#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 + +// Constants that define the dimensionality +//#define NDM 3 // dimension of the problem (3d) +//#define NND 6 // number of nodal dof's +//#define NEGD 12 // number of element global dof's +//#define NDM_SECTION 3 // number of section dof's without torsion +//#define NDM_NATURAL 5 // number of element dof's in the basic system without torsion +//#define NDM_NATURAL_WITH_TORSION 6 // number of element dof's in the basic system with torsion +//#define MAX_NUM_SECTIONS 10 // maximum number of sections allowed + +using namespace std; + + +Matrix MixedBeamColumnAsym3d::theMatrix(NEGD,NEGD); +Vector MixedBeamColumnAsym3d::theVector(NEGD); +double MixedBeamColumnAsym3d::workArea[400]; +//Matrix MixedBeamColumnAsym3d::transformNaturalCoords(NDM_NATURAL_WITH_TORSION,NDM_NATURAL_WITH_TORSION); +//Matrix MixedBeamColumnAsym3d::transformNaturalCoordsT(NDM_NATURAL_WITH_TORSION,NDM_NATURAL_WITH_TORSION); +//int MixedBeamColumnAsym3d::maxNumSections = 10; + +Vector *MixedBeamColumnAsym3d::sectionDefShapeFcn = 0; +Matrix *MixedBeamColumnAsym3d::nldhat = 0; +Matrix *MixedBeamColumnAsym3d::nd1 = 0; +Matrix *MixedBeamColumnAsym3d::nd2 = 0; +Matrix *MixedBeamColumnAsym3d::nd1T = 0; +Matrix *MixedBeamColumnAsym3d::nd2T = 0; + + +/* +#ifdef _USRDLL +#include +#define OPS_Export extern "C" _declspec(dllexport) +#elif _MACOSX +#define OPS_Export extern "C" __attribute__((visibility("default"))) +#else +#define OPS_Export extern "C" +#endif + + +OPS_Export void localInit() { + OPS_Error("MixedBeamColumnAsym3d element \nWritten by Mark D. Denavit, University of Illinois at Urbana-Champaign\n", 1); +} +*/ + +// Documentation: Three Dimensional Mixed Beam Column Element +// element MixedBeamColumnAsym3d $tag $iNode $jNode $numIntgrPts $secTag $transfTag <-mass $massDens> +// <-integration $intType> <-doRayleigh $rFlag> <-geomLinear> +// +// Required Input Parameters: +// $tag integer tag identifying the element +// $iNode, $jNode end nodes +// $numIntgrPts number of integration points along the element length +// $secTag identifier for previously-defined section object +// $transfTag identifier for previously-defined coordinate-transformation (CrdTransf) object +// +// Optional Input: +// -mass $massDens +// $massDens element mass density (per unit length), from which a lumped-mass matrix is formed (optional, default=0.0) +// -integration $intType +// $intType numerical integration type, options are Lobotto, Legendre, Radau, NewtonCotes, Trapezoidal (optional, default= Lobotto) +// -doRayleigh $rFlag +// $rFlag optional, default = 1 +// rFlag = 0 no rayleigh damping +// rFlag = 1 include rayleigh damping (default) +// -geomLinear perform analysis without internal geometric nonlinearity +// -shearCenter $ys $zs +// $ys $zs coordinates of shear center w.r.t centroid +// +// +// References: +// 1. Bulent N. Alemdar and Donald W. White, "Displacement, Flexibility, and Mixed Beam-Column Finite +// Element Formulations for Distributed Plasticity Analysis," Journal of Structural Engineering 131, +// no. 12 (December 2005): 1811-1819. +// 2. Cenk Tort and Jerome F. Hajjar, "Mixed Finite Element for Three-Dimensional Nonlinear Dynamic +// Analysis of Rectangular Concrete-Filled Steel Tube Beam-Columns," Journal of Engineering Mechanics +// 136, no. 11 (November 0, 2010): 1329-1339. +// 3. Denavit, M. D. and Hajjar, J. F. (2010). "Nonlinear Seismic Analysis of Circular Concrete-Filled +// Steel Tube Members and Frames," Report No. NSEL-023, Newmark Structural Laboratory Report Series +// (ISSN 1940-9826), Department of Civil and Environmental Engineering, University of Illinois at +// Urbana-Champaign, Urbana, Illinois, March. +// + +void* OPS_MixedBeamColumnAsym3d() +{ + 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; + double dData[2]; //input of ys and zs + dData[0] = 0.0; + dData[1] = 0.0; + int doRayleigh = 1; + bool geomLinear = false; + while (OPS_GetNumRemainingInputArgs() > 0) { + const char* type = OPS_GetString(); + if (strcmp(type, "-cMass") == 0) { + opserr << "WARNING: consistent mass not implemented\n"; + } + else if (strcmp(type, "-mass") == 0) { + numData = 1; + if (OPS_GetNumRemainingInputArgs() > 0) { + if (OPS_GetDoubleInput(&numData, &mass) < 0) { + opserr << "WARNING: invalid mass\n"; + return 0; + } + } + } + else if (strcmp(type, "-shearCenter") == 0) { + // Get the coordinates of shear center w.r.t centroid + numData = 2; + if (OPS_GetDoubleInput(&numData, dData) < 0) { + opserr << "WARNING: invalid ys and zs\n"; + return 0; + } + } + else if (strcmp(type, "-doRayleigh") == 0) { + numData = 1; + if (OPS_GetInt(&numData, &doRayleigh) != 0) { + opserr << "WARNING: Invalid doRayleigh in element MixedBeamColumnAsym3d " << iData[0]; + return 0; + } + } + else if (strcmp(type, "-geomLinear") == 0) { + opserr << "WARNING: geometric linear in the basic system not implemented\n"; + } + } + + // 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 MixedBeamColumnAsym3d(iData[0], iData[1], iData[2], secTags.Size(), sections, + *bi, *theTransf, dData[0], dData[1], mass, doRayleigh, geomLinear); + delete[] sections; + return theEle; +} + +void * OPS_MixedBeamColumnAsym3dTcl() { + // Variables to retrieve input + int iData[10]; + double dData[10]; + double dData2[2]; //input of ys and zs + dData2[0] = 0.0; + dData2[1] = 0.0; + int numData; + + // Check the number of dimensions + if (OPS_GetNDM() != 3) { + opserr << "ERROR: MixedBeamColumnAsym3d: invalid number of dimensions\n"; + return 0; + } + + // Check the number of degrees of freedom + if (OPS_GetNDF() != 6) { + opserr << "ERROR: MixedBeamColumnAsym3d: invalid number of degrees of freedom\n"; + return 0; + } + + // Check for minimum number of arguments + if (OPS_GetNumRemainingInputArgs() < 6) { + opserr << "ERROR: MixedBeamColumnAsym3d: too few arguments\n"; + return 0; + } + + // Get required input data + numData = 6; + if (OPS_GetIntInput(&numData, iData) != 0) { + opserr << "WARNING invalid element data - MixedBeamColumnAsym3d\n"; + return 0; + } + 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; + } + + // Get the coordinate transformation + CrdTransf *theTransf = OPS_getCrdTransf(transfTag); + if (theTransf == 0) { + opserr << "WARNING geometric transformation with tag " << transfTag << "not found for element " << eleTag << endln; + return 0; + } + + // Set Default Values for Optional Input + int doRayleigh = 1; + double massDens = 0.0; + bool geomLinear = false; + BeamIntegration *beamIntegr = 0; + + // Loop through remaining arguments to get optional input + while ( OPS_GetNumRemainingInputArgs() > 0 ) { + const char *sData = OPS_GetString(); + + if ( strcmp(sData,"-mass") == 0 ) { + numData = 1; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING invalid input, want: -mass $massDens \n"; + return 0; + } + massDens = dData[0]; + + } else if ( strcmp(sData,"-integration") == 0 ) { + const char *sData2 = OPS_GetString(); + + 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; + } + } else if ( strcmp(sData,"-doRayleigh") == 0 ) { + numData = 1; + if (OPS_GetInt(&numData, &doRayleigh) != 0) { + opserr << "WARNING: Invalid doRayleigh in element MixedBeamColumnAsym3d " << eleTag; + return 0; + } + + } else if ( strcmp(sData,"-geomLinear") == 0 ) { + geomLinear = true; + + } else if (strcmp(sData, "-shearCenter") == 0) { + // Get the coordinates of shear center w.r.t centroid + numData = 2; + if (OPS_GetDoubleInput(&numData, &dData2[0]) < 0) { + opserr << "WARNING: invalid ys and zs\n"; + return 0; + } + } else { + opserr << "WARNING unknown option " << sData << "\n"; + } + } + + // 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 MixedBeamColumnAsym3d(eleTag, nodeI, nodeJ, numIntgrPts, sections, *beamIntegr, *theTransf, + dData2[0], dData2[1], massDens, doRayleigh, geomLinear); + + if (theElement == 0) { + opserr << "WARNING ran out of memory creating element with tag " << eleTag << endln; + return 0; + } + + delete[] sections; + if (beamIntegr != 0) + delete beamIntegr; + + return theElement; +} + + +// constructor which takes the unique element tag, sections, +// and the node ID's of it's nodal end points. +// allocates the necessary space needed by each object +MixedBeamColumnAsym3d::MixedBeamColumnAsym3d (int tag, int nodeI, int nodeJ, int numSec, + SectionForceDeformation **sec, + BeamIntegration &bi, + CrdTransf &coordTransf, double yss, double zss, + double massDensPerUnitLength, + int damp, bool geomLin): + Element(tag,ELE_TAG_MixedBeamColumnAsym3d), + connectedExternalNodes(2), beamIntegr(0), numSections(0), sections(0), + crdTransf(0), doRayleigh(damp), geomLinear(geomLin), + rho(massDensPerUnitLength), initialLength(0.0), + itr(0), initialFlag(0), + V(NGF), committedV(NGF), + internalForce(NEBD), committedInternalForce(NEBD), + naturalForce(NGF), commitedNaturalForce(NGF), + lastNaturalDisp(NEBD), commitedLastNaturalDisp(NEBD), + sp(0), + Hinv(NGF,NGF), commitedHinv(NGF,NGF), + GMH(NGF,NEBD), commitedGMH(NGF,NEBD), + kv(NEBD,NEBD), kvcommit(NEBD,NEBD), + Ki(0), + sectionForceFibers(0), commitedSectionForceFibers(0), + sectionDefFibers(0), commitedSectionDefFibers(0), + sectionFlexibility(0), commitedSectionFlexibility(0), sectionForceShapeFcn(0), ys(yss), zs(zss) +{ + theNodes[0] = 0; + theNodes[1] = 0; + + connectedExternalNodes(0) = nodeI; + connectedExternalNodes(1) = nodeJ; + + // get copy of the beam integration object + beamIntegr = bi.getCopy(); + if (beamIntegr == 0) { + opserr<<"Error: MixedBeamColumnAsym3d::MixedBeamColumnAsym3d: could not create copy of beam integration object" << endln; + exit(-1); + } + + // get copy of the transformation object + crdTransf = coordTransf.getCopy3d(); + if (crdTransf == 0) { + opserr << "Error: MixedBeamColumnAsym3d::MixedBeamColumnAsym3d: could not create copy of coordinate transformation object" << endln; + exit(-1); + } + + + //this->setSectionPointers(numSec,sec); + if (numSec > maxNumSections) { + opserr << "Error: MixedBeamColumnAsym3d::setSectionPointers -- max number of sections exceeded"; + } + + numSections = numSec; + + if (sec == 0) { + opserr << "Error: MixedBeamColumnAsym3d::setSectionPointers -- invalid section pointer"; + } + + sections = new SectionForceDeformation *[numSections]; + if (sections == 0) { + opserr << "Error: MixedBeamColumnAsym3d::setSectionPointers -- could not allocate section pointers"; + } + + for (int i = 0; i < numSections; i++) { + if (sec[i] == 0) { + opserr << "Error: MixedBeamColumnAsym3d::setSectionPointers -- null section pointer " << i << endln; + } + + sections[i] = (SectionForceDeformation*) sec[i]->getCopy(); + + if (sections[i] == 0) { + opserr << "Error: MixedBeamColumnAsym3d::setSectionPointers -- could not create copy of section " << i << endln; + } + } + + p0[0] = 0.0; + p0[1] = 0.0; + p0[2] = 0.0; + p0[3] = 0.0; + p0[4] = 0.0; + + // Element vectors and matrices + sectionForceFibers = new Vector [numSections]; + commitedSectionForceFibers = new Vector [numSections]; + sectionDefFibers = new Vector [numSections]; + commitedSectionDefFibers = new Vector [numSections]; + sectionFlexibility = new Matrix [numSections]; + commitedSectionFlexibility = new Matrix [numSections]; + + for (int i = 0; i < numSections; i++){ + sectionForceFibers[i] = Vector(NSD); + sectionForceFibers[i].Zero(); + commitedSectionForceFibers[i] = Vector(NSD); + commitedSectionForceFibers[i].Zero(); + sectionDefFibers[i] = Vector(NSD); + sectionDefFibers[i].Zero(); + commitedSectionDefFibers[i] = Vector(NSD); + commitedSectionDefFibers[i].Zero(); + sectionFlexibility[i] = Matrix(NSD,NSD); + sectionFlexibility[i].Zero(); + commitedSectionFlexibility[i] = Matrix(NSD,NSD); + commitedSectionFlexibility[i].Zero(); + } + + V.Zero(); + internalForce.Zero(); + naturalForce.Zero(); + lastNaturalDisp.Zero(); + Hinv.Zero(); + GMH.Zero(); + kv.Zero(); + + committedV.Zero(); + committedInternalForce.Zero(); + commitedNaturalForce.Zero(); + commitedLastNaturalDisp.Zero(); + commitedHinv.Zero(); + commitedGMH.Zero(); + kvcommit.Zero(); + + if (sectionDefShapeFcn == 0) + sectionDefShapeFcn = new Vector [maxNumSections]; + if (nldhat == 0) + nldhat = new Matrix [maxNumSections]; + if (nd1 == 0) + nd1 = new Matrix [maxNumSections]; + if (nd2 == 0) + nd2 = new Matrix [maxNumSections]; + if (nd1T == 0) + nd1T = new Matrix [maxNumSections]; + if (nd2T == 0) + nd2T = new Matrix [maxNumSections]; + if (!sectionDefShapeFcn || !nldhat || !nd1 || !nd2 || !nd1T || !nd2T ) { + opserr << "MixedBeamColumnAsym3d::MixedBeamColumnAsym3d() -- failed to allocate static section arrays"; + exit(-1); + } + + int i; + for ( i=0; igetNode(Nd1); + theNodes[1] = theDomain->getNode(Nd2); + + if (theNodes[0] == 0) { + opserr << "MixedBeamColumnAsym3d::setDomain: Nd1: "; + opserr << Nd1 << "does not exist in model\n"; + exit(0); + } + + if (theNodes[1] == 0) { + opserr << "MixedBeamColumnAsym3d::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 << "MixedBeamColumnAsym3d::setDomain(): Nd2 or Nd1 incorrect dof "; + exit(0); + } + + // initialize the transformation + if (crdTransf->initialize(theNodes[0], theNodes[1])) { + opserr << "MixedBeamColumnAsym3d::setDomain(): Error initializing coordinate transformation"; + exit(0); + } + + // Check element length + if (crdTransf->getInitialLength() == 0.0) { + opserr << "MixedBeamColumnAsym3d::setDomain(): Zero element length:" << this->getTag(); + exit(0); + } + +} + +int MixedBeamColumnAsym3d::commitState() { + int err = 0; // error flag + int i = 0; // integer for loops + + // call element commitState to do any base class stuff + if ((err = this->Element::commitState()) != 0) { + opserr << "MixedBeamColumnAsym3d::commitState () - failed in base class"; + return err; + } + + // commit the sections + do { + 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 + committedV = V; + committedInternalForce = internalForce; + commitedNaturalForce = naturalForce; + commitedLastNaturalDisp = lastNaturalDisp; + commitedHinv = Hinv; + commitedGMH = GMH; + kvcommit = kv; + for( i = 0; i < numSections; i++){ + commitedSectionForceFibers[i] = sectionForceFibers[i]; + commitedSectionDefFibers[i] = sectionDefFibers[i]; + commitedSectionFlexibility[i] = sectionFlexibility[i]; + } + + // Reset iteration counter + itr = 0; + + return err; +} + + +int MixedBeamColumnAsym3d::revertToLastCommit() { + int err; + int i = 0; + + do { + err = sections[i]->revertToLastCommit(); + 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 + V = committedV; + internalForce = committedInternalForce; + naturalForce = commitedNaturalForce; + lastNaturalDisp = commitedLastNaturalDisp; + Hinv = commitedHinv; + GMH = commitedGMH; + kv = kvcommit; + for( i = 0; i < numSections; i++){ + sectionForceFibers[i] = commitedSectionForceFibers[i]; + sectionDefFibers[i] = commitedSectionDefFibers[i]; + sectionFlexibility[i] = commitedSectionFlexibility[i]; + } + + // Reset iteration counter + itr = 0; + + return err; +} + + +int MixedBeamColumnAsym3d::revertToStart() +{ + int err; + int i; // for loops + i = 0; + + // revert the sections state to start + do { + 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 + + // Set initial length + initialLength = crdTransf->getInitialLength(); + + // Get the numerical integration weights + double wt[maxNumSections]; // weights of sections or gauss points of integration points + beamIntegr->getSectionWeights(numSections, initialLength, wt); + + // Vector of zeros to use at initial natural displacements + Vector myZeros(NEBD); + myZeros.Zero(); + + // Set initial shape functions + for ( i = 0; i < numSections; i++ ){ + nldhat[i] = this->getNld_hat(i, myZeros, initialLength, geomLinear); //Xinlong: This need to be modified to consider Nldhat1 and Nldhat2 + nd1[i] = this->getNd1(i, myZeros, initialLength, geomLinear); + nd2[i] = this->getNd2(i, 0.0, initialLength); + nd1T[i].addMatrixTranspose(0.0, nd1[i], 1.0); //Xinlong: nd1T=nd1T*0.0+nd1'*1.0 + nd2T[i].addMatrixTranspose(0.0, nd2[i], 1.0); + } + + // Set initial and committed section flexibility and GJ + Matrix ks(NSD,NSD); + //double GJ; + for ( i = 0; i < numSections; i++ ){ + //getSectionTangent(i,2,ks,GJ); + ks = sections[i]->getInitialTangent(); + invertMatrix(NSD,ks,sectionFlexibility[i]); + commitedSectionFlexibility[i] = sectionFlexibility[i]; + } + + // Set initial and committed section forces and deformations + for ( i = 0; i < numSections; i++ ){ + sectionForceFibers[i].Zero(); + commitedSectionForceFibers[i].Zero(); + sectionDefFibers[i].Zero(); + commitedSectionDefFibers[i].Zero(); + } + + // Compute the following matrices: G, G2, H, H12, H22, Md, Kg + Matrix G(NGF,NEBD); + Matrix G2(NEBD,NEBD); + Matrix H(NGF,NGF); + Matrix H12(NGF,NEBD); + Matrix H22(NEBD,NEBD); + Matrix Md(NGF,NEBD); + Matrix Kg(NEBD,NEBD); + + G.Zero(); + G2.Zero(); + H.Zero(); + H12.Zero(); + H22.Zero(); + Md.Zero(); + Kg.Zero(); + for( i = 0; i < numSections; i++ ){ + G = G + initialLength * wt[i] * nd1T[i] * nldhat[i]; + G2 = G2 + initialLength * wt[i] * nd2T[i] * nldhat[i]; + H = H + initialLength * wt[i] * nd1T[i] * sectionFlexibility[i] * nd1[i]; + H12 = H12 + initialLength * wt[i] * nd1T[i] * sectionFlexibility[i] * nd2[i]; + H22 = H22 + initialLength * wt[i] * nd2T[i] * sectionFlexibility[i] * nd2[i]; + // Md is zero since deformations are zero + //Kg = Kg + initialLength * wt[i] * this->getKg(i, 0, initialLength); //This isn't necessary. If P=0.0, Kg is zero. Need to verify if P=0.0 + } + + // Compute the inverse of the H matrix + invertMatrix(NGF, H, Hinv); + commitedHinv = Hinv; + + // Compute the GMH matrix ( G + Md - H12 ) and its transpose + GMH = G + Md - H12; + //GMH = G; // Omit P-small delta + commitedGMH = GMH; + + // Compute the transposes of the following matrices: G2, GMH + Matrix G2T(NEBD,NEBD); + Matrix GMHT(NEBD,NGF); + G2T.addMatrixTranspose(0.0, G2, 1.0); //Xinlong: G2T=G2T*0.0+G2'*1.0 + GMHT.addMatrixTranspose(0.0, GMH, 1.0); + /* + // Compute the stiffness matrix without the torsion term + Matrix K_temp_noT(NDM_NATURAL,NDM_NATURAL); + K_temp_noT = ( Kg + G2 + G2T - H22 ) + GMHT * Hinv * GMH; + //K_temp_noT = ( Kg ) + GMHT * Hinv * GMH; // Omit P-small delta + + // Add in the torsional stiffness term + kv.Zero(); + for( i = 0; i < NDM_NATURAL; i++ ) { + for( j = 0; j < NDM_NATURAL; j++ ) { + kv(i,j) = K_temp_noT(i,j); + } + } + + kv(5,5) = GJ/initialLength; // Torsional Stiffness GJ/L + */ + kv.Zero(); + kv = (Kg + G2 + G2T - H22) + GMHT * Hinv * GMH; + kvcommit = kv; + + //Matrix kvOpenSees = transformNaturalCoordsT*kv*transformNaturalCoords; + Matrix Tr(NEBD, NEBD); //transformation matrix from element basic system to basic reference system + Matrix kr(NEBD, NEBD); //stiffness matrix in the element basic reference system + Tr.Zero(); + kr.Zero(); + + Tr(0, 0) = 1.0; + Tr(1, 1) = 1.0; + Tr(2, 2) = 1.0; + Tr(3, 3) = 1.0; + Tr(4, 4) = 1.0; + Tr(5, 5) = 1.0; + Tr(0, 1) = -ys; + Tr(0, 2) = ys; + Tr(0, 3) = zs; + Tr(0, 4) = -zs; + //perform transformation - transform axial force form centroid to shear center + kr.addMatrixTripleProduct(0.0, Tr, kv, 1.0); + + Ki = new Matrix(crdTransf->getInitialGlobalStiffMatrix(kr)); + + // Vector V is zero at initial state + V.Zero(); + committedV.Zero(); + + // Internal force is zero at initial state + internalForce.Zero(); + committedInternalForce.Zero(); + naturalForce.Zero(); + commitedNaturalForce.Zero(); + + // Last natural displacement is zero at initial state + lastNaturalDisp.Zero(); + commitedLastNaturalDisp.Zero(); + + // Reset iteration counter + itr = 0; + + // Set initialFlag to 1 so update doesn't call again + initialFlag = 1; + + return err; +} + +const Matrix & MixedBeamColumnAsym3d::getInitialStiff(void) { + // If things haven't be initialized, then do so + if (initialFlag == 0) { + this->revertToStart(); + } + return *Ki; +} + +const Matrix & MixedBeamColumnAsym3d::getTangentStiff(void) { + // If things haven't be initialized, then do so + if (initialFlag == 0) { + this->revertToStart(); + } + crdTransf->update(); // Will remove once we clean up the corotational 3d transformation -- MHS + //Matrix ktOpenSees = transformNaturalCoordsT*kv*transformNaturalCoords; + + Matrix Tr(NEBD, NEBD); //transformation matrix from element basic system to basic reference system + Matrix kr(NEBD, NEBD); //stiffness matrix in the element basic reference system + Tr.Zero(); + kr.Zero(); + + Tr(0, 0) = 1.0; + Tr(1, 1) = 1.0; + Tr(2, 2) = 1.0; + Tr(3, 3) = 1.0; + Tr(4, 4) = 1.0; + Tr(5, 5) = 1.0; + Tr(0, 1) = -ys; + Tr(0, 2) = ys; + Tr(0, 3) = zs; + Tr(0, 4) = -zs; + + //perform transformation on stiffness matrix - transform axial force form centroid to shear center + kr.addMatrixTripleProduct(0.0, Tr, kv, 1.0); + + //perform transformation on internal force vector + Vector Pr(NEBD); + Pr.Zero(); + Pr.addMatrixTransposeVector(0.0, Tr, internalForce, 1.0); //compared with dispBeamColumn, we don't consider element load here. + + return crdTransf->getGlobalStiffMatrix(kr,Pr); +} + +const Vector & MixedBeamColumnAsym3d::getResistingForce(void) { + crdTransf->update(); // Will remove once we clean up the corotational 3d transformation -- MHS + + Matrix Tr(NEBD, NEBD); //transformation matrix from element basic system to basic reference system + Tr.Zero(); + + Tr(0, 0) = 1.0; + Tr(1, 1) = 1.0; + Tr(2, 2) = 1.0; + Tr(3, 3) = 1.0; + Tr(4, 4) = 1.0; + Tr(5, 5) = 1.0; + Tr(0, 1) = -ys; + Tr(0, 2) = ys; + Tr(0, 3) = zs; + Tr(0, 4) = -zs; + + //perform transformation on internal force vector + Vector Pr(NEBD); + Pr.Zero(); + Pr.addMatrixTransposeVector(0.0, Tr, internalForce, 1.0); //compared with dispBeamColumn, we don't consider element load here. + + Vector p0Vec(p0, 5); + return crdTransf->getGlobalResistingForce(Pr, p0Vec); +} + +int MixedBeamColumnAsym3d::update() { + + // If things haven't be initialized, then do so + if (initialFlag == 0) { + this->revertToStart(); + } + + int i, j; // integers for loops + + // Update iteration counter + // says how many times update has been called since the last commit state + itr++; + + // Update Coordinate Transformation + crdTransf->update(); + + // Current Length + double currentLength; + if (geomLinear) { + currentLength = initialLength; + } else { + currentLength = initialLength; //Xinlong: need to be cleaned later on. Since we use Total Lagrangian, we should do integration on initial length. + } + + // Compute the natural displacements + Vector naturalDisp = crdTransf->getBasicTrialDisp(); + //naturalDispWithTorsion = transformNaturalCoords*naturalDispWithTorsion; + // convert to the arrangement of natural deformations that the element likes + /* + Vector naturalDisp(NDM_NATURAL); + for ( i = 0; i < NDM_NATURAL; i++ ) { + naturalDisp(i) = naturalDispWithTorsion(i); //all but the torsional component + } + double twist = naturalDispWithTorsion(5); + */ + Vector naturalIncrDeltaDisp(NEBD); + naturalIncrDeltaDisp = naturalDisp - lastNaturalDisp; + lastNaturalDisp = naturalDisp; + + // Get the numerical integration weights + double wt[maxNumSections]; // weights of sections or gauss points of integration points + beamIntegr->getSectionWeights(numSections, initialLength, wt); + + // Define Variables + //double GJ; + //double torsionalForce; + //Vector sectionForceShapeFcn[numSections]; + sectionForceShapeFcn = new Vector[numSections]; + for ( i = 0; i < numSections; i++ ) { + sectionForceShapeFcn[i] = Vector(NSD); + } + + // Compute shape functions and their transposes + for ( i = 0; i < numSections; i++ ){ + // Shape Functions + nldhat[i] = this->getNld_hat(i, naturalDisp, currentLength, geomLinear); + sectionDefShapeFcn[i] = this->getd_hat(i, naturalDisp, currentLength, geomLinear); + nd1[i] = this->getNd1(i, naturalDisp, currentLength, geomLinear); + if (geomLinear) { + nd2[i].Zero(); + } else { + nd2[i] = this->getNd2(i, internalForce(0), currentLength); //Xinlong: Shall we use naturalForce(0) instead of internalForce(0) here? + } + + // Transpose of shape functions + nd1T[i].addMatrixTranspose(0.0, nd1[i], 1.0); //Xinlong: nd1T=nd1T*0.0+nd1'*1.0 + nd2T[i].addMatrixTranspose(0.0, nd2[i], 1.0); + } + + // Update natural force + if (geomLinear) { + naturalForce = naturalForce + Hinv * ( GMH * naturalIncrDeltaDisp + V ); + } else { + naturalForce = naturalForce + Hinv * ( GMH * naturalIncrDeltaDisp + V ); + } + + + // Update sections + for ( i = 0; i < numSections; i++){ + // Compute section deformations + sectionForceShapeFcn[i] = nd1[i] * naturalForce; + if (sp != 0) { + const Matrix &s_p = *sp; + for ( j = 0; j < NSD; j++ ) { + sectionForceShapeFcn[i](j) += s_p(j,i); + } + } + sectionDefFibers[i] = sectionDefFibers[i] + sectionFlexibility[i] * ( sectionForceShapeFcn[i] - sectionForceFibers[i] ); + + // Send section deformation to section object + //double torsionalStrain = twist/currentLength; + //setSectionDeformation(i,sectionDefFibers[i],torsionalStrain); + if (sections[i]->setTrialSectionDeformation(sectionDefFibers[i]) < 0) { + opserr << "MixedBeamColumnAsym3d::update() - section failed in setTrial\n"; + return -1; + } + + // Get section force vector + //double tempTorsionalForce; + //getSectionStress(i,sectionForceFibers[i],tempTorsionalForce); + //if (i == 0) { + // torsionalForce = tempTorsionalForce; + //} + sectionForceFibers[i] = sections[i]->getStressResultant(); + + // Get section tangent matrix + Matrix ks(NSD,NSD); + //getSectionTangent(i,1,ks,GJ); + ks = sections[i]->getSectionTangent(); + + // Compute section flexibility matrix + invertMatrix(NSD,ks,sectionFlexibility[i]); + } + + // Compute the following matrices: V, V2, G, G2, H, H12, H22, Md, Kg + Vector V2(NEBD); + Matrix G(NGF,NEBD); + Matrix G2(NEBD,NEBD); + Matrix H(NGF,NGF); + Matrix H12(NGF,NEBD); + Matrix H22(NEBD,NEBD); + Matrix Md(NGF,NEBD); + Matrix Kg(NEBD,NEBD); + + V.Zero(); + V2.Zero(); + G.Zero(); + G2.Zero(); + H.Zero(); + H12.Zero(); + H22.Zero(); + Md.Zero(); + Kg.Zero(); + + for( i = 0; i < numSections; i++ ){ + V = V + initialLength * wt[i] * nd1T[i] * (sectionDefShapeFcn[i] - sectionDefFibers[i] - sectionFlexibility[i] * ( sectionForceShapeFcn[i] - sectionForceFibers[i] ) ); + //for V, see my comments on Denavit's paper. Also need to be verified with Nukala and Alemdar's papers. + V2 = V2 + initialLength * wt[i] * nd2T[i] * (sectionDefShapeFcn[i] - sectionDefFibers[i]); + G = G + initialLength * wt[i] * nd1T[i] * nldhat[i]; + G2 = G2 + initialLength * wt[i] * nd2T[i] * nldhat[i]; + H = H + initialLength * wt[i] * nd1T[i] * sectionFlexibility[i] * nd1[i]; + H12 = H12 + initialLength * wt[i] * nd1T[i] * sectionFlexibility[i] * nd2[i]; + H22 = H22 + initialLength * wt[i] * nd2T[i] * sectionFlexibility[i] * nd2[i]; + if (!geomLinear) { + Kg = Kg + initialLength * wt[i] * this->getKg(i, sectionForceFibers[i], currentLength); + // sectionForceFibers[i](0) is the axial load, P. Or shall we use sectionForceShapeFcn[i] here? + Md = Md + initialLength * wt[i] * this->getMd(i, sectionDefShapeFcn[i], sectionDefFibers[i], currentLength); + } + } + + // Compute the inverse of the H matrix + invertMatrix(NGF, H, Hinv); + + // Compute the GMH matrix ( G + Md - H12 ) and its transpose + GMH = G + Md - H12; + //GMH = G; // Omit P-small delta + + // Compute the transposes of the following matrices: G, G2, GMH + Matrix GT(NEBD,NGF); + Matrix G2T(NEBD,NEBD); + Matrix GMHT(NEBD,NGF); + GT.addMatrixTranspose(0.0, G, 1.0); + G2T.addMatrixTranspose(0.0, G2, 1.0); //Xinlong: G2T=G2T*0.0+G2'*1.0 + GMHT.addMatrixTranspose(0.0, GMH, 1.0); + + // Compute new internal force + //Vector internalForce(NEBD); + //internalForce.Zero(); + + if (geomLinear) { + internalForce = GT * naturalForce + V2 + GMHT * Hinv * V; + } else { + internalForce = GT * naturalForce + V2 + GMHT * Hinv * V; + } + /* + // Compute internal force for OpenSees ( i.e., add torsion and rearrange ) + for ( i = 0; i < NDM_NATURAL; i++ ) { + internalForceOpenSees(i) = internalForce(i); + } + internalForceOpenSees(5) = torsionalForce; // Add in torsional force + internalForceOpenSees = transformNaturalCoordsT*internalForceOpenSees; + + // Compute the stiffness matrix without the torsion term + Matrix K_temp(NDM_NATURAL,NDM_NATURAL); + if (geomLinear) { + K_temp = ( Kg + G2 + G2T - H22 ) + GMHT * Hinv * GMH; + } else { + K_temp = ( Kg + G2 + G2T - H22 ) + GMHT * Hinv * GMH; + } + + // Add in the torsional stiffness term + kv.Zero(); + for( i = 0; i < NDM_NATURAL; i++ ) { + for( j = 0; j< NDM_NATURAL; j++ ) { + kv(i,j) = K_temp(i,j); + } + } + + kv(5,5) = GJ/currentLength; // Torsional Stiffness GJ/L + */ + kv.Zero(); + if (geomLinear) { + kv = (Kg + G2 + G2T - H22) + GMHT * Hinv * GMH; + } + else { + kv = (Kg + G2 + G2T - H22) + GMHT * Hinv * GMH; + } + + return 0; +} + +const Matrix & MixedBeamColumnAsym3d::getMass(void) { + theMatrix.Zero(); + + if (rho != 0.0) { + theMatrix(0,0) = theMatrix(1,1) = theMatrix(2,2) = + theMatrix(6,6) = theMatrix(7,7) = theMatrix(8,8) = 0.5*initialLength*rho; + } + + return theMatrix; +} + +const Matrix & MixedBeamColumnAsym3d::getDamp(void) { + theMatrix.Zero(); + + // Add the damping forces + if ( doRayleigh == 1 && (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) ) { + theMatrix = this->Element::getDamp(); + } + + return theMatrix; +} + +void MixedBeamColumnAsym3d::zeroLoad(void) { + if (sp != 0) + sp->Zero(); + + p0[0] = 0.0; + p0[1] = 0.0; + p0[2] = 0.0; + p0[3] = 0.0; + p0[4] = 0.0; +} + +int MixedBeamColumnAsym3d::addLoad(ElementalLoad *theLoad, double loadFactor) { + + int type; + const Vector &data = theLoad->getData(type, loadFactor); + + if (sp == 0) { + sp = new Matrix(NSD,numSections); + if (sp == 0) { + opserr << "MixedBeamColumnAsym3d::addLoad -- out of memory\n"; + exit(-1); + } + } + + double L = crdTransf->getInitialLength(); + + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + if (type == LOAD_TAG_Beam3dUniformLoad) { + double wy = data(0)*loadFactor; // Transverse + double wz = data(1)*loadFactor; // Transverse + double wx = data(2)*loadFactor; // Axial + + Matrix &s_p = *sp; + + // Accumulate applied section forces due to element loads + for (int i = 0; i < numSections; i++) { + double x = xi[i]*L; + // Axial + s_p(0,i) += wx*(L-x); + // Moment + s_p(1,i) += wy*0.5*x*(x-L); + // Moment + s_p(2,i) += wz*0.5*x*(L-x); + } + + // Accumulate reactions in basic system + p0[0] -= wx*L; + double V; + 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_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 Vy2 = Py*aOverL; + double Vy1 = Py-Vy2; + + double Vz2 = Pz*aOverL; + double Vz1 = Pz-Vz2; + + Matrix &s_p = *sp; + + // Accumulate applied section forces due to element loads + for (int i = 0; i < numSections; i++) { + double x = xi[i]*L; + if (x <= a) { + s_p(0,i) += N; + s_p(1,i) -= x*Vy1; + s_p(2,i) += x*Vz1; + } + else { + s_p(1,i) -= (L-x)*Vy2; + s_p(2,i) += (L-x)*Vz2; + } + } + + // Accumulate reactions in basic system + p0[0] -= N; + p0[1] -= Vy1; + p0[2] -= Vy2; + p0[3] -= Vz1; + p0[4] -= Vz2; + + + } else { + opserr << "MixedBeamColumnAsym3d::addLoad() -- load type unknown for element with tag: " << + this->getTag() << endln; + + return -1; + } + + return 0; +} + +const Vector & MixedBeamColumnAsym3d::getResistingForceIncInertia() { + + // Compute the current resisting force + theVector = this->getResistingForce(); + + // Add the inertial forces + 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 ( doRayleigh == 1 && (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) ) { + theVector += this->getRayleighDampingForces(); + } + + return theVector; +} + + +void MixedBeamColumnAsym3d::Print(OPS_Stream &s, int flag) { + + if (flag == 1) { + s << "\nElement: " << this->getTag() << " Type: MixedBeamColumnAsym3d "; + s << "\tConnected Nodes: " << connectedExternalNodes ; + s << "\tNumber of Sections: " << numSections; + s << "\tMass density: " << rho; + for (int i = 0; i < numSections; i++) + s << "\nSection "<getTag() << " Type: MixedBeamColumnAsym3d "; + double xi[maxNumSections]; // location of sections or gauss points or integration points + beamIntegr->getSectionLocations(numSections, initialLength, xi); + double wt[maxNumSections]; // weights of sections or gauss points of integration points + beamIntegr->getSectionWeights(numSections, initialLength, wt); + s << "\n section xi wt"; + for (int i = 0; i < numSections; i++) + s << "\n"<getTag() << ", "; + s << "\"type\": \"mixedBeamColumn2d\", "; + 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() << "\""; + if (!doRayleigh) + s << ", \"doRayleigh\": false"; + if (geomLinear) + s << ", \"geomLinear\": true"; + s << "}"; + + } else { + s << "\nElement: " << this->getTag() << " Type: MixedBeamColumnAsym3d "; + s << "\tConnected Nodes: " << connectedExternalNodes ; + s << "\tNumber of Sections: " << numSections; + s << "\tMass density: " << rho << endln; + } + +} + + +OPS_Stream &operator<<(OPS_Stream &s, MixedBeamColumnAsym3d &E) { + E.Print(s); + return s; +} + + +Response* MixedBeamColumnAsym3d::setResponse(const char **argv, int argc, + OPS_Stream &output) { + + Response *theResponse = 0; + + output.tag("ElementOutput"); + output.attr("eleType","MixedBeamColumnAsym3d"); + 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, theVector); + + // 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","Tz_1"); + output.tag("ResponseType","N_2"); + output.tag("ResponseType","Py_2"); + output.tag("ResponseType","Pz_2"); + output.tag("ResponseType","T_2"); + output.tag("ResponseType","My_2"); + output.tag("ResponseType","Mz_2"); + + theResponse = new ElementResponse(this, 2, theVector); + + // basic or natural forces + } else if (strcmp(argv[0],"basicForce") == 0 || + strcmp(argv[0],"basicForces") == 0) { + + output.tag("ResponseType","N"); + output.tag("ResponseType","Mz_1"); + output.tag("ResponseType","Mz_2"); + output.tag("ResponseType","My_1"); + output.tag("ResponseType","My_2"); + output.tag("ResponseType","T"); + + theResponse = new ElementResponse(this, 3, Vector(6)); + } else if (strcmp(argv[0],"sectionDeformation_Force") == 0) { + + int i; + char *q = new char[15]; + for ( i = 0; i < numSections; i++ ){ + sprintf(q,"axialStrain_%i",i+1); + output.tag("ResponseType",q); + sprintf(q,"curvatureZ_%i",i+1); + output.tag("ResponseType",q); + sprintf(q,"curvatureY_%i",i+1); + output.tag("ResponseType",q); + } + delete [] q; + + theResponse = new ElementResponse(this, 4, Vector(3*numSections)); + + } else if (strcmp(argv[0],"plasticSectionDeformation_Force") == 0) { + + int i; + char *q = new char[25]; + for ( i = 0; i < numSections; i++ ){ + sprintf(q,"plasticAxialStrain_%i",i+1); + output.tag("ResponseType",q); + sprintf(q,"plasticCurvatureZ_%i",i+1); + output.tag("ResponseType",q); + sprintf(q,"plasticCurvatureY_%i",i+1); + output.tag("ResponseType",q); + } + delete [] q; + + theResponse = new ElementResponse(this, 5, Vector(3*numSections)); + + } else if (strcmp(argv[0],"integrationPoints") == 0) { + theResponse = new ElementResponse(this, 100, Vector(numSections)); + + } else if (strcmp(argv[0],"integrationWeights") == 0) { + theResponse = new ElementResponse(this, 101, Vector(numSections)); + + } else if (strcmp(argv[0],"sectionTags") == 0) { + theResponse = new ElementResponse(this, 110, ID(numSections)); + + } else if (strcmp(argv[0],"connectedNodes") == 0) { + theResponse = new ElementResponse(this, 102, Vector(2)); + + } else if (strcmp(argv[0],"numSections") == 0 || + strcmp(argv[0],"numberOfSections") == 0 ) { + theResponse = new ElementResponse(this, 103, Vector(1)); + + } else if (strcmp(argv[0],"section") ==0) { + if (argc > 2) { + + int sectionNum = atoi(argv[1]); + if (sectionNum > 0 && sectionNum <= numSections) { + + 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); + + theResponse = sections[sectionNum-1]->setResponse(&argv[2], argc-2, output); + + output.endTag(); + } + } + } + + output.endTag(); + return theResponse; +} + + +int MixedBeamColumnAsym3d::getResponse(int responseID, Information &eleInfo) { + if (responseID == 1) { // global forces + return eleInfo.setVector(this->getResistingForce()); + + } else if (responseID == 2) { // local forces + // Axial + double N = internalForce(0); + theVector(6) = N; + theVector(0) = -N+p0[0]; + + // Torsion + double T = internalForce(5); + theVector(9) = T; + theVector(3) = -T; + + // Moments about z and shears along y + double M1 = internalForce(1); + double M2 = internalForce(2); + theVector(5) = M1; + theVector(11) = M2; + double L = crdTransf->getInitialLength(); + double V = (M1+M2)/L; + theVector(1) = V+p0[1]; + theVector(7) = -V+p0[2]; + + // Moments about y and shears along z + M1 = internalForce(3); + M2 = internalForce(4); + theVector(4) = M1; + theVector(10) = M2; + V = -(M1+M2)/L; + theVector(2) = -V+p0[3]; + theVector(8) = V+p0[4]; + + return eleInfo.setVector(theVector); + + } else if (responseID == 3) { // basic forces + return eleInfo.setVector(internalForce); + + } else if (responseID == 4) { // section deformation (from forces) + + int i; + Vector tempVector(3*numSections); + tempVector.Zero(); + for ( i = 0; i < numSections; i++ ){ + tempVector(3*i) = sectionDefFibers[i](0); + tempVector(3*i+1) = sectionDefFibers[i](1); + tempVector(3*i+2) = sectionDefFibers[i](2); + } + + return eleInfo.setVector(tempVector); + + } else if (responseID == 5) { // plastic section deformation (from forces) + + int i; + Vector tempVector(3*numSections); + Vector sectionForce(NSD); + Vector plasticSectionDef(NSD); + Matrix ks(NSD,NSD); + Matrix fs(NSD,NSD); + tempVector.Zero(); + double scratch = 0.0; + for ( i = 0; i < numSections; i++ ){ + sectionForce = sections[i]->getStressResultant(); + ks = sections[i]->getInitialTangent(); + invertMatrix(NSD,ks,fs); + + plasticSectionDef = sectionDefFibers[i] - fs*sectionForce; + + tempVector(3*i) = plasticSectionDef(0); + tempVector(3*i+1) = plasticSectionDef(1); + tempVector(3*i+2) = plasticSectionDef(2); + } + + return eleInfo.setVector(tempVector); + + } else if (responseID == 100) { // integration points + + 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 == 101) { // integration weights + 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 == 110) { + ID tags(numSections); + for (int i = 0; i < numSections; i++) + tags(i) = sections[i]->getTag(); + return eleInfo.setID(tags); + + } else if (responseID == 102) { // connected nodes + Vector tempVector(2); + tempVector(0) = connectedExternalNodes(0); + tempVector(1) = connectedExternalNodes(1); + return eleInfo.setVector(tempVector); + + } else if (responseID == 103) { // number of sections + Vector tempVector(1); + tempVector(0) = numSections; + return eleInfo.setVector(tempVector); + + } else { + return -1; + + } +} + +Vector MixedBeamColumnAsym3d::getd_hat(int sec, const Vector &v, double L, bool geomLinear) { + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + Vector D_hat(NSD); + D_hat.Zero(); + + double oneOverL = 1.0 / L; + double xi1 = xi[sec]; + double dNv1 = 1.0 + 3.0*xi1*xi1 - 4.0*xi1; + double ddNv1 = 6.0*xi1*oneOverL - 4.0*oneOverL; + double dNv2 = 3.0*xi1*xi1 - 2.0*xi1; + double ddNv2 = 6.0*xi1*oneOverL - 2.0*oneOverL; + double dNw1 = -dNv1; + double ddNw1 = -ddNv1; + double dNw2 = -dNv2; + double ddNw2 = -ddNv2; + double Nf1 = xi1; + + double e0 = oneOverL * v(0); //u' + double e1 = ddNv1 * v(1) + ddNv2 * v(2); //v" + double e2 = ddNw1 * v(3) + ddNw2 * v(4); //w" + double e3 = oneOverL * v(5); //phi' + double e4 = dNv1 * v(1) + dNv2 * v(2); //v' + double e5 = dNw1 * v(3) + dNw2 * v(4); //w' + double e6 = Nf1 * v(5); //phi + + if (geomLinear) { + D_hat(0) = e0; + D_hat(1) = e1; + D_hat(2) = -e2; + } else { + D_hat(0) = e0 + 0.5*(e4*e4 + e5 * e5) + (zs*e4 - ys * e5)*e3; + D_hat(1) = e1 + e2 * e6; + D_hat(2) = -e2 + e1 * e6; + D_hat(3) = 0.5*e3*e3; + D_hat(4) = e3; + } + + return D_hat; +} + +Matrix MixedBeamColumnAsym3d::getKg(int sec, Vector P, double L) { + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + Matrix kg(NEBD,NEBD); + Matrix N2(NGF, NEBD); + Matrix Gmax(NGF, NGF); + kg.Zero(); + N2.Zero(); + Gmax.Zero(); + + double oneOverL = 1.0 / L; + double xi1 = xi[sec]; + double dNv1 = 1.0 + 3.0*xi1*xi1 - 4.0*xi1; + double ddNv1 = 6.0*xi1*oneOverL - 4.0*oneOverL; + double dNv2 = 3.0*xi1*xi1 - 2.0*xi1; + double ddNv2 = 6.0*xi1*oneOverL - 2.0*oneOverL; + double dNw1 = -dNv1; + double ddNw1 = -ddNv1; + double dNw2 = -dNv2; + double ddNw2 = -ddNv2; + double Nf1 = xi1; + + //Matrix Ndeltad2------------------------------------------------------- + N2(0, 0) = oneOverL; + N2(1, 1) = dNv1; + N2(1, 2) = dNv2; + N2(2, 3) = dNw1; + N2(2, 4) = dNw2; + N2(3, 1) = ddNv1; + N2(3, 2) = ddNv2; + N2(4, 3) = ddNw1; + N2(4, 4) = ddNw2; + N2(5, 5) = Nf1; + N2(6, 5) = oneOverL; + + Gmax(1, 1) = Gmax(2, 2) = P(0); //N + Gmax(5, 4) = Gmax(4, 5) = P(1); //Mz + Gmax(5, 3) = Gmax(3, 5) = P(2); //My + Gmax(6, 1) = Gmax(1, 6) = P(0)*zs; //Nzs + Gmax(6, 2) = Gmax(2, 6) = -P(0)*ys; //-Nys + Gmax(6, 6) = P(3); //W + + kg.addMatrixTripleProduct(0.0, N2, Gmax, 1.0); + + return kg; +} + +Matrix MixedBeamColumnAsym3d::getMd(int sec, Vector dShapeFcn, Vector dFibers, double L) { + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + Matrix md(NGF,NEBD); + md.Zero(); + + double x = L * xi[sec]; + double Nv1 = x * (1 - x / L)*(1 - x / L); + double Nv2 = x * x / L * (x / L - 1); + double Nw1 = -Nv1; + double Nw2 = -Nv2; + + md(0,1) = Nv1 * ( dShapeFcn(1) - dFibers(1) ); + md(0,2) = Nv2 * ( dShapeFcn(1) - dFibers(1) ); + md(0,3) = -Nw1 * ( dShapeFcn(2) - dFibers(2) ); + md(0,4) = -Nw2 * ( dShapeFcn(2) - dFibers(2) ); + + return md; +} + +Matrix MixedBeamColumnAsym3d::getNld_hat(int sec, const Vector &v, double L, bool geomLinear) { + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + Matrix Nld_hat(NSD,NEBD); + Matrix N1(NSD, NGF); + Matrix N2(NGF, NEBD); + Nld_hat.Zero(); + N1.Zero(); + N2.Zero(); + + double oneOverL = 1.0 / L; + double xi1 = xi[sec]; + double dNv1 = 1.0 + 3.0*xi1*xi1 - 4.0*xi1; + double ddNv1 = 6.0*xi1*oneOverL - 4.0*oneOverL; + double dNv2 = 3.0*xi1*xi1 - 2.0*xi1; + double ddNv2 = 6.0*xi1*oneOverL - 2.0*oneOverL; + double dNw1 = -dNv1; + double ddNw1 = -ddNv1; + double dNw2 = -dNv2; + double ddNw2 = -ddNv2; + double Nf1 = xi1; + + double dv = dNv1 * v(1) + dNv2 * v(2); //v' + double ddv = ddNv1 * v(1) + ddNv2 * v(2); //v" + double dw = dNw1 * v(3) + dNw2 * v(4); //w' + double ddw = ddNw1 * v(3) + ddNw2 * v(4); //w" + double f = Nf1 * v(5); //phi + double df = oneOverL * v(5); //phi' + + if (geomLinear) { + //Matrix Ndeltad1------------------------------------------------------- + N1(0, 0) = 1.0; + N1(1, 3) = 1.0; + N1(2, 4) = -1.0; + } else { + //Matrix Ndeltad1------------------------------------------------------- + N1(0, 0) = 1.0; + N1(0, 1) = dv + zs * df; + N1(0, 2) = dw - ys * df; + N1(0, 6) = zs * dv - ys * dw; + N1(1, 3) = 1.0; + N1(1, 4) = f; + N1(1, 5) = ddw; + N1(2, 3) = f; + N1(2, 4) = -1.0; + N1(2, 5) = ddv; + N1(3, 6) = df; + N1(4, 6) = 1.0; + } + //Matrix Ndeltad2------------------------------------------------------- + N2(0, 0) = oneOverL; + N2(1, 1) = dNv1; + N2(1, 2) = dNv2; + N2(2, 3) = dNw1; + N2(2, 4) = dNw2; + N2(3, 1) = ddNv1; + N2(3, 2) = ddNv2; + N2(4, 3) = ddNw1; + N2(4, 4) = ddNw2; + N2(5, 5) = Nf1; + N2(6, 5) = oneOverL; + + Nld_hat.addMatrixProduct(0.0, N1, N2, 1.0); //N1*N2 + + return Nld_hat; +} + +Matrix MixedBeamColumnAsym3d::getNd2(int sec, double P, double L) { + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + Matrix Nd2(NSD,NEBD); + Nd2.Zero(); + + double x = L * xi[sec]; + double Nv1 = x * (1 - x / L)*(1 - x / L); + double Nv2 = x * x / L * (x / L - 1); + double Nw1 = -Nv1; + double Nw2 = -Nv2; + + Nd2(1, 1) = P * Nv1; + Nd2(1, 2) = P * Nv2; + Nd2(2, 3) = -P * Nw1; + Nd2(2, 4) = -P * Nw2; + + return Nd2; +} + +Matrix MixedBeamColumnAsym3d::getNd1(int sec, const Vector &v, double L, bool geomLinear) { + double xi[maxNumSections]; + beamIntegr->getSectionLocations(numSections, L, xi); + + Matrix Nd1(NSD,NGF); + Nd1.Zero(); + + double x = L * xi[sec]; + double Nv1 = x * (1 - x / L)*(1 - x / L); + double Nv2 = x * x / L * (x / L - 1); + double Nw1 = -Nv1; + double Nw2 = -Nv2; + + if (geomLinear) { + Nd1(0, 0) = 1.0; + Nd1(1, 1) = x / L - 1.0; + Nd1(1, 2) = x / L; + Nd1(2, 3) = x / L - 1.0; + Nd1(2, 4) = x / L; + Nd1(3, 6) = 1.0; + Nd1(4, 5) = 1.0; + } else { + Nd1(0, 0) = 1.0; + Nd1(1, 0) = Nv1 * v(1) + Nv2 * v(2); + Nd1(1, 1) = x / L - 1.0; + Nd1(1, 2) = x / L; + Nd1(2, 0) = -Nw1 * v(3) - Nw2 * v(4); + Nd1(2, 3) = x / L - 1.0; + Nd1(2, 4) = x / L; + Nd1(3, 6) = 1.0; + Nd1(4, 5) = 1.0; + } + + return Nd1; +} +/* +void MixedBeamColumnAsym3d::getSectionTangent(int sec,int type,Matrix &kSection, + double &GJ) { + int order = sections[sec]->getOrder(); + const ID &code = sections[sec]->getType(); + + // Initialize formulation friendly variables + kSection.Zero(); + GJ = 0.0; + + // Get the stress resultant from section + Matrix sectionTangent(order,order); + if ( type == 1 ) { + sectionTangent = sections[sec]->getSectionTangent(); + } else if ( type == 2 ) { + sectionTangent = sections[sec]->getInitialTangent(); + } else { + sectionTangent.Zero(); + } + + // Set Components of Section Tangent + int i,j; + for (i = 0; i < order; i++) { + for (j = 0; j < order; j++) { + switch(code(i)) { + case SECTION_RESPONSE_P: + switch(code(j)) { + case SECTION_RESPONSE_P: + kSection(0,0) = sectionTangent(i,j); + break; + case SECTION_RESPONSE_MZ: + kSection(0,1) = sectionTangent(i,j); + break; + case SECTION_RESPONSE_MY: + kSection(0,2) = sectionTangent(i,j); + break; + default: + break; + } + break; + case SECTION_RESPONSE_MZ: + switch(code(j)) { + case SECTION_RESPONSE_P: + kSection(1,0) = sectionTangent(i,j); + break; + case SECTION_RESPONSE_MZ: + kSection(1,1) = sectionTangent(i,j); + break; + case SECTION_RESPONSE_MY: + kSection(1,2) = sectionTangent(i,j); + break; + default: + break; + } + break; + case SECTION_RESPONSE_MY: + switch(code(j)) { + case SECTION_RESPONSE_P: + kSection(2,0) = sectionTangent(i,j); + break; + case SECTION_RESPONSE_MZ: + kSection(2,1) = sectionTangent(i,j); + break; + case SECTION_RESPONSE_MY: + kSection(2,2) = sectionTangent(i,j); + break; + default: + break; + } + break; + case SECTION_RESPONSE_T: + GJ = sectionTangent(i,i); + break; + default: + break; + } + } + } +} + +void MixedBeamColumnAsym3d::getSectionStress(int sec,Vector &fSection, + double &torsion) { + int order = sections[sec]->getOrder(); + const ID &code = sections[sec]->getType(); + + // Get the stress resultant from section + Vector stressResultant = sections[sec]->getStressResultant(); + + // Initialize formulation friendly variables + fSection.Zero(); + torsion = 0.0; + + // Set Components of Section Stress Resultant + int j; + for (j = 0; j < order; j++) { + switch(code(j)) { + case SECTION_RESPONSE_P: + fSection(0) = stressResultant(j); + break; + case SECTION_RESPONSE_MZ: + fSection(1) = stressResultant(j); + break; + case SECTION_RESPONSE_MY: + fSection(2) = stressResultant(j); + break; + case SECTION_RESPONSE_T: + torsion = stressResultant(j); + break; + default: + break; + } + } +} + +void MixedBeamColumnAsym3d::setSectionDeformation(int sec,Vector &defSection, + double &twist) { + int order = sections[sec]->getOrder(); + const ID &code = sections[sec]->getType(); + + // Initialize Section Deformation Vector + Vector sectionDeformation(order); + sectionDeformation.Zero(); + + // Set Components of Section Deformations + int j; + for (j = 0; j < order; j++) { + switch(code(j)) { + case SECTION_RESPONSE_P: + sectionDeformation(j) = defSection(0); + break; + case SECTION_RESPONSE_MZ: + sectionDeformation(j) = defSection(1); + break; + case SECTION_RESPONSE_MY: + sectionDeformation(j) = defSection(2); + break; + case SECTION_RESPONSE_T: + sectionDeformation(j) = twist; + break; + default: + break; + } + } + + // Set the section deformations + int res = sections[sec]->setTrialSectionDeformation(sectionDeformation); +} +*/ + +int MixedBeamColumnAsym3d::sendSelf(int commitTag, Channel &theChannel) { + // @todo write MixedBeamColumnAsym3d::sendSelf + opserr << "Error: MixedBeamColumnAsym3d::sendSelf -- not yet implemented for MixedBeamColumnAsym3d element"; + return -1; +} + +int MixedBeamColumnAsym3d::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) { + // @todo write MixedBeamColumnAsym3d::recvSelf + opserr << "Error: MixedBeamColumnAsym3d::sendSelf -- not yet implemented for MixedBeamColumnAsym3d element"; + return -1; +} diff --git a/SRC/element/mixedBeamColumn/MixedBeamColumnAsym3d.h b/SRC/element/mixedBeamColumn/MixedBeamColumnAsym3d.h new file mode 100644 index 000000000..641c491b7 --- /dev/null +++ b/SRC/element/mixedBeamColumn/MixedBeamColumnAsym3d.h @@ -0,0 +1,198 @@ +/* ****************************************************************** ** +** 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.1 $ +// $Date: 2010-05-04 17:14:46 $ +// $Source: /scratch/slocal/chroot/cvsroot/openseescomp/CompositePackages/MixedBeamColumnAsym3d/MixedBeamColumnAsym3d.h,v $ + +// Modified by: Xinlong Du and Jerome F. Hajjar, Northeastern University, USA; Year 2020 +// Description: Adapted for analysis of asymmetric sections with introducing +// high-order axial terms for the basic element formulation +// References: +// Du, X., & Hajjar, J. F. (2021). Three-dimensional nonlinear mixed 6-DOF beam element +// for thin-walled members. Thin-Walled Structures, 164, 107817. + +#ifndef MixedBeamColumnAsym3d_h +#define MixedBeamColumnAsym3d_h + +// Written: Mark D. Denavit, University of Illinois at Urbana-Champaign +// +// Description: This file contains the interface for the MixedBeamColumnAsym3d class. +// It defines the class interface and the class attributes. +// +// What: "@(#) MixedBeamColumnAsym3d.h, revA" + +#include +#include +#include + +#include +#include +#include + +class Node; +class Channel; +class Response; +class BeamIntegration; +class SectionForceDeformation; + +class MixedBeamColumnAsym3d : public Element +{ + public: + // constructors + MixedBeamColumnAsym3d (int tag, int nodeI, int nodeJ, + int numSections, SectionForceDeformation **sectionPtrs, BeamIntegration &bi, + CrdTransf &coordTransf, double ys, double zs, double massDensPerUnitLength, int doRayleigh, bool geomLinear); + MixedBeamColumnAsym3d (); + + // destructor + ~MixedBeamColumnAsym3d(); + + // public methods to obtain information about dof & connectivity + 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); + const Matrix &getDamp(void); + + void zeroLoad(void); + int addLoad(ElementalLoad *theLoad, double loadFactor); + + const Vector &getResistingForce(void); + const Vector &getResistingForceIncInertia(void); + + // public methods for output + int sendSelf(int cTag, Channel &theChannel); + int recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + void Print(OPS_Stream &s, int flag = 0); + friend OPS_Stream &operator<<(OPS_Stream &s, MixedBeamColumnAsym3d &E); + + Response* setResponse(const char **argv, int argc, OPS_Stream &output); + int getResponse(int responseID, Information &eleInfo); + + const char *getClassType(void) const {return "MixedBeamColumnAsym3d";}; + + protected: + + private: + // Private Functions - Shape Functions + Matrix getNld_hat(int sec, const Vector &v, double L, bool geomLinear); + Vector getd_hat(int sec, const Vector &v, double L, bool geomLinear); + Matrix getNd1(int sec, const Vector &v, double L, bool geomLinear); + Matrix getNd2(int sec, double P, double L); + Matrix getKg(int sec, Vector P, double L); + Matrix getMd(int sec, Vector dShapeFcn, Vector dFibers, double L); + + // Private Functions - Interaction With The Sections + //void getSectionTangent(int sec,int type,Matrix &kSection,double &GJ); + //void getSectionStress(int sec,Vector &fSection,double &torsion); + //void setSectionDeformation(int sec,Vector &defSection,double &twist); + + // Private Attributes - a copy for each object of the class + ID connectedExternalNodes; // tags of the end nodes + Node *theNodes[2]; // pointers to the nodes + BeamIntegration *beamIntegr; // + int numSections; // + SectionForceDeformation **sections; // array of pointers to sections + CrdTransf *crdTransf; // pointer to coordinate transformation object + + int doRayleigh; // flag for whether or not rayleigh damping is active for this element + bool geomLinear; // flag for whether or not the internal geometric nonlinearity is active + double rho; // mass density per unit length + + int itr; // Counts the number of iterations from last comitted state (not very sure) + int initialFlag; + + // Attributes that do NOT change during the analysis + double initialLength; + Matrix *Ki; + + // Element Load Variables + Matrix *sp; + double p0[5]; // Reactions in the basic system due to element loads + + // Attributes that change during the analysis + Vector V; + Vector internalForce; //Xinlong: internal resisting force (6) + Vector naturalForce; //Xinlong: generalized force degrees of freedom (7) + Vector lastNaturalDisp; + Matrix Hinv; + Matrix GMH; + Matrix kv; // stiffness matrix in the basic system + Vector *sectionForceFibers; + Vector *sectionDefFibers; + Matrix *sectionFlexibility; + Vector *sectionForceShapeFcn; + + // Committed versions + Vector committedV; + Vector committedInternalForce; + Vector commitedNaturalForce; + Vector commitedLastNaturalDisp; + Matrix commitedHinv; + Matrix commitedGMH; + Matrix kvcommit; + Vector *commitedSectionForceFibers; + Vector *commitedSectionDefFibers; + Matrix *commitedSectionFlexibility; + + // static data - single copy for all objects of the class + //static int maxNumSections; + enum { maxNumSections = 10 }; + static Matrix theMatrix; + static Vector theVector; + static double workArea[]; + //static Matrix transformNaturalCoords; + //static Matrix transformNaturalCoordsT; + // matrix to transform the natural coordinates from what the coordinate transformation uses and what the element uses + + // These variable are always recomputed, so there is no need to store them for each instance of the element + static Vector *sectionDefShapeFcn; + static Matrix *nldhat; + static Matrix *nd1; + static Matrix *nd2; + static Matrix *nd1T; + static Matrix *nd2T; + + double ys; //Xinlong: y coord of shear center relative to centroid + double zs; //Xinlong: z coord of shear center relative to centroid + + enum { NDM = 3 }; // dimension of the problem (3d) + enum { NND = 6 }; // number of nodal dof's + enum { NGF = 7 }; //Xinlong: number of generalized force degrees of freedom + enum { NSD = 5 }; //Xinlong: number of section dofs + enum { NEGD = 12 }; // number of element global dof's + enum { NEBD = 6 }; // number of element dof's in the basic system +}; + +#endif + diff --git a/SRC/element/shell/ShellNLDKGT.cpp b/SRC/element/shell/ShellNLDKGT.cpp index 00e1bbef2..f0bc315de 100644 --- a/SRC/element/shell/ShellNLDKGT.cpp +++ b/SRC/element/shell/ShellNLDKGT.cpp @@ -114,7 +114,7 @@ double ShellNLDKGT::wg[4] ; //null constructor ShellNLDKGT::ShellNLDKGT( ) : Element( 0, ELE_TAG_ShellNLDKGT ), -connectedExternalNodes(3), CstrainGauss(32),TstrainGauss(32),load(0), Ki(0) +connectedExternalNodes(3), CstrainGauss(32),TstrainGauss(32),load(0), Ki(0), nodePointers(), xl(), g1(), g2(), g3() { for (int i = 0 ; i < 4; i++ ) materialPointers[i] = 0; @@ -150,8 +150,8 @@ ShellNLDKGT::ShellNLDKGT( int tag, int node2, int node3, SectionForceDeformation &theMaterial ) : -Element( tag, ELE_TAG_ShellDKGT ), -connectedExternalNodes(3), CstrainGauss(32),TstrainGauss(32),load(0), Ki(0) +Element( tag, ELE_TAG_ShellNLDKGT), +connectedExternalNodes(3), CstrainGauss(32),TstrainGauss(32),load(0), Ki(0), nodePointers(), xl(), g1(), g2(), g3() { int i; connectedExternalNodes(0) = node1 ; diff --git a/SRC/element/surfaceLoad/SurfaceLoad.cpp b/SRC/element/surfaceLoad/SurfaceLoad.cpp index ee792d405..b8ca3d7a3 100644 --- a/SRC/element/surfaceLoad/SurfaceLoad.cpp +++ b/SRC/element/surfaceLoad/SurfaceLoad.cpp @@ -511,14 +511,14 @@ SurfaceLoad::Print(OPS_Stream &s, int flag) } Response* -SurfaceLoad::setResponse(const char **argv, int argc, Information &eleInfo) +SurfaceLoad::setResponse(const char **argv, int argc, OPS_Stream &output) { - return 0; + return Element::setResponse(argv, argc, output); } int SurfaceLoad::getResponse(int responseID, Information &eleInfo) { - return -1; + return Element::getResponse(responseID, eleInfo); } diff --git a/SRC/element/surfaceLoad/SurfaceLoad.h b/SRC/element/surfaceLoad/SurfaceLoad.h index 8ad2fb2c2..37454cf7e 100644 --- a/SRC/element/surfaceLoad/SurfaceLoad.h +++ b/SRC/element/surfaceLoad/SurfaceLoad.h @@ -90,7 +90,7 @@ class SurfaceLoad : public Element void Print(OPS_Stream &s, int flag =0); - Response *setResponse(const char **argv, int argc, Information &eleInfo); + Response *setResponse(const char **argv, int argc, OPS_Stream &output); int getResponse(int responseID, Information &eleInformation); protected: diff --git a/SRC/element/surfaceLoad/TriSurfaceLoad.cpp b/SRC/element/surfaceLoad/TriSurfaceLoad.cpp index 59e4cb7f2..4c1ff9688 100644 --- a/SRC/element/surfaceLoad/TriSurfaceLoad.cpp +++ b/SRC/element/surfaceLoad/TriSurfaceLoad.cpp @@ -508,15 +508,15 @@ TriSurfaceLoad::Print(OPS_Stream &s, int flag) } Response* -TriSurfaceLoad::setResponse(const char **argv, int argc, Information &eleInfo) +TriSurfaceLoad::setResponse(const char **argv, int argc, OPS_Stream &output) { - return 0; + return Element::setResponse(argv, argc, output); } int TriSurfaceLoad::getResponse(int responseID, Information &eleInfo) { - return -1; + return Element::getResponse(responseID, eleInfo); } diff --git a/SRC/element/surfaceLoad/TriSurfaceLoad.h b/SRC/element/surfaceLoad/TriSurfaceLoad.h index ce38599e9..12c2e3ec5 100644 --- a/SRC/element/surfaceLoad/TriSurfaceLoad.h +++ b/SRC/element/surfaceLoad/TriSurfaceLoad.h @@ -90,7 +90,7 @@ class TriSurfaceLoad : public Element void Print(OPS_Stream &s, int flag =0); - Response *setResponse(const char **argv, int argc, Information &eleInfo); + Response *setResponse(const char **argv, int argc, OPS_Stream &output); int getResponse(int responseID, Information &eleInformation); protected: diff --git a/SRC/element/tetrahedron/FourNodeTetrahedron.cpp b/SRC/element/tetrahedron/FourNodeTetrahedron.cpp index ac02c2dd0..87f107fc7 100644 --- a/SRC/element/tetrahedron/FourNodeTetrahedron.cpp +++ b/SRC/element/tetrahedron/FourNodeTetrahedron.cpp @@ -1701,7 +1701,7 @@ FourNodeTetrahedron::setResponse(const char **argv, int argc, OPS_Stream &output if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) { - for (int i=1; i<=3; i++) + for (int i=1; i<=4; i++) { sprintf(outputData,"P1_%d",i); output.tag("ResponseType",outputData); diff --git a/SRC/element/triangle/Tri31.h b/SRC/element/triangle/Tri31.h index 3c1e3d175..cf98ac3ee 100644 --- a/SRC/element/triangle/Tri31.h +++ b/SRC/element/triangle/Tri31.h @@ -98,6 +98,7 @@ class Tri31 : public Element // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/element/truss/CorotTruss.cpp b/SRC/element/truss/CorotTruss.cpp index 7f0d22808..c067575a7 100644 --- a/SRC/element/truss/CorotTruss.cpp +++ b/SRC/element/truss/CorotTruss.cpp @@ -1098,41 +1098,35 @@ 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) { - output.tag("GaussPointOutput"); - output.attr("number", 1); - output.attr("eta", 0.0); - + // a material quantity + } else if (strcmp(argv[0], "material") == 0 || strcmp(argv[0], "-material") == 0) { if (argc > 1) { // we need at least one more argument otherwise // there is no need to forward this call to the material + // by default assume the old call style for backward compatibility "material result" + int offset = 1; + bool is_valid = true; + // in case the user specifies the gauss point id... "material 1 result" 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); + if (sectionNum == 1) { + // this is the only supported gauss id + offset = 2; } - 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 if (sectionNum > 1) { + // this is a number, but not within the valid range + is_valid = false; } + // if it is 0, then it is not a number, forward it as usual... } - else { - // otherwise forward it as usual - theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + if (is_valid) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + theResponse = theMaterial->setResponse(&argv[offset], argc - offset, output); + output.endTag(); } } - output.endTag(); } output.endTag(); diff --git a/SRC/element/truss/CorotTruss2.cpp b/SRC/element/truss/CorotTruss2.cpp index 4763fd6a4..2204ceabf 100644 --- a/SRC/element/truss/CorotTruss2.cpp +++ b/SRC/element/truss/CorotTruss2.cpp @@ -936,38 +936,33 @@ CorotTruss2::setResponse(const char **argv, int argc, OPS_Stream &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 + // by default assume the old call style for backward compatibility "material result" + int offset = 1; + bool is_valid = true; + // in case the user specifies the gauss point id... "material 1 result" 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); + if (sectionNum == 1) { + // this is the only supported gauss id + offset = 2; } - 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 if (sectionNum > 1) { + // this is a number, but not within the valid range + is_valid = false; } + // if it is 0, then it is not a number, forward it as usual... } - else { - // otherwise forward it as usual - theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + if (is_valid) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + theResponse = theMaterial->setResponse(&argv[offset], argc - offset, output); + output.endTag(); } } - output.endTag(); } output.endTag(); diff --git a/SRC/element/truss/CorotTrussSection.cpp b/SRC/element/truss/CorotTrussSection.cpp index c4222a8f1..7f7d8ee90 100644 --- a/SRC/element/truss/CorotTrussSection.cpp +++ b/SRC/element/truss/CorotTrussSection.cpp @@ -964,38 +964,33 @@ CorotTrussSection::setResponse(const char **argv, int argc, OPS_Stream &output) // a section quantity } 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 + // there is no need to forward this call to the material + // by default assume the old call style for backward compatibility "material result" + int offset = 1; + bool is_valid = true; + // in case the user specifies the gauss point id... "section 1 result" 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); + if (sectionNum == 1) { + // this is the only supported gauss id + offset = 2; } - 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 if (sectionNum > 1) { + // this is a number, but not within the valid range + is_valid = false; } + // if it is 0, then it is not a number, forward it as usual... } - else { - // otherwise forward it as usual - theResponse = theSection->setResponse(&argv[1], argc - 1, output); + if (is_valid) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + theResponse = theSection->setResponse(&argv[offset], argc - offset, output); + output.endTag(); } } - output.endTag(); } output.endTag(); diff --git a/SRC/element/truss/N4BiaxialTruss.cpp b/SRC/element/truss/N4BiaxialTruss.cpp index 2ec115f20..75c2bbff0 100644 --- a/SRC/element/truss/N4BiaxialTruss.cpp +++ b/SRC/element/truss/N4BiaxialTruss.cpp @@ -1276,59 +1276,38 @@ 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) { - 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 + // by default assume the old call style for backward compatibility "material result" + int offset = 1; + bool is_valid = true; + // in case the user specifies the gauss point id... "material 1 result" 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; + if (sectionNum == 1) { + // this is the only supported gauss id + offset = 2; } - 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 if (sectionNum > 1) { + // this is a number, but not within the valid range + is_valid = false; } + // if it is 0, then it is not a number, forward it as usual... } - else { - // otherwise forward it as usual + if (is_valid) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.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); - + Response* theResponse1 = theMaterial_1->setResponse(&argv[offset], argc - offset, output); + Response* theResponse2 = theMaterial_2->setResponse(&argv[offset], argc - offset, output); theCResponse->addResponse(theResponse1); theCResponse->addResponse(theResponse2); - theResponse = theCResponse; + output.endTag(); } } - output.endTag(); } output.endTag(); diff --git a/SRC/element/truss/Truss.cpp b/SRC/element/truss/Truss.cpp index eff0ede8f..925702d12 100644 --- a/SRC/element/truss/Truss.cpp +++ b/SRC/element/truss/Truss.cpp @@ -1195,38 +1195,33 @@ 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) { - 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 + // there is no need to forward this call to the material + // by default assume the old call style for backward compatibility "material result" + int offset = 1; + bool is_valid = true; + // in case the user specifies the gauss point id... "material 1 result" 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); + if (sectionNum == 1) { + // this is the only supported gauss id + offset = 2; } - 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 if (sectionNum > 1) { + // this is a number, but not within the valid range + is_valid = false; } + // if it is 0, then it is not a number, forward it as usual... } - else { - // otherwise forward it as usual - theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + if (is_valid) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + theResponse = theMaterial->setResponse(&argv[offset], argc - offset, output); + output.endTag(); } } - output.endTag(); } output.endTag(); diff --git a/SRC/element/truss/Truss2.cpp b/SRC/element/truss/Truss2.cpp index 6502cfa78..bc19f840c 100644 --- a/SRC/element/truss/Truss2.cpp +++ b/SRC/element/truss/Truss2.cpp @@ -1196,38 +1196,33 @@ Response* // 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 + // by default assume the old call style for backward compatibility "material result" + int offset = 1; + bool is_valid = true; + // in case the user specifies the gauss point id... "material 1 result" 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); + if (sectionNum == 1) { + // this is the only supported gauss id + offset = 2; } - 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 if (sectionNum > 1) { + // this is a number, but not within the valid range + is_valid = false; } + // if it is 0, then it is not a number, forward it as usual... } - else { - // otherwise forward it as usual - theResponse = theMaterial->setResponse(&argv[1], argc - 1, output); + if (is_valid) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + theResponse = theMaterial->setResponse(&argv[offset], argc - offset, output); + output.endTag(); } } - output.endTag(); } output.endTag(); diff --git a/SRC/element/truss/TrussSection.cpp b/SRC/element/truss/TrussSection.cpp index ce5184bea..f87ccac22 100644 --- a/SRC/element/truss/TrussSection.cpp +++ b/SRC/element/truss/TrussSection.cpp @@ -1125,38 +1125,33 @@ TrussSection::setResponse(const char **argv, int argc, OPS_Stream &output) // a section quantity } 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 + // there is no need to forward this call to the material + // by default assume the old call style for backward compatibility "material result" + int offset = 1; + bool is_valid = true; + // in case the user specifies the gauss point id... "section 1 result" 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); + if (sectionNum == 1) { + // this is the only supported gauss id + offset = 2; } - 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 if (sectionNum > 1) { + // this is a number, but not within the valid range + is_valid = false; } + // if it is 0, then it is not a number, forward it as usual... } - else { - // otherwise forward it as usual - theResponse = theSection->setResponse(&argv[1], argc - 1, output); + if (is_valid) { + output.tag("GaussPointOutput"); + output.attr("number", 1); + output.attr("eta", 0.0); + theResponse = theSection->setResponse(&argv[offset], argc - offset, output); + output.endTag(); } } - output.endTag(); } output.endTag(); diff --git a/SRC/element/zeroLength/ZeroLengthContact2D.cpp b/SRC/element/zeroLength/ZeroLengthContact2D.cpp index 38c9dc70c..e5ba5ce01 100644 --- a/SRC/element/zeroLength/ZeroLengthContact2D.cpp +++ b/SRC/element/zeroLength/ZeroLengthContact2D.cpp @@ -623,7 +623,7 @@ ZeroLengthContact2D::Print(OPS_Stream &s, int flag) } Response* -ZeroLengthContact2D::setResponse(const char **argv, int argc, Information &eleInformation) +ZeroLengthContact2D::setResponse(const char **argv, int argc, OPS_Stream &output) { if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) return new ElementResponse(this, 1, resid); @@ -642,7 +642,7 @@ ZeroLengthContact2D::setResponse(const char **argv, int argc, Information &eleIn return new ElementResponse(this, 4, gap); else - return 0; + return Element::setResponse(argv, argc, output); } @@ -662,7 +662,7 @@ ZeroLengthContact2D::getResponse(int responseID, Information &eleInfo) return eleInfo.setDouble(this->gap); else - return -1; + return Element::getResponse(responseID, eleInfo); } diff --git a/SRC/element/zeroLength/ZeroLengthContact2D.h b/SRC/element/zeroLength/ZeroLengthContact2D.h index cbc5cbd5c..92094059e 100644 --- a/SRC/element/zeroLength/ZeroLengthContact2D.h +++ b/SRC/element/zeroLength/ZeroLengthContact2D.h @@ -144,7 +144,7 @@ class ZeroLengthContact2D: public Element 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, Information &eleInformation); + Response *setResponse(const char **argv, int argc, OPS_Stream &output); int getResponse(int responseID, Information &eleInformation); //void updateDir (const Vector& x, const Vector& y); diff --git a/SRC/element/zeroLength/ZeroLengthContact3D.cpp b/SRC/element/zeroLength/ZeroLengthContact3D.cpp index b544fff88..d0e8e84d1 100644 --- a/SRC/element/zeroLength/ZeroLengthContact3D.cpp +++ b/SRC/element/zeroLength/ZeroLengthContact3D.cpp @@ -522,7 +522,7 @@ ZeroLengthContact3D::Print(OPS_Stream &s, int flag) } Response* -ZeroLengthContact3D::setResponse(const char **argv, int argc, Information &eleInformation) +ZeroLengthContact3D::setResponse(const char **argv, int argc, OPS_Stream &output) { if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) return new ElementResponse(this, 1, resid); @@ -532,7 +532,7 @@ ZeroLengthContact3D::setResponse(const char **argv, int argc, Information &eleIn return new ElementResponse(this, 2, stiff); else - return 0; + return Element::setResponse(argv, argc, output); } @@ -544,7 +544,7 @@ ZeroLengthContact3D::getResponse(int responseID, Information &eleInfo) else if (responseID == 2) return eleInfo.setMatrix(this->getTangentStiff()); else - return -1; + return Element::getResponse(responseID, eleInfo); } diff --git a/SRC/element/zeroLength/ZeroLengthContact3D.h b/SRC/element/zeroLength/ZeroLengthContact3D.h index 4e4783dd0..197aa8238 100644 --- a/SRC/element/zeroLength/ZeroLengthContact3D.h +++ b/SRC/element/zeroLength/ZeroLengthContact3D.h @@ -160,7 +160,7 @@ class ZeroLengthContact3D: public Element 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, Information &eleInformation); + Response *setResponse(const char **argv, int argc, OPS_Stream &output); int getResponse(int responseID, Information &eleInformation); diff --git a/SRC/element/zeroLength/ZeroLengthContactNTS2D.cpp b/SRC/element/zeroLength/ZeroLengthContactNTS2D.cpp index f97d478b5..d1b515b52 100644 --- a/SRC/element/zeroLength/ZeroLengthContactNTS2D.cpp +++ b/SRC/element/zeroLength/ZeroLengthContactNTS2D.cpp @@ -477,7 +477,7 @@ ZeroLengthContactNTS2D::Print(OPS_Stream &s, int flag) } Response* -ZeroLengthContactNTS2D::setResponse(const char **argv, int argc, Information &eleInformation) +ZeroLengthContactNTS2D::setResponse(const char **argv, int argc, OPS_Stream &output) { if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) return new ElementResponse(this, 1, resid); @@ -491,7 +491,7 @@ ZeroLengthContactNTS2D::setResponse(const char **argv, int argc, Information &el } else if (strcmp(argv[0],"gap")== 0) return new ElementResponse(this, 4, normal_gap); else - return 0; + return Element::setResponse(argv, argc, output); } int @@ -506,7 +506,7 @@ ZeroLengthContactNTS2D::getResponse(int responseID, Information &eleInfo) else if (responseID == 4) return eleInfo.setVector(this->normal_gap); else - return -1; + return Element::Element::getResponse(responseID, eleInfo); } // Private methods diff --git a/SRC/element/zeroLength/ZeroLengthContactNTS2D.h b/SRC/element/zeroLength/ZeroLengthContactNTS2D.h index 8a4c0dddb..b92b0aa8d 100644 --- a/SRC/element/zeroLength/ZeroLengthContactNTS2D.h +++ b/SRC/element/zeroLength/ZeroLengthContactNTS2D.h @@ -128,7 +128,7 @@ class ZeroLengthContactNTS2D: public Element 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, Information &eleInformation); + Response *setResponse(const char **argv, int argc, OPS_Stream &output); int getResponse(int responseID, Information &eleInformation); //void updateDir (const Vector& x, const Vector& y); diff --git a/SRC/element/zeroLength/ZeroLengthInterface2D.cpp b/SRC/element/zeroLength/ZeroLengthInterface2D.cpp index bd40f7597..c14eb73ff 100644 --- a/SRC/element/zeroLength/ZeroLengthInterface2D.cpp +++ b/SRC/element/zeroLength/ZeroLengthInterface2D.cpp @@ -375,7 +375,7 @@ ZeroLengthInterface2D::Print(OPS_Stream &s, int flag) } Response* -ZeroLengthInterface2D::setResponse(const char **argv, int argc, Information &eleInformation) +ZeroLengthInterface2D::setResponse(const char **argv, int argc, OPS_Stream &output) { if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) return new ElementResponse(this, 1, resid); @@ -389,7 +389,7 @@ ZeroLengthInterface2D::setResponse(const char **argv, int argc, Information &ele } else if (strcmp(argv[0],"gap")== 0) return new ElementResponse(this, 4, normal_gap); else - return 0; + return Element::setResponse(argv, argc, output); } int @@ -404,7 +404,7 @@ ZeroLengthInterface2D::getResponse(int responseID, Information &eleInfo) else if (responseID == 4) return eleInfo.setVector(this->normal_gap); else - return -1; + return Element::getResponse(responseID, eleInfo); } // Private methods diff --git a/SRC/element/zeroLength/ZeroLengthInterface2D.h b/SRC/element/zeroLength/ZeroLengthInterface2D.h index 7c6c5e66f..fc0dda56b 100644 --- a/SRC/element/zeroLength/ZeroLengthInterface2D.h +++ b/SRC/element/zeroLength/ZeroLengthInterface2D.h @@ -130,7 +130,7 @@ class ZeroLengthInterface2D: public Element 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, Information &eleInformation); + Response *setResponse(const char **argv, int argc, OPS_Stream &output); int getResponse(int responseID, Information &eleInformation); //void updateDir (const Vector& x, const Vector& y); diff --git a/SRC/handler/BinaryFileStream.cpp b/SRC/handler/BinaryFileStream.cpp index 064350c03..2cb095c0f 100644 --- a/SRC/handler/BinaryFileStream.cpp +++ b/SRC/handler/BinaryFileStream.cpp @@ -875,7 +875,7 @@ BinaryFileStream::setOrder(const ID &orderData) count++; } - opserr << printMapping; + //opserr << printMapping; } return 0; diff --git a/SRC/interpreter/OpenSeesBeamIntegrationCommands.cpp b/SRC/interpreter/OpenSeesBeamIntegrationCommands.cpp index 3cec41720..ac58612e3 100644 --- a/SRC/interpreter/OpenSeesBeamIntegrationCommands.cpp +++ b/SRC/interpreter/OpenSeesBeamIntegrationCommands.cpp @@ -51,10 +51,12 @@ void* OPS_NewtonCotesBeamIntegration(int&,ID&); void* OPS_RadauBeamIntegration(int&,ID&); void* OPS_TrapezoidalBeamIntegration(int&,ID&); void* OPS_CompositeSimpsonBeamIntegration(int&,ID&); +void* OPS_SimpsonBeamIntegration(int&,ID&); void* OPS_UserDefinedBeamIntegration(int&,ID&); void* OPS_FixedLocationBeamIntegration(int&,ID&); void* OPS_LowOrderBeamIntegration(int&,ID&); void* OPS_MidDistanceBeamIntegration(int&,ID&); +void* OPS_ChebyshevBeamIntegration(int&,ID&); void* OPS_UserHingeBeamIntegration(int&,ID&); void* OPS_HingeMidpointBeamIntegration(int&,ID&); void* OPS_HingeRadauBeamIntegration(int&,ID&); @@ -77,10 +79,12 @@ namespace { int setUpFunctions(void) { functionMap.insert(std::make_pair("Lobatto", &OPS_LobattoBeamIntegration)); functionMap.insert(std::make_pair("Legendre", &OPS_LegendreBeamIntegration)); + functionMap.insert(std::make_pair("Chebyshev", &OPS_ChebyshevBeamIntegration)); functionMap.insert(std::make_pair("NewtonCotes", &OPS_NewtonCotesBeamIntegration)); functionMap.insert(std::make_pair("Radau", &OPS_RadauBeamIntegration)); functionMap.insert(std::make_pair("Trapezoidal", &OPS_TrapezoidalBeamIntegration)); functionMap.insert(std::make_pair("CompositeSimpson", &OPS_CompositeSimpsonBeamIntegration)); + functionMap.insert(std::make_pair("Simpson", &OPS_SimpsonBeamIntegration)); functionMap.insert(std::make_pair("UserDefined", &OPS_UserDefinedBeamIntegration)); functionMap.insert(std::make_pair("FixedLocation", &OPS_FixedLocationBeamIntegration)); functionMap.insert(std::make_pair("LowOrder", &OPS_LowOrderBeamIntegration)); diff --git a/SRC/interpreter/OpenSeesCommands.cpp b/SRC/interpreter/OpenSeesCommands.cpp index 9c68df5a0..80d163455 100644 --- a/SRC/interpreter/OpenSeesCommands.cpp +++ b/SRC/interpreter/OpenSeesCommands.cpp @@ -1563,7 +1563,7 @@ int OPS_Integrator() ti = (TransientIntegrator*)OPS_CentralDifferenceNoDamping(); } else if (strcmp(type, "ExplicitDifference") == 0) { - ti = (TransientIntegrator*)OPS_Explicitdifference(); + ti = (TransientIntegrator*)OPS_ExplicitDifference(); } else { opserr<<"WARNING unknown integrator type "<getDomain()->getCommitTag(); + int numdata = 1; + if (OPS_GetNumRemainingInputArgs() > 0) { + if (OPS_GetIntInput(&numdata, &commitTag) < 0) { + opserr << "WARNING: failed to get commitTag\n"; + return -1; + } + cmds->getDomain()->setCommitTag(commitTag); + } + if (OPS_SetIntOutput(&numdata, &commitTag, true) < 0) { + opserr << "WARNING failed to set commitTag\n"; + return 0; + } + + return 0; +} + void* OPS_ParallelRCM() { #ifdef _PARALLEL_INTERPRETERS diff --git a/SRC/interpreter/OpenSeesCommands.h b/SRC/interpreter/OpenSeesCommands.h index 109e7ab34..d5f62f858 100644 --- a/SRC/interpreter/OpenSeesCommands.h +++ b/SRC/interpreter/OpenSeesCommands.h @@ -251,6 +251,7 @@ int OPS_nodeCoord(); int OPS_setNodeCoord(); int OPS_updateElementDomain(); int OPS_eleNodes(); +int OPS_eleType(); int OPS_nodeDOFs(); int OPS_nodeMass(); int OPS_nodePressure(); @@ -267,6 +268,7 @@ int OPS_sectionStiffness(); int OPS_sectionFlexibility(); int OPS_sectionLocation(); int OPS_sectionWeight(); +int OPS_sectionTag(); int OPS_sectionDisplacement(); int OPS_cbdiDisplacement(); int OPS_basicDeformation(); @@ -282,6 +284,11 @@ int OPS_sensNodeAccel(); int OPS_sensLambda(); int OPS_sensSectionForce(); int OPS_sensNodePressure(); +int OPS_getNumElements(); +int OPS_getEleClassTags(); +int OPS_getEleLoadClassTags(); +int OPS_getEleLoadTags(); +int OPS_getEleLoadData(); // Sensitivity:END ///////////////////////////////////////////// /* OpenSeesMiscCommands.cpp */ @@ -369,6 +376,7 @@ int OPS_numFact(); int OPS_numIter(); int* OPS_GetNumEigen(); int OPS_systemSize(); +int OPS_domainCommitTag(); void* OPS_KrylovNewton(); void* OPS_RaphsonNewton(); @@ -376,6 +384,7 @@ void* OPS_MillerNewton(); void* OPS_SecantNewton(); void* OPS_PeriodicNewton(); void* OPS_NewtonLineSearch(); +void* OPS_ExpressNewton(); void* OPS_ParallelNumberer(); void* OPS_ParallelRCM(); @@ -485,7 +494,7 @@ void* OPS_WilsonTheta(); void* OPS_CentralDifference(); void* OPS_CentralDifferenceAlternative(); void* OPS_CentralDifferenceNoDamping(); -void* OPS_Explicitdifference(); +void* OPS_ExplicitDifference(); void* OPS_LinearAlgorithm(); void* OPS_NewtonRaphsonAlgorithm(); diff --git a/SRC/interpreter/OpenSeesElementCommands.cpp b/SRC/interpreter/OpenSeesElementCommands.cpp index 226c6c8d8..8c4fc6e46 100644 --- a/SRC/interpreter/OpenSeesElementCommands.cpp +++ b/SRC/interpreter/OpenSeesElementCommands.cpp @@ -150,9 +150,12 @@ void* OPS_ForceBeamColumn2dThermal(); void* OPS_DispBeamColumn2d(const ID& info); void* OPS_DispBeamColumnNL2d(const ID& info); void* OPS_DispBeamColumn3d(); +void* OPS_DispBeamColumnNL3d(); void* OPS_DispBeamColumnWarping3d(); +void* OPS_DispBeamColumnAsym3d(); void* OPS_MixedBeamColumn2d(); void* OPS_MixedBeamColumn3d(); +void* OPS_MixedBeamColumnAsym3d(); void* OPS_ForceBeamColumnCBDI2d(); void* OPS_ForceBeamColumnCSBDI2d(); void* OPS_ForceBeamColumnCBDI3d(); @@ -221,6 +224,7 @@ void* OPS_KikuchiBearing(); void* OPS_YamamotoBiaxialHDR(); void* OPS_FourNodeTetrahedron(); void* OPS_CatenaryCableElement(); +void *OPS_ASDEmbeddedNodeElement(void); void* OPS_GradientInelasticBeamColumn2d(); void* OPS_GradientInelasticBeamColumn3d(); void* OPS_RockingBC(); @@ -332,7 +336,7 @@ namespace { ID info; return OPS_DispBeamColumnNL2d(info); } else { - return OPS_DispBeamColumn3d(); + return OPS_DispBeamColumnNL3d(); } } @@ -664,7 +668,8 @@ namespace { functionMap.insert(std::make_pair("SurfaceLoad", &OPS_SurfaceLoad)); functionMap.insert(std::make_pair("elasticBeamColumn", &OPS_ElasticBeam)); functionMap.insert(std::make_pair("elasticBeamColumnWarping", &OPS_ElasticBeamWarping3d)); - functionMap.insert(std::make_pair("dispBeamColumnWarping", &OPS_DispBeamColumnWarping3d)); + functionMap.insert(std::make_pair("dispBeamColumnWarping", &OPS_DispBeamColumnWarping3d)); + functionMap.insert(std::make_pair("dispBeamColumnAsym", &OPS_DispBeamColumnAsym3d)); functionMap.insert(std::make_pair("forceBeamColumn", &OPS_ForceBeamColumn)); functionMap.insert(std::make_pair("nonlinearBeamColumn", &OPS_NonlinearBeamColumn)); functionMap.insert(std::make_pair("dispBeamColumn", &OPS_DispBeamColumn)); @@ -673,11 +678,13 @@ namespace { 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("mixedBeamColumnAsym", &OPS_MixedBeamColumnAsym3d)); functionMap.insert(std::make_pair("zeroLength", &OPS_ZeroLength)); functionMap.insert(std::make_pair("zeroLengthSection", &OPS_ZeroLengthSection)); functionMap.insert(std::make_pair("zeroLengthND", &OPS_ZeroLengthND)); functionMap.insert(std::make_pair("FourNodeTetrahedron", &OPS_FourNodeTetrahedron)); functionMap.insert(std::make_pair("CatenaryCable", &OPS_CatenaryCableElement)); + functionMap.insert(std::make_pair("ASDEmbeddedNodeElement", &OPS_ASDEmbeddedNodeElement)); functionMap.insert(std::make_pair("gradientInelasticBeamColumn", &OPS_GradientInelasticBeamColumn)); functionMap.insert(std::make_pair("RockingBC", &OPS_RockingBC)); diff --git a/SRC/interpreter/OpenSeesOutputCommands.cpp b/SRC/interpreter/OpenSeesOutputCommands.cpp index 02409717c..eb48dd18c 100644 --- a/SRC/interpreter/OpenSeesOutputCommands.cpp +++ b/SRC/interpreter/OpenSeesOutputCommands.cpp @@ -45,8 +45,11 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #include #include #include +#include #include #include +#include +#include #include #include #include @@ -311,6 +314,10 @@ int OPS_nodeEigenvector() // get eigen vectors Node* theNode = theDomain->getNode(data[0]); + if (theNode == 0) { + opserr << "nodeEigenvector - node with tag " << data[0] << " not found\n"; + return -1; + } const Matrix &theEigenvectors = theNode->getEigenvectors(); int size = theEigenvectors.noRows(); @@ -1567,6 +1574,41 @@ int OPS_updateElementDomain() return 0; } +int OPS_eleType() +{ + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING want - eleType eleTag?\n"; + return -1; + } + + int tag; + int numdata = 1; + + if (OPS_GetIntInput(&numdata, &tag) < 0) { + opserr << "WARNING eleType eleTag? \n"; + return -1; + } + + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + char buffer[80]; + Element *theElement = theDomain->getElement(tag); + if (theElement == 0) { + opserr << "WARNING eleType ele " << tag << " not found" << endln; + return -1; + } + const char* type = theElement->getClassType(); + sprintf(buffer, "%s", type); + + if (OPS_SetString(buffer) < 0) { + opserr << "WARNING failed to set eleType\n"; + return -1; + } + + return 0; +} + int OPS_eleNodes() { if (OPS_GetNumRemainingInputArgs() < 1) { @@ -2260,8 +2302,8 @@ int OPS_sectionFlexibility() int OPS_sectionLocation() { // make sure at least one other argument to contain type of system - if (OPS_GetNumRemainingInputArgs() < 2) { - opserr << "WARNING want - sectionLocation eleTag? secNum? \n"; + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING want - sectionLocation eleTag? \n"; return -1; } @@ -2270,17 +2312,21 @@ int OPS_sectionLocation() // opserr << argv[i] << ' ' ; //opserr << endln; - int numdata = 2; - int data[2]; - - if (OPS_GetIntInput(&numdata, data) < 0) { - opserr << "WARNING sectionLocation eleTag? secNum? - could not read int input? \n"; + int numdata = 1; + int tag; + if (OPS_GetIntInput(&numdata, &tag) < 0) { + opserr << "WARNING sectionLocation eleTag? - could not read int input? \n"; return -1; } - int tag = data[0]; - int secNum = data[1]; - + int secNum = 0; + if (OPS_GetNumRemainingInputArgs() > 0) { + if (OPS_GetIntInput(&numdata, &secNum) < 0) { + opserr << "WARNING sectionLocation eleTag? - could not read int input? \n"; + return -1; + } + } + Domain* theDomain = OPS_GetDomain(); if (theDomain == 0) return -1; @@ -2306,20 +2352,27 @@ int OPS_sectionLocation() Information &info = theResponse->getInformation(); const Vector &theVec = *(info.theVector); - if (secNum <= 0 || secNum > theVec.Size()) { - opserr << "WARNING invalid secNum\n"; + int Np = theVec.Size(); + + if (secNum > 0 && secNum <= Np) { // One IP + double value = theVec(secNum-1); + numdata = 1; + if (OPS_SetDoubleOutput(&numdata, &value, true) < 0) { + opserr << "WARNING failed to set output\n"; delete theResponse; return -1; - } - - double value = theVec(secNum-1); - numdata = 1; - - if (OPS_SetDoubleOutput(&numdata, &value, true) < 0) { + } + } else { // All IPs in a list + std::vector data(Np); + for (int i = 0; i < Np; i++) + data[i] = theVec(i); + numdata = Np; + if (OPS_SetDoubleOutput(&numdata, &data[0], false) < 0) { opserr << "WARNING failed to set output\n"; delete theResponse; return -1; - } + } + } delete theResponse; @@ -2329,8 +2382,8 @@ int OPS_sectionLocation() int OPS_sectionWeight() { // make sure at least one other argument to contain type of system - if (OPS_GetNumRemainingInputArgs() < 2) { - opserr << "WARNING want - sectionWeight eleTag? secNum? \n"; + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING want - sectionWeight eleTag? \n"; return -1; } @@ -2339,17 +2392,21 @@ int OPS_sectionWeight() // opserr << argv[i] << ' ' ; //opserr << endln; - int numdata = 2; - int data[2]; - - if (OPS_GetIntInput(&numdata, data) < 0) { - opserr << "WARNING sectionWeight eleTag? secNum? - could not read int input? \n"; + int numdata = 1; + int tag; + if (OPS_GetIntInput(&numdata, &tag) < 0) { + opserr << "WARNING sectionWeight eleTag? - could not read int input? \n"; return -1; } - int tag = data[0]; - int secNum = data[1]; - + int secNum = 0; + if (OPS_GetNumRemainingInputArgs() > 0) { + if (OPS_GetIntInput(&numdata, &secNum) < 0) { + opserr << "WARNING sectionWeight eleTag? - could not read int input? \n"; + return -1; + } + } + Domain* theDomain = OPS_GetDomain(); if (theDomain == 0) return -1; @@ -2375,19 +2432,106 @@ int OPS_sectionWeight() Information &info = theResponse->getInformation(); const Vector &theVec = *(info.theVector); - if (secNum <= 0 || secNum > theVec.Size()) { - opserr << "WARNING invalid secNum\n"; + int Np = theVec.Size(); + + if (secNum > 0 && secNum <= Np) { // One IP + double value = theVec(secNum-1); + numdata = 1; + if (OPS_SetDoubleOutput(&numdata, &value, true) < 0) { + opserr << "WARNING failed to set output\n"; + delete theResponse; + return -1; + } + } else { // All IPs in a list + std::vector data(Np); + for (int i = 0; i < Np; i++) + data[i] = theVec(i); + numdata = Np; + if (OPS_SetDoubleOutput(&numdata, &data[0], false) < 0) { + opserr << "WARNING failed to set output\n"; delete theResponse; return -1; + } + } + + delete theResponse; + + return 0; +} + +int OPS_sectionTag() +{ + // make sure at least one other argument to contain type of system + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING want - sectionTag eleTag? \n"; + return -1; } - double value = theVec(secNum-1); - numdata = 1; + //opserr << "sectionLocation: "; + //for (int i = 0; i < argc; i++) + // opserr << argv[i] << ' ' ; + //opserr << endln; - if (OPS_SetDoubleOutput(&numdata, &value, true) < 0) { + int numdata = 1; + int tag; + if (OPS_GetIntInput(&numdata, &tag) < 0) { + opserr << "WARNING sectionTag eleTag? - could not read int input? \n"; + return -1; + } + + int secNum = 0; + if (OPS_GetNumRemainingInputArgs() > 0) { + if (OPS_GetIntInput(&numdata, &secNum) < 0) { + opserr << "WARNING sectionTag eleTag? - could not read int input? \n"; + return -1; + } + } + + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + Element *theElement = theDomain->getElement(tag); + if (theElement == 0) { + opserr << "WARNING sectionTag - element with tag " << tag << " not found in domain \n"; + return -1; + } + + int argcc = 1; + char a[80] = "sectionTags"; + 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 ID &theID = *(info.theID); + int Np = theID.Size(); + + if (secNum > 0 && secNum <= Np) { // One IP + int value = theID(secNum-1); + numdata = 1; + if (OPS_SetIntOutput(&numdata, &value, true) < 0) { opserr << "WARNING failed to set output\n"; delete theResponse; return -1; + } + } else { // All IPs in a list + std::vector data(Np); + for (int i = 0; i < Np; i++) + data[i] = theID(i); + numdata = Np; + if (OPS_SetIntOutput(&numdata, &data[0], false) < 0) { + opserr << "WARNING failed to set output\n"; + delete theResponse; + return -1; + } } delete theResponse; @@ -3137,4 +3281,254 @@ int OPS_sensNodePressure() return 0; } +int OPS_getEleClassTags() +{ + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + int numdata = OPS_GetNumRemainingInputArgs(); + + std::vector data; + + // all element tags + if (numdata < 1) { + Element *theEle; + ElementIter &theEles = theDomain->getElements(); + + while ((theEle = theEles()) != 0) { + data.push_back(theEle->getClassTag()); + } + + // specific element tag + } else if (numdata == 1) { + int eleTag; + + if (OPS_GetIntInput(&numdata, &eleTag) < 0) { + opserr << "could not read eleTag\n"; + return -1; + } + + Element *theEle = theDomain->getElement(eleTag); + + data.push_back(theEle->getClassTag()); + + } else { + opserr << "WARNING want - getEleClassTags \n"; + return -1; + } + + int size = data.size(); + + if (OPS_SetIntOutput(&size, data.data(), false) < 0) { + opserr << "WARNING failed to set output\n"; + return -1; + } + + return 0; +} + +int OPS_getEleLoadClassTags() +{ + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + int numdata = OPS_GetNumRemainingInputArgs(); + + std::vector data; + + if (numdata < 1) { + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain->getLoadPatterns(); + + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + while ((theLoad = theEleLoads()) != 0) { + data.push_back(theLoad->getClassTag()); + } + + } + + } else if (numdata == 1) { + + int patternTag; + if (OPS_GetIntInput(&numdata, &patternTag) < 0) { + opserr << "could not read patternTag\n"; + return -1; + } + + LoadPattern *thePattern = theDomain->getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadClassTags\n"; + return -1; + } + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + while ((theLoad = theEleLoads()) != 0) { + data.push_back(theLoad->getClassTag()); + } + + } else { + opserr << "WARNING want - getEleLoadClassTags \n"; + return -1; + } + + + int size = data.size(); + + if (OPS_SetIntOutput(&size, data.data(), false) < 0) { + opserr << "WARNING failed to set output\n"; + return -1; + } + + return 0; +} + +int OPS_getEleLoadTags() +{ + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + int numdata = OPS_GetNumRemainingInputArgs(); + + std::vector data; + + if (numdata < 1) { + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain->getLoadPatterns(); + + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + while ((theLoad = theEleLoads()) != 0) { + data.push_back(theLoad->getElementTag()); + } + + } + + } else if (numdata == 1) { + + int patternTag; + if (OPS_GetIntInput(&numdata, &patternTag) < 0) { + opserr << "could not read patternTag\n"; + return -1; + } + + LoadPattern* thePattern = theDomain->getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadTags\n"; + return -1; + } + ElementalLoadIter& theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + while ((theLoad = theEleLoads()) != 0) { + data.push_back(theLoad->getElementTag()); + } + + } else { + opserr << "WARNING want - getEleLoadTags \n"; + return -1; + } + + int size = data.size(); + + if (OPS_SetIntOutput(&size, data.data(), false) < 0) { + opserr << "WARNING failed to set output\n"; + return -1; + } + + return 0; +} + +int OPS_getEleLoadData() +{ + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + int numdata = OPS_GetNumRemainingInputArgs(); + + std::vector data; + + if (numdata < 1) { + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain->getLoadPatterns(); + + int typeEL; + + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter &theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + while ((theLoad = theEleLoads()) != 0) { + const Vector &eleLoadData = theLoad->getData(typeEL, 1.0); + + int eleLoadDataSize = eleLoadData.Size(); + for (int i = 0; i < eleLoadDataSize; i++) { + data.push_back(eleLoadData(i)); + } + } + } + + } else if (numdata == 1) { + + int patternTag; + if (OPS_GetIntInput(&numdata, &patternTag) < 0) { + opserr << "could not read patternTag\n"; + return -1; + } + + LoadPattern* thePattern = theDomain->getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadData\n"; + return -1; + } + ElementalLoadIter& theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + int typeEL; + + while ((theLoad = theEleLoads()) != 0) { + const Vector &eleLoadData = theLoad->getData(typeEL, 1.0); + + int eleLoadDataSize = eleLoadData.Size(); + for (int i = 0; i < eleLoadDataSize; i++) { + data.push_back(eleLoadData(i)); + } + } + + } else { + opserr << "WARNING want - getEleLoadData \n"; + return -1; + } + + int size = data.size(); + + if (OPS_SetDoubleOutput(&size, data.data(), false) < 0) { + opserr << "WARNING failed to set output\n"; + return -1; + } + + return 0; +} + +int OPS_getNumElements() +{ + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + int nEles = theDomain->getNumElements(); + int size = 1; + + if (OPS_SetIntOutput(&size, &nEles, false) < 0) { + opserr << "WARNING failed to set output\n"; + return -1; + } + + return 0; +} + // Sensitivity:END ///////////////////////////////////////////// diff --git a/SRC/interpreter/OpenSeesSectionCommands.cpp b/SRC/interpreter/OpenSeesSectionCommands.cpp index 03ca3e873..94f3e45d6 100644 --- a/SRC/interpreter/OpenSeesSectionCommands.cpp +++ b/SRC/interpreter/OpenSeesSectionCommands.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,7 @@ void* OPS_ElasticShearSection3d(); void* OPS_FiberSection2d(); void* OPS_FiberSection3d(); void* OPS_FiberSectionWarping3d(); +void* OPS_FiberSectionAsym3d(); void* OPS_NDFiberSection2d(); void* OPS_NDFiberSection3d(); void* OPS_UniaxialFiber2d(); @@ -94,6 +96,7 @@ namespace { static FiberSection2d* theActiveFiberSection2d = 0; static FiberSection3d* theActiveFiberSection3d = 0; static FiberSectionWarping3d* theActiveFiberSectionWarping3d = 0; + static FiberSectionAsym3d* theActiveFiberSectionAsym3d = 0; static NDFiberSection2d* theActiveNDFiberSection2d = 0; static NDFiberSection3d* theActiveNDFiberSection3d = 0; @@ -220,6 +223,23 @@ namespace { return theSec; } + static void* OPS_FiberSectionAsym() + { + void* theSec = 0; + int ndm = OPS_GetNDM(); + int ndf = OPS_GetNDF(); + if (ndm == 2) { + //theSec = OPS_FiberSectionAsym2d(); + //theActiveFiberSectionAsym2d = (FiberSectionAsym2d*)theSec; + } + else if (ndm == 3) { + theSec = OPS_FiberSectionAsym3d(); + theActiveFiberSectionAsym3d = (FiberSectionAsym3d*)theSec; + } + + return theSec; + } + static void* OPS_FiberSectionThermal() { void* theSec = 0; @@ -1055,6 +1075,7 @@ namespace { functionMap.insert(std::make_pair("Fiber", &OPS_FiberSection)); functionMap.insert(std::make_pair("fiberSec", &OPS_FiberSection)); functionMap.insert(std::make_pair("FiberWarping", &OPS_FiberSectionWarping)); + functionMap.insert(std::make_pair("FiberAsym", &OPS_FiberSectionAsym)); functionMap.insert(std::make_pair("FiberThermal", &OPS_FiberSectionThermal)); functionMap.insert(std::make_pair("NDFiber", &OPS_NDFiberSection)); functionMap.insert(std::make_pair("Uniaxial", &OPS_UniaxialSection)); @@ -1092,6 +1113,7 @@ int OPS_Section() theActiveFiberSection2d = 0; theActiveFiberSection3d = 0; theActiveFiberSectionWarping3d = 0; + theActiveFiberSectionAsym3d = 0; theActiveNDFiberSection2d = 0; theActiveNDFiberSection3d = 0; @@ -1129,6 +1151,7 @@ int OPS_Section() theActiveFiberSection2d = 0; theActiveFiberSection3d = 0; theActiveFiberSectionWarping3d = 0; + theActiveFiberSectionAsym3d = 0; theActiveNDFiberSection2d = 0; theActiveNDFiberSection3d = 0; @@ -1152,7 +1175,7 @@ int OPS_Fiber() theFiber = (UniaxialFiber2d*) OPS_UniaxialFiber2d(); - } else if (theActiveFiberSection3d != 0 || theActiveFiberSectionWarping3d != 0 || theActiveFiberSection3dThermal!=0) { + } else if (theActiveFiberSection3d != 0 || theActiveFiberSectionWarping3d != 0 || theActiveFiberSectionAsym3d != 0 || theActiveFiberSection3dThermal!=0) { theFiber = (UniaxialFiber3d*) OPS_UniaxialFiber3d(); @@ -1187,6 +1210,10 @@ int OPS_Fiber() res = theActiveFiberSectionWarping3d->addFiber(*theFiber); + } else if (theActiveFiberSectionAsym3d != 0) { + + res = theActiveFiberSectionAsym3d->addFiber(*theFiber); + } else if (theActiveNDFiberSection2d != 0) { res = theActiveNDFiberSection2d->addFiber(*theFiber); @@ -1302,7 +1329,18 @@ int OPS_Patch() return -1; } theFiber = new UniaxialFiber3d(j,*material,area,cPos); - theActiveFiberSectionWarping3d->addFiber(*theFiber); + theActiveFiberSectionWarping3d->addFiber(*theFiber); + + } else if (theActiveFiberSectionAsym3d != 0) { + + material = OPS_getUniaxialMaterial(matTag); + if (material == 0) { + opserr << "WARNING material " << matTag << " cannot be found\n"; + delete thePatch; + return -1; + } + theFiber = new UniaxialFiber3d(j, *material, area, cPos); + theActiveFiberSectionAsym3d->addFiber(*theFiber); } else if (theActiveFiberSection3dThermal != 0) { @@ -1438,6 +1476,17 @@ int OPS_Layer() theFiber = new UniaxialFiber3d(j,*material,area,cPos); theActiveFiberSectionWarping3d->addFiber(*theFiber); + } else if (theActiveFiberSectionAsym3d != 0) { + + material = OPS_getUniaxialMaterial(matTag); + if (material == 0) { + opserr << "WARNING material " << matTag << " cannot be found\n"; + delete theLayer; + return -1; + } + theFiber = new UniaxialFiber3d(j, *material, area, cPos); + theActiveFiberSectionAsym3d->addFiber(*theFiber); + } else if (theActiveFiberSection3dThermal != 0) { material = OPS_getUniaxialMaterial(matTag); diff --git a/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp b/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp index d466bc214..d02bf487d 100644 --- a/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp +++ b/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp @@ -76,6 +76,8 @@ void* OPS_EPPGapMaterial(); void* OPS_ENTMaterial(); void* OPS_Steel01(); void* OPS_Steel02(); +void* OPS_SteelFractureDI(); +void* OPS_Steel02Fatigue(); void* OPS_Steel03(); void* OPS_Concrete01(); void* OPS_Steel4(); @@ -130,8 +132,12 @@ void* OPS_BWBN(); void* OPS_PySimple1(); void* OPS_TzSimple1(); void* OPS_QzSimple1(); +void* OPS_PySimple2(); +void* OPS_TzSimple2(); +void* OPS_QzSimple2(); void* OPS_PyLiq1(); void* OPS_TzLiq1(); +void* OPS_QzLiq1(); void* OPS_KikuchiAikenHDR(); void* OPS_KikuchiAikenLRB(); void* OPS_AxialSp(); @@ -174,6 +180,7 @@ void* OPS_IMKBilin(); void* OPS_IMKPinching(); void* OPS_IMKPeakOriented(); void* OPS_SLModel(); +void* OPS_SMAMaterial(); void* OPS_ArctangentBackbone(); void* OPS_BilinearBackbone(); @@ -224,6 +231,7 @@ namespace { uniaxialMaterialsMap.insert(std::make_pair("ENT", &OPS_ENTMaterial)); uniaxialMaterialsMap.insert(std::make_pair("Steel01", &OPS_Steel01)); uniaxialMaterialsMap.insert(std::make_pair("Steel02", &OPS_Steel02)); + uniaxialMaterialsMap.insert(std::make_pair("Steel02Fatigue", &OPS_Steel02Fatigue)); uniaxialMaterialsMap.insert(std::make_pair("Steel03", &OPS_Steel03)); uniaxialMaterialsMap.insert(std::make_pair("Concrete01", &OPS_Concrete01)); uniaxialMaterialsMap.insert(std::make_pair("Steel4", &OPS_Steel4)); @@ -292,8 +300,10 @@ namespace { uniaxialMaterialsMap.insert(std::make_pair("PySimple1", &OPS_PySimple1)); uniaxialMaterialsMap.insert(std::make_pair("TzSimple1", &OPS_TzSimple1)); uniaxialMaterialsMap.insert(std::make_pair("QzSimple1", &OPS_QzSimple1)); + uniaxialMaterialsMap.insert(std::make_pair("QzSimple2", &OPS_QzSimple2)); uniaxialMaterialsMap.insert(std::make_pair("PyLiq1", &OPS_PyLiq1)); uniaxialMaterialsMap.insert(std::make_pair("TzLiq1", &OPS_TzLiq1)); + uniaxialMaterialsMap.insert(std::make_pair("QzLiq1", &OPS_QzLiq1)); uniaxialMaterialsMap.insert(std::make_pair("KikuchiAikenHDR", &OPS_KikuchiAikenHDR)); uniaxialMaterialsMap.insert(std::make_pair("KikuchiAikenLRB", &OPS_KikuchiAikenLRB)); uniaxialMaterialsMap.insert(std::make_pair("AxialSp", &OPS_AxialSp)); @@ -338,10 +348,12 @@ namespace { uniaxialMaterialsMap.insert(std::make_pair("UniaxialJ2Plasticity", &OPS_UniaxialJ2Plasticity)); uniaxialMaterialsMap.insert(std::make_pair("OOHysteretic", &OPS_OOHystereticMaterial)); uniaxialMaterialsMap.insert(std::make_pair("UVCuniaxial", &OPS_UVCuniaxial)); + uniaxialMaterialsMap.insert(std::make_pair("SteelFractureDI", &OPS_SteelFractureDI)); 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)); + uniaxialMaterialsMap.insert(std::make_pair("SMA", &OPS_SMAMaterial)); uniaxialMaterialsMap.insert(std::make_pair("HystereticPoly", &OPS_HystereticPoly)); // Salvatore Sessa 14-Jan-2021 Mail: salvatore.sessa2@unina.it return 0; diff --git a/SRC/interpreter/PythonWrapper.cpp b/SRC/interpreter/PythonWrapper.cpp index 9febb1e84..09c2a1055 100644 --- a/SRC/interpreter/PythonWrapper.cpp +++ b/SRC/interpreter/PythonWrapper.cpp @@ -1127,6 +1127,18 @@ static PyObject *Py_ops_eleNodes(PyObject *self, PyObject *args) return wrapper->getResults(); } +static PyObject *Py_ops_eleType(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_eleType() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + static PyObject *Py_ops_nodeDOFs(PyObject *self, PyObject *args) { wrapper->resetCommandLine(PyTuple_Size(args), 1, args); @@ -1487,6 +1499,18 @@ static PyObject *Py_ops_sectionWeight(PyObject *self, PyObject *args) return wrapper->getResults(); } +static PyObject *Py_ops_sectionTag(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_sectionTag() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + static PyObject *Py_ops_sectionDisplacement(PyObject *self, PyObject *args) { wrapper->resetCommandLine(PyTuple_Size(args), 1, args); @@ -2004,6 +2028,66 @@ static PyObject *Py_ops_sensNodePressure(PyObject *self, PyObject *args) return wrapper->getResults(); } +static PyObject *Py_ops_getNumElements(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_getNumElements() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + +static PyObject *Py_ops_getEleClassTags(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_getEleClassTags() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + +static PyObject *Py_ops_getEleLoadClassTags(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_getEleLoadClassTags() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + +static PyObject *Py_ops_getEleLoadTags(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_getEleLoadTags() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + +static PyObject *Py_ops_getEleLoadData(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_getEleLoadData() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + static PyObject *Py_ops_randomVariable(PyObject *self, PyObject *args) { wrapper->resetCommandLine(PyTuple_Size(args), 1, args); @@ -2243,6 +2327,17 @@ static PyObject *Py_ops_pc(PyObject *self, PyObject *args) { return wrapper->getResults(); } +static PyObject *Py_ops_domainCommitTag(PyObject *self, PyObject *args) { + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_domainCommitTag() < 0) { + opserr << (void *)0; + return NULL; + } + + return wrapper->getResults(); +} + ///////////////////////////////////////////////// ////////////// Add Python commands ////////////// ///////////////////////////////////////////////// @@ -2330,6 +2425,7 @@ PythonWrapper::addOpenSeesCommands() addCommand("setNodeCoord", &Py_ops_setNodeCoord); addCommand("updateElementDomain", &Py_ops_updateElementDomain); addCommand("eleNodes", &Py_ops_eleNodes); + addCommand("eleType", &Py_ops_eleType); addCommand("nodeDOFs", &Py_ops_nodeDOFs); addCommand("nodeMass", &Py_ops_nodeMass); addCommand("nodePressure", &Py_ops_nodePressure); @@ -2360,6 +2456,7 @@ PythonWrapper::addOpenSeesCommands() addCommand("sectionFlexibility", &Py_ops_sectionFlexibility); addCommand("sectionLocation", &Py_ops_sectionLocation); addCommand("sectionWeight", &Py_ops_sectionWeight); + addCommand("sectionTag", &Py_ops_sectionTag); addCommand("sectionDisplacement", &Py_ops_sectionDisplacement); addCommand("cbdiDisplacement", &Py_ops_cbdiDisplacement); addCommand("basicDeformation", &Py_ops_basicDeformation); @@ -2404,6 +2501,11 @@ PythonWrapper::addOpenSeesCommands() addCommand("sensLambda", &Py_ops_sensLambda); addCommand("sensSectionForce", &Py_ops_sensSectionForce); addCommand("sensNodePressure", &Py_ops_sensNodePressure); + addCommand("getNumElements", &Py_ops_getNumElements); + addCommand("getEleClassTags", &Py_ops_getEleClassTags); + addCommand("getEleLoadClassTags", &Py_ops_getEleLoadClassTags); + addCommand("getEleLoadTags", &Py_ops_getEleLoadTags); + addCommand("getEleLoadData", &Py_ops_getEleLoadData); addCommand("randomVariable", &Py_ops_randomVariable); addCommand("getRVTags", &Py_ops_getRVTags); addCommand("getMean", &Py_ops_getRVMean); @@ -2427,6 +2529,7 @@ PythonWrapper::addOpenSeesCommands() addCommand("unloadingRule", &Py_ops_unloadingRule); addCommand("partition", &Py_ops_partition); addCommand("pressureConstraint", &Py_ops_pc); + addCommand("domainCommitTag", &Py_ops_domainCommitTag); PyMethodDef method = {NULL,NULL,0,NULL}; methodsOpenSees.push_back(method); diff --git a/SRC/interpreter/TclWrapper.cpp b/SRC/interpreter/TclWrapper.cpp index 99ca5b278..6f2fd2276 100644 --- a/SRC/interpreter/TclWrapper.cpp +++ b/SRC/interpreter/TclWrapper.cpp @@ -741,6 +741,14 @@ static int Tcl_ops_eleNodes(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_OK; } +static int Tcl_ops_eleType(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { + wrapper->resetCommandLine(argc, 1, argv); + + if (OPS_eleType() < 0) return TCL_ERROR; + + return TCL_OK; +} + static int Tcl_ops_nodeDOFs(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { wrapper->resetCommandLine(argc, 1, argv); @@ -1308,6 +1316,51 @@ static int Tcl_ops_sensNodePressure(ClientData clientData, Tcl_Interp *interp, i return TCL_OK; } +static int Tcl_ops_getNumElements(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + wrapper->resetCommandLine(argc, 1, argv); + + if (OPS_getNumElements() < 0) return TCL_ERROR; + + return TCL_OK; +} + +static int Tcl_ops_getEleClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + wrapper->resetCommandLine(argc, 1, argv); + + if (OPS_getEleClassTags() < 0) return TCL_ERROR; + + return TCL_OK; +} + +static int Tcl_ops_getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + wrapper->resetCommandLine(argc, 1, argv); + + if (OPS_getEleLoadClassTags() < 0) return TCL_ERROR; + + return TCL_OK; +} + +static int Tcl_ops_getEleLoadTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + wrapper->resetCommandLine(argc, 1, argv); + + if (OPS_getEleLoadTags() < 0) return TCL_ERROR; + + return TCL_OK; +} + +static int Tcl_ops_getEleLoadData(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + wrapper->resetCommandLine(argc, 1, argv); + + if (OPS_getEleLoadData() < 0) return TCL_ERROR; + + return TCL_OK; +} + static int Tcl_ops_randomVariable(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { wrapper->resetCommandLine(argc, 1, argv); @@ -1653,6 +1706,11 @@ TclWrapper::addOpenSeesCommands(Tcl_Interp* interp) addCommand(interp,"sensLambda", &Tcl_ops_sensLambda); addCommand(interp,"sensSectionForce", &Tcl_ops_sensSectionForce); addCommand(interp,"sensNodePressure", &Tcl_ops_sensNodePressure); + addCommand(interp,"getNumElements", &Tcl_ops_getNumElements); + addCommand(interp,"getEleClassTags", &Tcl_ops_getEleClassTags); + addCommand(interp,"getEleLoadClassTags", &Tcl_ops_getEleLoadClassTags); + addCommand(interp,"getEleLoadTags", &Tcl_ops_getEleLoadTags); + addCommand(interp,"getEleLoadData", &Tcl_ops_getEleLoadData); addCommand(interp,"randomVariable", &Tcl_ops_randomVariable); addCommand(interp,"getRVTags", &Tcl_ops_getRVTags); addCommand(interp,"getMean", &Tcl_ops_getRVMean); diff --git a/SRC/material/nD/AcousticMedium.cpp b/SRC/material/nD/AcousticMedium.cpp index 862f0d185..13a837b55 100644 --- a/SRC/material/nD/AcousticMedium.cpp +++ b/SRC/material/nD/AcousticMedium.cpp @@ -281,7 +281,7 @@ AcousticMedium::recvSelf (int commitTag, Channel &theChannel, -Response * AcousticMedium::setResponse (const char **argv, int argc, OPS_Stream &matInformation) { +Response * AcousticMedium::setResponse (const char **argv, int argc, OPS_Stream &output) { if (strcmp(argv[0],"sigma") == 0 ) return new MaterialResponse(this, 1, sigma); @@ -290,7 +290,7 @@ Response * AcousticMedium::setResponse (const char **argv, int argc, OPS_Stream return new MaterialResponse(this, 2, epsilon); - return 0; + return NDMaterial::setResponse(argv, argc, output); }; @@ -312,7 +312,7 @@ int AcousticMedium::getResponse (int responseID, Information &matInfo) { } - return 0; + return NDMaterial::getResponse(responseID, matInfo); }; diff --git a/SRC/material/nD/AcousticMedium.h b/SRC/material/nD/AcousticMedium.h index 105d19c34..fda5a0ea8 100644 --- a/SRC/material/nD/AcousticMedium.h +++ b/SRC/material/nD/AcousticMedium.h @@ -69,7 +69,7 @@ class AcousticMedium : public NDMaterial FEM_ObjectBroker &theBroker); - Response *setResponse (const char **argv, int argc, OPS_Stream &matInformation); + Response *setResponse (const char **argv, int argc, OPS_Stream &output); int getResponse (int responseID, Information &matInformation); diff --git a/SRC/material/nD/CapPlasticity.cpp b/SRC/material/nD/CapPlasticity.cpp index 4caa309d6..819b08af9 100644 --- a/SRC/material/nD/CapPlasticity.cpp +++ b/SRC/material/nD/CapPlasticity.cpp @@ -377,7 +377,6 @@ int CapPlasticity::sendSelf(int commitTag, Channel &theChannel) {return 0;}; int CapPlasticity::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker ) {return 0;}; -//Response * CapPlasticity::setResponse (const char **argv, int argc, Information &matInformation) { Response* CapPlasticity::setResponse (const char **argv, int argc, OPS_Stream &output) { @@ -404,7 +403,7 @@ CapPlasticity::setResponse (const char **argv, int argc, OPS_Stream &output) { } else - return 0; + return NDMaterial::setResponse(argv, argc, output); }; @@ -447,7 +446,7 @@ int CapPlasticity::getResponse (int responseID, Information &matInfo) { return 0; } - return 0; + return NDMaterial::getResponse(responseID, matInfo); }; diff --git a/SRC/material/nD/LinearCap.cpp b/SRC/material/nD/LinearCap.cpp index c78e0a653..e2cbbd5fd 100644 --- a/SRC/material/nD/LinearCap.cpp +++ b/SRC/material/nD/LinearCap.cpp @@ -315,7 +315,7 @@ int LinearCap::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker ) {return 0;}; -Response * LinearCap::setResponse (const char **argv, int argc, OPS_Stream &matInformation) { +Response * LinearCap::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, stress); @@ -331,7 +331,7 @@ Response * LinearCap::setResponse (const char **argv, int argc, OPS_Stream &matI return new MaterialResponse(this, 4, plastStrain); - return 0; + return NDMaterial::setResponse(argv, argc, output); }; @@ -363,7 +363,7 @@ int LinearCap::getResponse (int responseID, Information &matInfo) { } - return 0; + return NDMaterial::getResponse(responseID, matInfo); }; diff --git a/SRC/material/nD/LinearCap.h b/SRC/material/nD/LinearCap.h index c88565350..c842e787f 100644 --- a/SRC/material/nD/LinearCap.h +++ b/SRC/material/nD/LinearCap.h @@ -62,7 +62,7 @@ class LinearCap : public NDMaterial { int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker ) ; - Response *setResponse (const char **argv, int argc, OPS_Stream &matInformation); + Response *setResponse (const char **argv, int argc, OPS_Stream &output); int getResponse (int responseID, Information &matInformation); void Print(OPS_Stream &s, int flag = 0) ; diff --git a/SRC/material/nD/PlateFiberMaterial.cpp b/SRC/material/nD/PlateFiberMaterial.cpp index 1345b6f50..2f88d8c33 100644 --- a/SRC/material/nD/PlateFiberMaterial.cpp +++ b/SRC/material/nD/PlateFiberMaterial.cpp @@ -79,9 +79,11 @@ void* OPS_PlateFiberMaterial() //null constructor PlateFiberMaterial::PlateFiberMaterial() : NDMaterial(0, ND_TAG_PlateFiberMaterial), +theMaterial(0), strain(5) { - + Tstrain22 = 0.0; + Cstrain22 = 0.0; } diff --git a/SRC/material/nD/UWmaterials/InitialStateAnalysisWrapper.h b/SRC/material/nD/UWmaterials/InitialStateAnalysisWrapper.h index 733314f2c..94852009d 100644 --- a/SRC/material/nD/UWmaterials/InitialStateAnalysisWrapper.h +++ b/SRC/material/nD/UWmaterials/InitialStateAnalysisWrapper.h @@ -84,6 +84,7 @@ class InitialStateAnalysisWrapper : public NDMaterial friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet int getMainClassTag(); // sends class tag of main material object diff --git a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.cpp b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.cpp index 50fa9f415..aa8905789 100644 --- a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.cpp +++ b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.cpp @@ -26,6 +26,8 @@ // #include +#include +#include #include #include #include @@ -544,14 +546,36 @@ void J2CyclicBoundingSurface::Print(OPS_Stream & s, int flag) { } -NDMaterial* -J2CyclicBoundingSurface::getCopy(void) -{ +NDMaterial* J2CyclicBoundingSurface::getCopy(void) +{ opserr << "J2CyclicBoundingSurface::getCopy -- subclass responsibilitynot implemented.\n"; exit(-1); return 0; } +NDMaterial* +J2CyclicBoundingSurface::getCopy(const char* type) +{ + if (strcmp(type, "ThreeDimensional") == 0 || strcmp(type, "3D") == 0) { + J2CyclicBoundingSurface3D* clone; + clone = new J2CyclicBoundingSurface3D(this->getTag(), m_shear, m_bulk, m_su, m_density, m_h_par, m_m_par, m_h0_par, m_chi, m_beta); + return clone; + } + else if (strcmp(type, "PlaneStrain2D") == 0 || strcmp(type, "PlaneStrain") == 0) { + J2CyclicBoundingSurfacePlaneStrain* clone; + clone = new J2CyclicBoundingSurfacePlaneStrain(this->getTag(), m_shear, m_bulk, m_su, m_density, m_h_par, m_m_par, m_h0_par, m_chi, m_beta); + return clone; + } + else { + opserr << "J2CyclicBoundingSurface::getCopy failed to get copy: " << type << endln; + return 0; + } + + //opserr << "J2CyclicBoundingSurface::getCopy -- subclass responsibilitynot implemented.\n"; + //exit(-1); + //return 0; +} + const char* J2CyclicBoundingSurface::getType(void) const { @@ -566,21 +590,6 @@ J2CyclicBoundingSurface::getOrder(void) const return 0; } - -NDMaterial * J2CyclicBoundingSurface::getCopy(const char * type) -{ - - if (strcmp(type, "ThreeDimensional") == 0 || strcmp(type, "3D") == 0) { - J2CyclicBoundingSurface *clone; - clone = new J2CyclicBoundingSurface(this->getTag(), m_shear, m_bulk, m_su, m_density, m_h_par, m_m_par, m_h0_par, m_chi, m_beta); - return clone; - } - else { - opserr << "J2CyclicBoundingSurface::getCopy failed to get copy: " << type << endln; - return 0; - } -} - int J2CyclicBoundingSurface::commitState() { @@ -676,46 +685,45 @@ J2CyclicBoundingSurface::recvSelf(int commitTag, Channel &theChannel, return 0; } -// get the strain and integrate plasticity equations -int -J2CyclicBoundingSurface::setTrialStrain(const Vector &strain_from_element) -{ - m_strain_np1 = strain_from_element; - this->integrate(); - - return 0; -} - -// unused trial strain functions -int -J2CyclicBoundingSurface::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& -J2CyclicBoundingSurface::getStrain() -{ - return m_strain_np1; -} - -// send back the stress -const Vector& -J2CyclicBoundingSurface::getStress() -{ - //return m_stress_np1; - return m_stress_t_n1; -} - +//// get the strain and integrate plasticity equations +//int +//J2CyclicBoundingSurface::setTrialStrain(const Vector &strain_from_element) +//{ +// m_strain_np1 = strain_from_element; +// this->integrate(); +// +// return 0; +//} +// +//// unused trial strain functions +//int +//J2CyclicBoundingSurface::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& +//J2CyclicBoundingSurface::getStrain() +//{ +// return m_strain_np1; +//} +// +//// send back the stress +//const Vector& +//J2CyclicBoundingSurface::getStress() +//{ +// //return m_stress_np1; +// return m_stress_t_n1; +//} // send back the tangent const Matrix& -J2CyclicBoundingSurface::getTangent() +J2CyclicBoundingSurface::calcTangent() { // Force elastic response if (m_ElastFlag == 0) { @@ -759,8 +767,8 @@ J2CyclicBoundingSurface::getTangent() } // send back the tangent -const Matrix& -J2CyclicBoundingSurface::getInitialTangent() -{ - return m_Ce; -} +//const Matrix& +//J2CyclicBoundingSurface::calcInitialTangent() +//{ +// return m_Ce; +//} diff --git a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.h b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.h index 43ea436af..09af64be6 100644 --- a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.h +++ b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface.h @@ -107,20 +107,20 @@ class J2CyclicBoundingSurface : public NDMaterial { virtual const Matrix& getDampTangent(); - virtual int setTrialStrain(const Vector &strain_from_element); - virtual int setTrialStrain(const Vector &v, const Vector &r); + //virtual int setTrialStrain(const Vector &strain_from_element); + //virtual int setTrialStrain(const Vector &v, const Vector &r); - // send back the strain - virtual const Vector& getStrain(); + //// send back the strain + //virtual const Vector& getStrain(); - // send back the stress - virtual const Vector& getStress(); + //// send back the stress + //virtual const Vector& getStress(); - // send back the tangent - virtual const Matrix& getTangent(); + //// send back the tangent + //virtual const Matrix& getTangent(); - // send back the tangent - virtual const Matrix& getInitialTangent(); + //// send back the tangent + //virtual const Matrix& getInitialTangent(); protected: @@ -178,6 +178,7 @@ class J2CyclicBoundingSurface : public NDMaterial { void viscoElastic_integrator(); void calcInitialTangent(); + const Matrix& calcTangent(); //hardening function double H(double kappa); diff --git a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.cpp b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.cpp index 59ff7c992..f4b75aa4c 100644 --- a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.cpp +++ b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.cpp @@ -26,6 +26,9 @@ // Description: This file contains the implementation of the J2CyclicBoundingSurface3D class. #include "J2CyclicBoundingSurface3D.h" +Matrix J2CyclicBoundingSurface3D::tangent(3, 3); + + // 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) @@ -107,17 +110,12 @@ J2CyclicBoundingSurface3D::getStress() const Matrix& J2CyclicBoundingSurface3D::getTangent() { - Matrix C(6, 6); - C = J2CyclicBoundingSurface::getTangent(); - return C; + return calcTangent(); } // send back the tangent const Matrix& J2CyclicBoundingSurface3D::getInitialTangent() { - Matrix C(6, 6); - J2CyclicBoundingSurface::calcInitialTangent(); - C = m_Ce; - return C; + return m_Ce; } \ No newline at end of file diff --git a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.h b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.h index dd26e4968..0be72c6d6 100644 --- a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.h +++ b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurface3D.h @@ -67,7 +67,7 @@ class J2CyclicBoundingSurface3D : public J2CyclicBoundingSurface const Matrix& getInitialTangent(); private : - + static Matrix tangent; }; diff --git a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.cpp b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.cpp index e53eb0ff0..4ea71d16f 100644 --- a/SRC/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.cpp +++ b/SRC/material/nD/UWmaterials/J2CyclicBoundingSurfacePlaneStrain.cpp @@ -121,7 +121,7 @@ const Matrix& J2CyclicBoundingSurfacePlaneStrain::getTangent() { Matrix C(6,6); - C = J2CyclicBoundingSurface::getTangent(); + C = J2CyclicBoundingSurface::calcTangent(); tangent(0,0) = C(0,0); tangent(0,1) = C(0,1); diff --git a/SRC/material/nD/soil/FluidSolidPorousMaterial.h b/SRC/material/nD/soil/FluidSolidPorousMaterial.h index ab3bda800..d30289ff1 100644 --- a/SRC/material/nD/soil/FluidSolidPorousMaterial.h +++ b/SRC/material/nD/soil/FluidSolidPorousMaterial.h @@ -92,8 +92,9 @@ class FluidSolidPorousMaterial : public NDMaterial int updateParameter(int responseID, Information &eleInformation); // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. - friend class PyLiq1; - friend class TzLiq1; + friend class PyLiq1; + friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/material/nD/soil/MultiYieldSurfaceClay.h b/SRC/material/nD/soil/MultiYieldSurfaceClay.h index 552bdb205..9fb285246 100644 --- a/SRC/material/nD/soil/MultiYieldSurfaceClay.h +++ b/SRC/material/nD/soil/MultiYieldSurfaceClay.h @@ -104,8 +104,9 @@ class MultiYieldSurfaceClay : public NDMaterial //void setCurrentStress(const Vector stress) { currentStress=T2Vector(stress); } // int updateParameter(int responseID, Information &eleInformation,int Yang); - friend class PyLiq1; + friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/material/nD/soil/PressureDependMultiYield02.h b/SRC/material/nD/soil/PressureDependMultiYield02.h index e08d1218c..cdf0c0d81 100644 --- a/SRC/material/nD/soil/PressureDependMultiYield02.h +++ b/SRC/material/nD/soil/PressureDependMultiYield02.h @@ -120,6 +120,7 @@ class PressureDependMultiYield02 : public NDMaterial // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/material/nD/soil/PressureDependMultiYield03.h b/SRC/material/nD/soil/PressureDependMultiYield03.h index 5ae2b5722..0efb1a7f0 100644 --- a/SRC/material/nD/soil/PressureDependMultiYield03.h +++ b/SRC/material/nD/soil/PressureDependMultiYield03.h @@ -118,6 +118,7 @@ class PressureDependMultiYield03 : public NDMaterial // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/material/nD/soil/PressureIndependMultiYield.h b/SRC/material/nD/soil/PressureIndependMultiYield.h index d4101607b..1a21fa7da 100644 --- a/SRC/material/nD/soil/PressureIndependMultiYield.h +++ b/SRC/material/nD/soil/PressureIndependMultiYield.h @@ -105,6 +105,7 @@ class PressureIndependMultiYield : public NDMaterial // RWB; PyLiq1 & TzLiq1 need to see the excess pore pressure and initial stresses. friend class PyLiq1; friend class TzLiq1; + friend class QzLiq1; // Sumeet protected: diff --git a/SRC/material/nD/soil/TclUpdateMaterialStageCommand.cpp b/SRC/material/nD/soil/TclUpdateMaterialStageCommand.cpp index 15d0050ce..02578139d 100644 --- a/SRC/material/nD/soil/TclUpdateMaterialStageCommand.cpp +++ b/SRC/material/nD/soil/TclUpdateMaterialStageCommand.cpp @@ -14,6 +14,7 @@ #include #include +#include #include diff --git a/SRC/material/section/Elliptical2.cpp b/SRC/material/section/Elliptical2.cpp index 98bfe91c7..9b10772fa 100644 --- a/SRC/material/section/Elliptical2.cpp +++ b/SRC/material/section/Elliptical2.cpp @@ -594,7 +594,7 @@ Elliptical2::getResponse(int responseID, Information &eleInformation) return eleInformation.setVector(theVec); } else - return -1; + return SectionForceDeformation::getResponse(responseID, eleInformation); } int diff --git a/SRC/material/section/FiberSection2d.cpp b/SRC/material/section/FiberSection2d.cpp index a7d68651a..6e6172c93 100644 --- a/SRC/material/section/FiberSection2d.cpp +++ b/SRC/material/section/FiberSection2d.cpp @@ -422,15 +422,15 @@ FiberSection2d::getInitialTangent(void) static double fiberLocs[10000]; static double fiberArea[10000]; - + if (sectionIntegr != 0) { sectionIntegr->getFiberLocations(numFibers, fiberLocs); - sectionIntegr->getFiberWeights(numFibers, fiberArea); + sectionIntegr->getFiberWeights(numFibers, fiberArea); } else { for (int i = 0; i < numFibers; i++) { fiberLocs[i] = matData[2*i]; - fiberArea[i] = matData[2*i+1]; + fiberArea[i] = matData[2*i+1]; } } @@ -857,10 +857,21 @@ Response* FiberSection2d::setResponse(const char **argv, int argc, OPS_Stream &output) { - Response *theResponse =0; + Response *theResponse = 0; + + if (argc > 2 && strcmp(argv[0],"fiber") == 0) { - if (argc > 2 || strcmp(argv[0],"fiber") == 0) { + static double fiberLocs[10000]; + if (sectionIntegr != 0) { + sectionIntegr->getFiberLocations(numFibers, fiberLocs); + } + else { + for (int i = 0; i < numFibers; i++) { + fiberLocs[i] = matData[2*i]; + } + } + int key = numFibers; int passarg = 2; @@ -880,9 +891,10 @@ FiberSection2d::setResponse(const char **argv, int argc, // Find first fiber with specified material tag for (j = 0; j < numFibers; j++) { if (matTag == theMaterials[j]->getTag()) { - ySearch = matData[2*j]; + //ySearch = matData[2*j]; + ySearch = fiberLocs[j]; dy = ySearch-yCoord; - closestDist = fabs(dy); + closestDist = dy*dy; key = j; break; } @@ -890,9 +902,10 @@ FiberSection2d::setResponse(const char **argv, int argc, // Search the remaining fibers for ( ; j < numFibers; j++) { if (matTag == theMaterials[j]->getTag()) { - ySearch = matData[2*j]; + //ySearch = matData[2*j]; + ySearch = fiberLocs[j]; dy = ySearch-yCoord; - distance = fabs(dy); + distance = dy*dy; if (distance < closestDist) { closestDist = distance; key = j; @@ -909,15 +922,17 @@ FiberSection2d::setResponse(const char **argv, int argc, double ySearch, dy; double distance; - ySearch = matData[0]; + //ySearch = matData[0]; + ySearch = fiberLocs[0]; dy = ySearch-yCoord; closestDist = fabs(dy); key = 0; for (int j = 1; j < numFibers; j++) { - ySearch = matData[2*j]; + //ySearch = matData[2*j]; + ySearch = fiberLocs[j]; dy = ySearch-yCoord; - distance = fabs(dy); + distance = dy*dy; if (distance < closestDist) { closestDist = distance; key = j; @@ -932,13 +947,11 @@ FiberSection2d::setResponse(const char **argv, int argc, output.attr("zLoc",0.0); output.attr("area",matData[2*key+1]); - theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); + theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); output.endTag(); } - return theResponse; - } else if (strcmp(argv[0],"fiberData") == 0) { int numData = numFibers*5; @@ -955,26 +968,27 @@ FiberSection2d::setResponse(const char **argv, int argc, output.endTag(); } Vector theResponseData(numData); - return theResponse = new MaterialResponse(this, 5, theResponseData); - + theResponse = new MaterialResponse(this, 5, theResponseData); } else if ((strcmp(argv[0],"numFailedFiber") == 0) || (strcmp(argv[0],"numFiberFailed") == 0)) { int count = 0; - return theResponse = new MaterialResponse(this, 6, count); + theResponse = new MaterialResponse(this, 6, count); } else if ((strcmp(argv[0],"sectionFailed") == 0) || (strcmp(argv[0],"hasSectionFailed") == 0) || (strcmp(argv[0],"hasFailed") == 0)) { int count = 0; - return theResponse = new MaterialResponse(this, 7, count); + 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()); + theResponse = new MaterialResponse(this, 8, getEnergy()); } -// If not a fiber response, call the base class method -return SectionForceDeformation::setResponse(argv, argc, output); + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); + + return theResponse; } @@ -1020,10 +1034,10 @@ FiberSection2d::getResponse(int responseID, Information §Info) return sectInfo.setInt(count); } - //by SAJalali - else if (responseID == 8) { - return sectInfo.setDouble(getEnergy()); - } + //by SAJalali + else if (responseID == 8) { + return sectInfo.setDouble(getEnergy()); + } return SectionForceDeformation::getResponse(responseID, sectInfo); } diff --git a/SRC/material/section/FiberSection2dThermal.cpp b/SRC/material/section/FiberSection2dThermal.cpp index 033305d6a..a2e46743f 100644 --- a/SRC/material/section/FiberSection2dThermal.cpp +++ b/SRC/material/section/FiberSection2dThermal.cpp @@ -1069,212 +1069,90 @@ Response* FiberSection2dThermal::setResponse(const char **argv, int argc, OPS_Stream &output) { - const ID &type = this->getType(); - int typeSize = this->getOrder(); - - Response *theResponse =0; - - output.tag("SectionOutput"); - output.attr("secType", this->getClassType()); - output.attr("secTag", this->getTag()); - - // deformations - if (strcmp(argv[0],"deformations") == 0 || strcmp(argv[0],"deformation") == 0) { - for (int i=0; igetSectionDeformation()); - - // forces - } else if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0) { - for (int i=0; igetStressResultant()); - - // force and deformation - } else if (strcmp(argv[0],"forceAndDeformation") == 0) { - for (int j=0; jgetOrder())); - - } - - else { - if (argc > 2 || strcmp(argv[0],"fiber") == 0) { - - int key = numFibers; - int passarg = 2; - - if (argc <= 3) { // fiber number was input directly - - key = atoi(argv[1]); - - } else if (argc > 4) { // find fiber closest to coord. with mat tag - - int matTag = atoi(argv[3]); - double yCoord = atof(argv[1]); - - double closestDist; - double ySearch, dy; - double distance; - int j; - // Find first fiber with specified material tag - for (j = 0; j < numFibers; j++) { - if (matTag == theMaterials[j]->getTag()) { - ySearch = matData[2*j]; - dy = ySearch-yCoord; - closestDist = fabs(dy); - key = j; - break; - } - } - // Search the remaining fibers - for ( ; j < numFibers; j++) { - if (matTag == theMaterials[j]->getTag()) { - ySearch = matData[2*j]; - dy = ySearch-yCoord; - distance = fabs(dy); - if (distance < closestDist) { - closestDist = distance; - key = j; - } - } + Response *theResponse = 0; + + if (argc > 2 && strcmp(argv[0],"fiber") == 0) { + + int key = numFibers; + int passarg = 2; + + if (argc <= 3) { // fiber number was input directly + + key = atoi(argv[1]); + + } else if (argc > 4) { // find fiber closest to coord. with mat tag + + int matTag = atoi(argv[3]); + double yCoord = atof(argv[1]); + + double closestDist; + double ySearch, dy; + double distance; + int j; + // Find first fiber with specified material tag + for (j = 0; j < numFibers; j++) { + if (matTag == theMaterials[j]->getTag()) { + ySearch = matData[2*j]; + dy = ySearch-yCoord; + closestDist = fabs(dy); + key = j; + break; } - passarg = 4; } - - else { // fiber near-to coordinate specified - - double yCoord = atof(argv[1]); - double closestDist; - double ySearch, dy; - double distance; - - ySearch = matData[0]; - dy = ySearch-yCoord; - closestDist = fabs(dy); - key = 0; - for (int j = 1; j < numFibers; j++) { + // Search the remaining fibers + for ( ; j < numFibers; j++) { + if (matTag == theMaterials[j]->getTag()) { ySearch = matData[2*j]; dy = ySearch-yCoord; - distance = fabs(dy); if (distance < closestDist) { closestDist = distance; key = j; } } - passarg = 3; } - - if (key < numFibers && key >= 0) { - output.tag("FiberOutput"); - output.attr("yLoc",matData[2*key]); - output.attr("zLoc",0.0); - output.attr("area",matData[2*key+1]); - - theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); - - output.endTag(); + passarg = 4; + } + + else { // fiber near-to coordinate specified + + double yCoord = atof(argv[1]); + double closestDist; + double ySearch, dy; + double distance; + + ySearch = matData[0]; + dy = ySearch-yCoord; + closestDist = fabs(dy); + key = 0; + for (int j = 1; j < numFibers; j++) { + ySearch = matData[2*j]; + dy = ySearch-yCoord; + + distance = fabs(dy); + if (distance < closestDist) { + closestDist = distance; + key = j; + } } + passarg = 3; + } + + if (key < numFibers && key >= 0) { + output.tag("FiberOutput"); + output.attr("yLoc",matData[2*key]); + output.attr("zLoc",0.0); + output.attr("area",matData[2*key+1]); + + theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); + + output.endTag(); } } - output.endTag(); + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); + return theResponse; } diff --git a/SRC/material/section/FiberSection3d.cpp b/SRC/material/section/FiberSection3d.cpp index b39403178..a14ab44ad 100644 --- a/SRC/material/section/FiberSection3d.cpp +++ b/SRC/material/section/FiberSection3d.cpp @@ -1084,128 +1084,113 @@ FiberSection3d::Print(OPS_Stream &s, int flag) Response* FiberSection3d::setResponse(const char **argv, int argc, OPS_Stream &output) { + Response *theResponse = 0; + + if (argc > 2 && strcmp(argv[0],"fiber") == 0) { - const ID &type = this->getType(); - int typeSize = this->getOrder(); - - Response *theResponse =0; - - output.tag("SectionOutput"); - output.attr("secType", this->getClassType()); - output.attr("secTag", this->getTag()); - - // deformations - if (strcmp(argv[0],"deformations") == 0 || strcmp(argv[0],"deformation") == 0) { - for (int i=0; igetFiberLocations(numFibers, yLocs, zLocs); + } + else { + for (int i = 0; i < numFibers; i++) { + yLocs[i] = matData[3*i]; + zLocs[i] = matData[3*i+1]; } } - theResponse = new MaterialResponse(this, 1, this->getSectionDeformation()); - - // forces - } else if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0) { - for (int i=0; i 4) { // find fiber closest to coord. with mat tag + int matTag = atoi(argv[3]); + double yCoord = atof(argv[1]); + double zCoord = atof(argv[2]); + double closestDist = 0.0; + double ySearch, zSearch, dy, dz; + double distance; + int j; + + // Find first fiber with specified material tag + for (j = 0; j < numFibers; j++) { + if (matTag == theMaterials[j]->getTag()) { + //ySearch = matData[3*j]; + //zSearch = matData[3*j+1]; + ySearch = yLocs[j]; + zSearch = zLocs[j]; + dy = ySearch-yCoord; + dz = zSearch-zCoord; + closestDist = dy*dy + dz*dz; + key = j; + break; + } } - } - theResponse = new MaterialResponse(this, 2, this->getStressResultant()); - - // force and deformation - } else if (strcmp(argv[0],"forceAndDeformation") == 0) { - for (int i=0; igetTag()) { + //ySearch = matData[3*j]; + //zSearch = matData[3*j+1]; + ySearch = yLocs[j]; + zSearch = zLocs[j]; + dy = ySearch-yCoord; + dz = zSearch-zCoord; + distance = dy*dy + dz*dz; + if (distance < closestDist) { + closestDist = distance; + key = j; + } + } } + passarg = 4; } - for (int j=0; j= 0) { + output.tag("FiberOutput"); + output.attr("yLoc",matData[3*key]); + output.attr("zLoc",matData[3*key+1]); + output.attr("area",matData[3*key+2]); + + theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); + + output.endTag(); } - - theResponse = new MaterialResponse(this, 4, Vector(2*this->getOrder())); } else if (strcmp(argv[0],"fiberData") == 0) { int numData = numFibers*5; @@ -1234,103 +1219,16 @@ FiberSection3d::setResponse(const char **argv, int argc, OPS_Stream &output) (strcmp(argv[0],"hasFailed") == 0)) { int count = 0; - return theResponse = new MaterialResponse(this, 7, count); + 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, 10, getEnergy()); + theResponse = new MaterialResponse(this, 10, getEnergy()); } + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); - else { - if (argc > 2 || strcmp(argv[0],"fiber") == 0) { - - int key = numFibers; - int passarg = 2; - - if (argc <= 3) { // fiber number was input directly - - key = atoi(argv[1]); - - } else if (argc > 4) { // find fiber closest to coord. with mat tag - int matTag = atoi(argv[3]); - double yCoord = atof(argv[1]); - double zCoord = atof(argv[2]); - double closestDist = 0.0; - double ySearch, zSearch, dy, dz; - double distance; - int j; - - // Find first fiber with specified material tag - for (j = 0; j < numFibers; j++) { - if (matTag == theMaterials[j]->getTag()) { - ySearch = matData[3*j]; - zSearch = matData[3*j+1]; - dy = ySearch-yCoord; - dz = zSearch-zCoord; - closestDist = sqrt(dy*dy + dz*dz); - key = j; - break; - } - } - - // Search the remaining fibers - for ( ; j < numFibers; j++) { - if (matTag == theMaterials[j]->getTag()) { - ySearch = matData[3*j]; - zSearch = matData[3*j+1]; - dy = ySearch-yCoord; - dz = zSearch-zCoord; - distance = sqrt(dy*dy + dz*dz); - if (distance < closestDist) { - closestDist = distance; - key = j; - } - } - } - passarg = 4; - } - - else { // fiber near-to coordinate specified - double yCoord = atof(argv[1]); - double zCoord = atof(argv[2]); - double closestDist; - double ySearch, zSearch, dy, dz; - double distance; - ySearch = matData[0]; - zSearch = matData[1]; - dy = ySearch-yCoord; - dz = zSearch-zCoord; - closestDist = sqrt(dy*dy + dz*dz); - key = 0; - for (int j = 1; j < numFibers; j++) { - ySearch = matData[3*j]; - zSearch = matData[3*j+1]; - dy = ySearch-yCoord; - dz = zSearch-zCoord; - distance = sqrt(dy*dy + dz*dz); - if (distance < closestDist) { - closestDist = distance; - key = j; - } - } - passarg = 3; - } - - if (key < numFibers && key >= 0) { - output.tag("FiberOutput"); - output.attr("yLoc",matData[3*key]); - output.attr("zLoc",matData[3*key+1]); - output.attr("area",matData[3*key+2]); - - theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); - - output.endTag(); - } - } - } - - output.endTag(); return theResponse; } diff --git a/SRC/material/section/FiberSection3dThermal.cpp b/SRC/material/section/FiberSection3dThermal.cpp index b595a36a8..8267e3d6a 100644 --- a/SRC/material/section/FiberSection3dThermal.cpp +++ b/SRC/material/section/FiberSection3dThermal.cpp @@ -974,129 +974,93 @@ FiberSection3dThermal::Print(OPS_Stream &s, int flag) Response* FiberSection3dThermal::setResponse(const char **argv, int argc, OPS_Stream &output) { - - const ID &type = this->getType(); - int typeSize = this->getOrder(); - - Response *theResponse =0; - - output.tag("SectionOutput"); - output.attr("secType", this->getClassType()); - output.attr("secTag", this->getTag()); - - // deformations - if (strcmp(argv[0],"deformations") == 0 || strcmp(argv[0],"deformation") == 0) { - for (int i=0; i 2 && strcmp(argv[0],"fiber") == 0) { + + int key = numFibers; + int passarg = 2; + + if (argc <= 3) { // fiber number was input directly + + key = atoi(argv[1]); + + } else if (argc > 4) { // find fiber closest to coord. with mat tag + int matTag = atoi(argv[3]); + double yCoord = atof(argv[1]); + double zCoord = atof(argv[2]); + double closestDist; + double ySearch, zSearch, dy, dz; + double distance; + int j; + + // Find first fiber with specified material tag + for (j = 0; j < numFibers; j++) { + if (matTag == theMaterials[j]->getTag()) { + ySearch = -matData[3*j]; + zSearch = matData[3*j+1]; + dy = ySearch-yCoord; + dz = zSearch-zCoord; + closestDist = sqrt(dy*dy + dz*dz); + key = j; + break; + } } - } - theResponse = new MaterialResponse(this, 1, this->getSectionDeformation()); - - // forces - } else if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0) { - for (int i=0; igetTag()) { + ySearch = -matData[3*j]; + zSearch = matData[3*j+1]; + dy = ySearch-yCoord; + dz = zSearch-zCoord; + distance = sqrt(dy*dy + dz*dz); + if (distance < closestDist) { + closestDist = distance; + key = j; + } + } } + passarg = 4; } - theResponse = new MaterialResponse(this, 2, this->getStressResultant()); - - // force and deformation - } else if (strcmp(argv[0],"forceAndDeformation") == 0) { - for (int i=0; i= 0) { + output.tag("FiberOutput"); + output.attr("yLoc",matData[3*key]); + output.attr("zLoc",matData[3*key+1]); + output.attr("area",matData[3*key+2]); + + theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); + + output.endTag(); } - theResponse = new MaterialResponse(this, 4, Vector(2*this->getOrder())); - } else if (strcmp(argv[0],"fiberData") == 0) { int numData = numFibers*5; for (int j = 0; j < numFibers; j++) { @@ -1115,97 +1079,9 @@ FiberSection3dThermal::setResponse(const char **argv, int argc, OPS_Stream &outp theResponse = new MaterialResponse(this, 5, theResponseData); } + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); - else { - if (argc > 2 || strcmp(argv[0],"fiber") == 0) { - - int key = numFibers; - int passarg = 2; - - - if (argc <= 3) { // fiber number was input directly - - key = atoi(argv[1]); - - } else if (argc > 4) { // find fiber closest to coord. with mat tag - int matTag = atoi(argv[3]); - double yCoord = atof(argv[1]); - double zCoord = atof(argv[2]); - double closestDist; - double ySearch, zSearch, dy, dz; - double distance; - int j; - - // Find first fiber with specified material tag - for (j = 0; j < numFibers; j++) { - if (matTag == theMaterials[j]->getTag()) { - ySearch = -matData[3*j]; - zSearch = matData[3*j+1]; - dy = ySearch-yCoord; - dz = zSearch-zCoord; - closestDist = sqrt(dy*dy + dz*dz); - key = j; - break; - } - } - - // Search the remaining fibers - for ( ; j < numFibers; j++) { - if (matTag == theMaterials[j]->getTag()) { - ySearch = -matData[3*j]; - zSearch = matData[3*j+1]; - dy = ySearch-yCoord; - dz = zSearch-zCoord; - distance = sqrt(dy*dy + dz*dz); - if (distance < closestDist) { - closestDist = distance; - key = j; - } - } - } - passarg = 4; - } - - else { // fiber near-to coordinate specified - double yCoord = atof(argv[1]); - double zCoord = atof(argv[2]); - double closestDist; - double ySearch, zSearch, dy, dz; - double distance; - ySearch = -matData[0]; - zSearch = matData[1]; - dy = ySearch-yCoord; - dz = zSearch-zCoord; - closestDist = sqrt(dy*dy + dz*dz); - key = 0; - for (int j = 1; j < numFibers; j++) { - ySearch = -matData[3*j]; - zSearch = matData[3*j+1]; - dy = ySearch-yCoord; - dz = zSearch-zCoord; - distance = sqrt(dy*dy + dz*dz); - if (distance < closestDist) { - closestDist = distance; - key = j; - } - } - passarg = 3; - } - - if (key < numFibers && key >= 0) { - output.tag("FiberOutput"); - output.attr("yLoc",matData[3*key]); - output.attr("zLoc",matData[3*key+1]); - output.attr("area",matData[3*key+2]); - - theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); - - output.endTag(); - } - } - } - - output.endTag(); return theResponse; } @@ -1213,8 +1089,6 @@ FiberSection3dThermal::setResponse(const char **argv, int argc, OPS_Stream &outp int FiberSection3dThermal::getResponse(int responseID, Information §Info) { - // Just call the base class method ... don't need to define - // this function, but keeping it here just for clarity if (responseID == 5) { int numData = 5*numFibers; Vector data(numData); @@ -1231,9 +1105,8 @@ FiberSection3dThermal::getResponse(int responseID, Information §Info) count += 5; } return sectInfo.setVector(data); - } else { + } else return SectionForceDeformation::getResponse(responseID, sectInfo); - } } int diff --git a/SRC/material/section/FiberSectionAsym3d.cpp b/SRC/material/section/FiberSectionAsym3d.cpp new file mode 100644 index 000000000..f68ee4269 --- /dev/null +++ b/SRC/material/section/FiberSectionAsym3d.cpp @@ -0,0 +1,1569 @@ +/* ****************************************************************** ** +** 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.32 $ +// $Date: 2010-08-16 05:05:07 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/section/FiberSectionAsym3d.cpp,v $ + +// Written: fmk +// Created: 04/04 +// +// Description: This file contains the class implementation of FiberSection2d. + +// Modified by: Xinlong Du and Jerome F. Hajjar, Northeastern University, USA; Year 2019 +// Description: Modified FiberSection3d.cpp (from version 3.0.0 on 11/5/2018) +// to include shear center coordinates and high-order longitudinal strain terms. +// References: +// Du, X., & Hajjar, J. (2021). Three-dimensional nonlinear displacement-based beam element +// for members with angle and tee sections. Engineering Structures, 239, 112239. +// Du, X., & Hajjar, J. F. (2021). Three-dimensional nonlinear mixed 6-DOF beam element +// for thin-walled members. Thin-Walled Structures, 164, 107817. + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ID FiberSectionAsym3d::code(5); + +void* OPS_FiberSectionAsym3d() +{ + int numData = OPS_GetNumRemainingInputArgs(); + if(numData < 1) { + opserr<<"insufficient arguments for FiberSectionAsym3d\n"; + return 0; + } + + numData = 1; + int tag; + if (OPS_GetIntInput(&numData, &tag) < 0) return 0; + numData = 2; + double dData[2]; + if (OPS_GetDoubleInput(&numData, dData) < 0) return 0; + + double GJ = 0.0; + UniaxialMaterial *torsion = 0; + bool deleteTorsion = false; + if (OPS_GetNumRemainingInputArgs() >= 2) { + const char* opt = OPS_GetString(); + if (strcmp(opt, "-GJ") == 0) { + numData = 1; + if (OPS_GetDoubleInput(&numData, &GJ) < 0) return 0; + torsion = new ElasticMaterial(0, GJ); + deleteTorsion = true; + } + } + + int num = 30; + SectionForceDeformation* section = new FiberSectionAsym3d(tag, num, torsion, dData[0], dData[1]); + if (deleteTorsion) + delete torsion; + return section; +} + +// constructors: +FiberSectionAsym3d::FiberSectionAsym3d(int tag, int num, Fiber **fibers, UniaxialMaterial *torsion, double yss, double zss): + SectionForceDeformation(tag, SEC_TAG_FiberSectionAsym3d), + numFibers(num), sizeFibers(num), theMaterials(0), matData(0), + QzBar(0.0), QyBar(0.0), Abar(0.0), yBar(0.0), zBar(0.0), sectionIntegr(0), e(5), s(0), ks(0), theTorsion(0), ys(yss), zs(zss) //Xinlong +{ + if (numFibers != 0) { + theMaterials = new UniaxialMaterial *[numFibers]; + + if (theMaterials == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to allocate Material pointers\n"; + exit(-1); + } + + matData = new double [numFibers*3]; + + if (matData == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to allocate double array for material data\n"; + exit(-1); + } + + for (int i = 0; i < numFibers; i++) { + Fiber *theFiber = fibers[i]; + double yLoc, zLoc, Area; + theFiber->getFiberLocation(yLoc, zLoc); + Area = theFiber->getArea(); + + QzBar += yLoc*Area; + QyBar += zLoc*Area; + Abar += Area; + + matData[i*3] = yLoc; + matData[i*3+1] = zLoc; + matData[i*3+2] = Area; + UniaxialMaterial *theMat = theFiber->getMaterial(); + theMaterials[i] = theMat->getCopy(); + + if (theMaterials[i] == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to get copy of a Material\n"; + exit(-1); + } + } + + yBar = QzBar/Abar; + zBar = QyBar/Abar; + } + + theTorsion = torsion->getCopy(); + if (theTorsion == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to get copy of torsion material\n"; + } + + s = new Vector(sData, 5); //Xinlong + ks = new Matrix(kData, 5, 5); //Xinlong + + sData[0] = 0.0; + sData[1] = 0.0; + sData[2] = 0.0; + sData[3] = 0.0; + sData[4] = 0.0; //Xinlong + + for (int i=0; i<25; i++) //Xinlong + kData[i] = 0.0; + + code(0) = SECTION_RESPONSE_P; + code(1) = SECTION_RESPONSE_MZ; + code(2) = SECTION_RESPONSE_MY; + code(3) = SECTION_RESPONSE_T; + code(4) = SECTION_RESPONSE_W; +} + +FiberSectionAsym3d::FiberSectionAsym3d(int tag, int num, UniaxialMaterial *torsion, double yss, double zss): //Xinlong + SectionForceDeformation(tag, SEC_TAG_FiberSectionAsym3d), + numFibers(0), sizeFibers(num), theMaterials(0), matData(0), + QzBar(0.0), QyBar(0.0), Abar(0.0), yBar(0.0), zBar(0.0), sectionIntegr(0), e(5), s(0), ks(0), theTorsion(0), ys(yss), zs(zss) //Xinlong +{ + if(sizeFibers != 0) { + theMaterials = new UniaxialMaterial *[sizeFibers]; + + if (theMaterials == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to allocate Material pointers\n"; + exit(-1); + } + + matData = new double [sizeFibers*3]; + + if (matData == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- 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; + theMaterials[i] = 0; + } + } + + theTorsion = torsion->getCopy(); + if (theTorsion == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to get copy of torsion material\n"; + } + + s = new Vector(sData, 5); //Xinlong + ks = new Matrix(kData, 5, 5); //Xinlong + + sData[0] = 0.0; + sData[1] = 0.0; + sData[2] = 0.0; + sData[3] = 0.0; + sData[4] = 0.0; //Xinlong + + for (int i=0; i<25; i++) //Xinlong + kData[i] = 0.0; + + code(0) = SECTION_RESPONSE_P; + code(1) = SECTION_RESPONSE_MZ; + code(2) = SECTION_RESPONSE_MY; + code(3) = SECTION_RESPONSE_T; + code(4) = SECTION_RESPONSE_W; +} + +FiberSectionAsym3d::FiberSectionAsym3d(int tag, int num, UniaxialMaterial **mats, + SectionIntegration &si, UniaxialMaterial *torsion, double yss, double zss): //Xinlong + SectionForceDeformation(tag, SEC_TAG_FiberSectionAsym3d), + numFibers(num), sizeFibers(num), theMaterials(0), matData(0), + QzBar(0.0), QyBar(0.0), Abar(0.0), yBar(0.0), zBar(0.0), sectionIntegr(0), e(5), s(0), ks(0), theTorsion(0), ys(yss), zs(zss) //Xinlong +{ + if (numFibers != 0) { + theMaterials = new UniaxialMaterial *[numFibers]; + + if (theMaterials == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to allocate Material pointers"; + exit(-1); + } + matData = new double [numFibers*3]; + + if (matData == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to allocate double array for material data\n"; + exit(-1); + } + } + + sectionIntegr = si.getCopy(); + if (sectionIntegr == 0) { + opserr << "Error: FiberSectionAsym3d::FiberSectionAsym3d: could not create copy of section integration object" << endln; + exit(-1); + } + + static double yLocs[10000]; + static double zLocs[10000]; + sectionIntegr->getFiberLocations(numFibers, yLocs, zLocs); + + static double fiberArea[10000]; + sectionIntegr->getFiberWeights(numFibers, fiberArea); + + for (int i = 0; i < numFibers; i++) { + + Abar += fiberArea[i]; + QzBar += yLocs[i]*fiberArea[i]; + QyBar += zLocs[i]*fiberArea[i]; + + theMaterials[i] = mats[i]->getCopy(); + + if (theMaterials[i] == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to get copy of a Material\n"; + exit(-1); + } + } + + yBar = QzBar/Abar; + zBar = QyBar/Abar; + + theTorsion = torsion->getCopy(); + if (theTorsion == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to get copy of torsion material\n"; + } + + s = new Vector(sData, 5); //Xinlong + ks = new Matrix(kData, 5, 5); //Xinlong + + for (int i = 0; i < 5; i++) //Xinlong + sData[i] = 0.0; + + for (int i = 0; i < 25; i++) //Xinlong + kData[i] = 0.0; + + code(0) = SECTION_RESPONSE_P; + code(1) = SECTION_RESPONSE_MZ; + code(2) = SECTION_RESPONSE_MY; + code(3) = SECTION_RESPONSE_T; + code(4) = SECTION_RESPONSE_W; +} + +// constructor for blank object that recvSelf needs to be invoked upon +FiberSectionAsym3d::FiberSectionAsym3d(): + SectionForceDeformation(0, SEC_TAG_FiberSectionAsym3d), + numFibers(0), sizeFibers(0), theMaterials(0), matData(0), + QzBar(0.0), QyBar(0.0), Abar(0.0), yBar(0.0), zBar(0.0), sectionIntegr(0), e(5), s(0), ks(0), theTorsion(0), ys(0.0), zs(0.0) //Xinlong +{ + s = new Vector(sData, 5); //Xinlong + ks = new Matrix(kData, 5, 5); //Xinlong + + sData[0] = 0.0; + sData[1] = 0.0; + sData[2] = 0.0; + sData[3] = 0.0; + sData[4] = 0.0; //Xinlong + + for (int i=0; i<25; i++) //Xinlong + kData[i] = 0.0; + + code(0) = SECTION_RESPONSE_P; + code(1) = SECTION_RESPONSE_MZ; + code(2) = SECTION_RESPONSE_MY; + code(3) = SECTION_RESPONSE_T; + code(4) = SECTION_RESPONSE_W; +} + +int +FiberSectionAsym3d::addFiber(Fiber &newFiber) +{ + // need to create a larger array + if(numFibers == sizeFibers) { + int newSize = 2*sizeFibers; + UniaxialMaterial **newArray = new UniaxialMaterial *[newSize]; + double *newMatData = new double [3 * newSize]; + + if (newArray == 0 || newMatData == 0) { + opserr << "FiberSectionAsym3d::addFiber -- failed to allocate Fiber pointers\n"; + exit(-1); + } + + // copy the old pointers + for (int i = 0; i < numFibers; i++) { + newArray[i] = theMaterials[i]; + newMatData[3*i] = matData[3*i]; + newMatData[3*i+1] = matData[3*i+1]; + newMatData[3*i+2] = matData[3*i+2]; + } + + // initialize new memomry + for (int i = numFibers; i < newSize; i++) { + newArray[i] = 0; + newMatData[3*i] = 0.0; + newMatData[3*i+1] = 0.0; + newMatData[3*i+2] = 0.0; + } + sizeFibers = newSize; + + // set new memory + if (theMaterials != 0) { + delete [] theMaterials; + delete [] matData; + } + + theMaterials = newArray; + matData = newMatData; + } + + // set the new pointers + double yLoc, zLoc, Area; + newFiber.getFiberLocation(yLoc, zLoc); + Area = newFiber.getArea(); + matData[numFibers*3] = yLoc; + matData[numFibers*3+1] = zLoc; + matData[numFibers*3+2] = Area; + UniaxialMaterial *theMat = newFiber.getMaterial(); + theMaterials[numFibers] = theMat->getCopy(); + + if (theMaterials[numFibers] == 0) { + opserr << "FiberSectionAsym3d::addFiber -- failed to get copy of a Material\n"; + return -1; + } + + numFibers++; + + // Recompute centroid + Abar += Area; + QzBar += yLoc*Area; + QyBar += zLoc*Area; + + yBar = QzBar/Abar; + zBar = QyBar/Abar; + + return 0; +} + + + +// destructor: +FiberSectionAsym3d::~FiberSectionAsym3d() +{ + if (theMaterials != 0) { + for (int i = 0; i < numFibers; i++) + if (theMaterials[i] != 0) + delete theMaterials[i]; + + delete [] theMaterials; + } + + if (matData != 0) + delete [] matData; + + if (s != 0) + delete s; + + if (ks != 0) + delete ks; + + if (sectionIntegr != 0) + delete sectionIntegr; + + if (theTorsion != 0) + delete theTorsion; +} + +int +FiberSectionAsym3d::setTrialSectionDeformation (const Vector &deforms) +{ + //double zs = 0.6385; //z coord of shear center w.r.t. centroid + //double ys = -0.6741; //y coord of shear center w.r.t. centroid + + int res = 0; + e = deforms; + + for (int i = 0; i < 5; i++) //Xinlong + sData[i] = 0.0; + for (int i = 0; i < 25; i++) //Xinlong + kData[i] = 0.0; + /* + double d0 = deforms(0); //u' Xinlong + double d1 = deforms(1); //v" Xinlong + double d2 = deforms(2); //w" Xinlong + double d3 = deforms(3); //phi' Xinlong + double d4 = deforms(4); //v' Xinlong + double d5 = deforms(5); //w' Xinlong + double d6 = deforms(6); //phi Xinlong + double d7 = deforms(7); //theta_Iz + double d8 = deforms(8); //theta_Iy + double d9 = deforms(9); //theta_Jz + double d10 = deforms(10); //theta_Jy + */ + double d0 = deforms(0); + double d1 = deforms(1); + double d2 = deforms(2); + double d3 = deforms(3); + double d4 = deforms(4); //Phi' + + static double yLocs[10000]; + static double zLocs[10000]; + static double fiberArea[10000]; + + if (sectionIntegr != 0) { + sectionIntegr->getFiberLocations(numFibers, yLocs, zLocs); + sectionIntegr->getFiberWeights(numFibers, fiberArea); + } + else { + + for (int i = 0; i < numFibers; i++) { + + yLocs[i] = matData[3*i]; + zLocs[i] = matData[3*i+1]; + fiberArea[i] = matData[3*i+2]; + } + } + + double tangent, stress; + for (int i = 0; i < numFibers; i++) { + UniaxialMaterial *theMat = theMaterials[i]; + double y = yLocs[i] - yBar; + double z = zLocs[i] - zBar; + double A = fiberArea[i]; + + // determine material strain and set it + double pSquare = (y - ys)*(y - ys) + (z - zs)*(z - zs); + //double strain = d0 - y * d1 - z * d2 + (4.0*d7*d7+4.0*d8*d8+4.0*d9*d9+4.0*d10*d10-2.0*d7*d9-2.0*d8*d10)/60.0 + 0.5*pSquare*d3*d3 + (zs*d4 - ys * d5)*d3 + (z*d1 - y * d2)*d6; + double strain = d0 - y * d1 + z * d2 + pSquare * d3; + res += theMat->setTrial(strain, stress, tangent); + + double value = tangent * A; //EA + double vas1 = -y*value; //-yEA + double vas2 = z*value; //zEA + double vas1as2 = vas1*z; //-yzEA + + kData[0] += value; //EA + kData[1] += vas1; //-yEA + kData[2] += vas2; //zEA + kData[3] += pSquare * value; //p2EA + + kData[6] += vas1 * -y; //y2EA + kData[7] += vas1as2; //-yzEA + kData[8] += pSquare * vas1; //-p2yEA + + kData[12] += vas2 * z; //z2EA + kData[13] += pSquare * vas2; //p2zEA + + kData[18] += pSquare * pSquare*value; //p4EA + + double fs0 = stress * A; //sigma*A + + sData[0] += fs0; //N + sData[1] += fs0 * -y; //Mz + sData[2] += fs0 * z; //My + sData[3] += fs0 * pSquare; //W + } + + kData[5] = kData[1]; + kData[10] = kData[2]; + kData[15] = kData[3]; + kData[11] = kData[7]; + kData[16] = kData[8]; + kData[17] = kData[13]; + + if (theTorsion != 0) { + res += theTorsion->setTrial(d4, stress, tangent); + sData[4] = stress; //T + kData[24] = tangent; //GJ + } + + return res; +} + +const Matrix& +FiberSectionAsym3d::getInitialTangent(void) +{ + //double zs = 0.6385; //z coord of shear center w.r.t. centroid + //double ys = -0.6741; //y coord of shear center w.r.t. centroid + static double kInitialData[25]; + static Matrix kInitial(kInitialData, 5, 5); + + kInitial.Zero(); + + static double yLocs[10000]; + static double zLocs[10000]; + static double fiberArea[10000]; + + if (sectionIntegr != 0) { + sectionIntegr->getFiberLocations(numFibers, yLocs, zLocs); + sectionIntegr->getFiberWeights(numFibers, fiberArea); + } + else { + for (int i = 0; i < numFibers; i++) { + yLocs[i] = matData[3*i]; + zLocs[i] = matData[3*i+1]; + fiberArea[i] = matData[3*i+2]; + } + } + + for (int i = 0; i < numFibers; i++) { + UniaxialMaterial *theMat = theMaterials[i]; + double y = yLocs[i] - yBar; + double z = zLocs[i] - zBar; + double A = fiberArea[i]; + double pSquare = (y - ys)*(y - ys) + (z - zs)*(z - zs); + + double tangent = theMat->getInitialTangent(); + + double value = tangent * A; + double vas1 = -y*value; + double vas2 = z*value; + double vas1as2 = vas1*z; + + kInitialData[0] += value; //EA + kInitialData[1] += vas1; //-yEA + kInitialData[2] += vas2; //zEA + kInitialData[3] += pSquare * value; //p2EA + + kInitialData[6] += vas1 * -y; //y2EA + kInitialData[7] += vas1as2; //-yzEA + kInitialData[8] += pSquare * vas1; //-p2yEA + + kInitialData[12] += vas2 * z; //z2EA + kInitialData[13] += pSquare * vas2; //p2zEA + + kInitialData[18] += pSquare * pSquare*value; //p4EA + } + + kInitialData[5] = kInitialData[1]; + kInitialData[10] = kInitialData[2]; + kInitialData[15] = kInitialData[3]; + kInitialData[11] = kInitialData[7]; + kInitialData[16] = kInitialData[8]; + kInitialData[17] = kInitialData[13]; + + if (theTorsion != 0) + kInitialData[24] = theTorsion->getInitialTangent(); + + return kInitial; +} + +const Vector& +FiberSectionAsym3d::getSectionDeformation(void) +{ + return e; +} + +const Matrix& +FiberSectionAsym3d::getSectionTangent(void) +{ + return *ks; +} + +const Vector& +FiberSectionAsym3d::getStressResultant(void) +{ + return *s; +} + +SectionForceDeformation* +FiberSectionAsym3d::getCopy(void) +{ + FiberSectionAsym3d *theCopy = new FiberSectionAsym3d (); + theCopy->setTag(this->getTag()); + + theCopy->numFibers = numFibers; + theCopy->sizeFibers = numFibers; + + if (numFibers != 0) { + theCopy->theMaterials = new UniaxialMaterial *[numFibers]; + + if (theCopy->theMaterials == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to allocate Material pointers\n"; + exit(-1); + } + + theCopy->matData = new double [numFibers*3]; + + if (theCopy->matData == 0) { + opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to allocate double array for material data\n"; + exit(-1); + } + + + for (int i = 0; i < numFibers; i++) { + theCopy->matData[i*3] = matData[i*3]; + theCopy->matData[i*3+1] = matData[i*3+1]; + theCopy->matData[i*3+2] = matData[i*3+2]; + theCopy->theMaterials[i] = theMaterials[i]->getCopy(); + + if (theCopy->theMaterials[i] == 0) { + opserr << "FiberSectionAsym3d::getCopy -- failed to get copy of a Material\n"; + exit(-1); + } + } + } + + theCopy->e = e; + theCopy->QzBar = QzBar; + theCopy->QyBar = QyBar; + theCopy->Abar = Abar; + theCopy->yBar = yBar; + theCopy->zBar = zBar; + theCopy->ys = ys; //Xinlong 11/20/2019 + theCopy->zs = zs; //Xinlong 11/20/2019 + + for (int i=0; i<25; i++) //Xinlong + theCopy->kData[i] = kData[i]; + + theCopy->sData[0] = sData[0]; + theCopy->sData[1] = sData[1]; + theCopy->sData[2] = sData[2]; + theCopy->sData[3] = sData[3]; + theCopy->sData[4] = sData[4]; //Xinlong + + if (theTorsion != 0) + theCopy->theTorsion = theTorsion->getCopy(); + else + theCopy->theTorsion = 0; + + if (sectionIntegr != 0) + theCopy->sectionIntegr = sectionIntegr->getCopy(); + else + theCopy->sectionIntegr = 0; + + return theCopy; +} + +const ID& +FiberSectionAsym3d::getType () +{ + return code; +} + +int +FiberSectionAsym3d::getOrder () const +{ + return 5; +} + +int +FiberSectionAsym3d::commitState(void) +{ + int err = 0; + + for (int i = 0; i < numFibers; i++) + err += theMaterials[i]->commitState(); + + if (theTorsion != 0) + err += theTorsion->commitState(); + + return err; +} + +int +FiberSectionAsym3d::revertToLastCommit(void) +{ + //double zs = 0.6385; //z coord of shear center w.r.t. centroid + //double ys = -0.6741; //y coord of shear center w.r.t. centroid + + int err = 0; + + for (int i = 0; i < 5; i++) //Xinlong + sData[i] = 0.0; + for (int i = 0; i < 25; i++) //Xinlong + kData[i] = 0.0; + + static double yLocs[10000]; + static double zLocs[10000]; + static double fiberArea[10000]; + + if (sectionIntegr != 0) { + sectionIntegr->getFiberLocations(numFibers, yLocs, zLocs); + sectionIntegr->getFiberWeights(numFibers, fiberArea); + } + else { + for (int i = 0; i < numFibers; i++) { + yLocs[i] = matData[3*i]; + zLocs[i] = matData[3*i+1]; + fiberArea[i] = matData[3*i+2]; + } + } + + for (int i = 0; i < numFibers; i++) { + UniaxialMaterial *theMat = theMaterials[i]; + double y = yLocs[i] - yBar; + double z = zLocs[i] - zBar; + double A = fiberArea[i]; + + double pSquare = (y - ys)*(y - ys) + (z - zs)*(z - zs); + + // invoke revertToLast on the material + err += theMat->revertToLastCommit(); + + double tangent = theMat->getTangent(); + double stress = theMat->getStress(); + + double value = tangent * A; + double vas1 = -y*value; + double vas2 = z*value; + double vas1as2 = vas1*z; + + + kData[0] += value; //EA + kData[1] += vas1; //-yEA + kData[2] += vas2; //zEA + kData[3] += pSquare * value; //p2EA + + kData[6] += vas1 * -y; //y2EA + kData[7] += vas1as2; //-yzEA + kData[8] += pSquare * vas1; //-p2yEA + + kData[12] += vas2 * z; //z2EA + kData[13] += pSquare * vas2; //p2zEA + + kData[18] += pSquare * pSquare*value; //p4EA + + double fs0 = stress * A; + + sData[0] += fs0; //N + sData[1] += fs0 * -y; //Mz + sData[2] += fs0 * z; //My + sData[3] += fs0 * pSquare; //W + } + + kData[5] = kData[1]; + kData[10] = kData[2]; + kData[15] = kData[3]; + kData[11] = kData[7]; + kData[16] = kData[8]; + kData[17] = kData[13]; + + if (theTorsion != 0) { + err += theTorsion->revertToLastCommit(); + kData[24] = theTorsion->getTangent(); + } + else + kData[24] = 0.0; + //why do not have sData[4] here? + return err; +} + +int +FiberSectionAsym3d::revertToStart(void) +{ + //double zs = 0.6385; //z coord of shear center w.r.t. centroid + //double ys = -0.6741; //y coord of shear center w.r.t. centroid + + // revert the fibers to start + int err = 0; + + for (int i = 0; i < 5; i++) //Xinlong + sData[i] = 0.0; + for (int i = 0; i < 25; i++) //Xinlong + kData[i] = 0.0; + + static double yLocs[10000]; + static double zLocs[10000]; + static double fiberArea[10000]; + + if (sectionIntegr != 0) { + sectionIntegr->getFiberLocations(numFibers, yLocs, zLocs); + sectionIntegr->getFiberWeights(numFibers, fiberArea); + } + else { + for (int i = 0; i < numFibers; i++) { + yLocs[i] = matData[3*i]; + zLocs[i] = matData[3*i+1]; + fiberArea[i] = matData[3*i+2]; + } + } + + for (int i = 0; i < numFibers; i++) { + UniaxialMaterial *theMat = theMaterials[i]; + double y = yLocs[i] - yBar; + double z = zLocs[i] - zBar; + double A = fiberArea[i]; + + double pSquare = (y - ys)*(y - ys) + (z - zs)*(z - zs); + + // invoke revertToStart on the material + err += theMat->revertToStart(); + + double tangent = theMat->getTangent(); + double stress = theMat->getStress(); + + double value = tangent * A; + double vas1 = -y*value; + double vas2 = z*value; + double vas1as2 = vas1*z; + + kData[0] += value; //EA + kData[1] += vas1; //-yEA + kData[2] += vas2; //zEA + kData[3] += pSquare * value; //p2EA + + kData[6] += vas1 * -y; //y2EA + kData[7] += vas1as2; //-yzEA + kData[8] += pSquare * vas1; //-p2yEA + + kData[12] += vas2 * z; //z2EA + kData[13] += pSquare * vas2; //p2zEA + + kData[18] += pSquare * pSquare*value; //p4EA + + double fs0 = stress * A; + + sData[0] += fs0; //N + sData[1] += fs0 * -y; //Mz + sData[2] += fs0 * z; //My + sData[3] += fs0 * pSquare; //W + } + + kData[5] = kData[1]; + kData[10] = kData[2]; + kData[15] = kData[3]; + kData[11] = kData[7]; + kData[16] = kData[8]; + kData[17] = kData[13]; + + if (theTorsion != 0) { + err += theTorsion->revertToStart(); + kData[24] = theTorsion->getTangent(); + sData[4] = theTorsion->getStress(); + } + else { + kData[24] = 0.0; + sData[4] = 0.0; + } + + return err; +} + +int +FiberSectionAsym3d::sendSelf(int commitTag, Channel &theChannel) +{ + int res = 0; + + // create an id to send objects tag and numFibers, + // size 6 so no conflict with matData below if just 2 fibers + static Vector data(6); + data(0) = this->getTag(); + data(1) = numFibers; + data(2) = (theTorsion != 0) ? 1 : 0; + int dbTag = this->getDbTag(); + if (theTorsion != 0) { + theTorsion->setDbTag(dbTag); + data(3) = theTorsion->getClassTag(); + } + data(4) = ys; + data(5) = zs; + + res += theChannel.sendVector(dbTag, commitTag, data); + if (res < 0) { + opserr << "FiberSectionAsym3d::sendSelf - failed to send Vector data\n"; + return res; + } + + if (theTorsion != 0) + theTorsion->sendSelf(commitTag, theChannel); + + if (numFibers != 0) { + + // create an id containingg classTag and dbTag for each material & send it + ID materialData(2*numFibers); + for (int i=0; igetClassTag(); + int matDbTag = theMat->getDbTag(); + if (matDbTag == 0) { + matDbTag = theChannel.getDbTag(); + if (matDbTag != 0) + theMat->setDbTag(matDbTag); + } + materialData(2*i+1) = matDbTag; + } + + res += theChannel.sendID(dbTag, commitTag, materialData); + if (res < 0) { + opserr << "FiberSectionAsym3d::sendSelf - failed to send material data\n"; + return res; + } + + // send the fiber data, i.e. area and loc + Vector fiberData(matData, 3*numFibers); + res += theChannel.sendVector(dbTag, commitTag, fiberData); + if (res < 0) { + opserr << "FiberSectionAsym3d::sendSelf - failed to send fiber data\n"; + return res; + } + + // now invoke send(0 on all the materials + for (int j=0; jsendSelf(commitTag, theChannel); + } + + return res; +} + +int +FiberSectionAsym3d::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + + static Vector data(6); + + int dbTag = this->getDbTag(); + res += theChannel.recvVector(dbTag, commitTag, data); + ys = data(4); + zs = data(5); + + if (res < 0) { + opserr << "FiberSectionAsym3d::recvSelf - failed to recv Vector data\n"; + return res; + } + + this->setTag((int)data(0)); + + if ((int)data(2) == 1 && theTorsion == 0) { + int cTag = (int)data(3); + theTorsion = theBroker.getNewUniaxialMaterial(cTag); + if (theTorsion == 0) { + opserr << "FiberSectionAsym3d::recvSelf - failed to get torsion material \n"; + return -1; + } + theTorsion->setDbTag(dbTag); + } + + if (theTorsion->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "FiberSectionAsym3d::recvSelf - torsion failed to recvSelf \n"; + return -2; + } + + // recv data about materials objects, classTag and dbTag + if ((int)data(1) != 0) { + ID materialData(2*(int)data(1)); + res += theChannel.recvID(dbTag, commitTag, materialData); + if (res < 0) { + opserr << "FiberSectionAsym3d::recvSelf - failed to send material data\n"; + return res; + } + + // if current arrays not of correct size, release old and resize + if (theMaterials == 0 || numFibers != (int)data(1)) { + // delete old stuff if outa date + if (theMaterials != 0) { + for (int i=0; igetClassTag() != classTag) { + delete theMaterials[i]; + theMaterials[i] = theBroker.getNewUniaxialMaterial(classTag); + } + + if (theMaterials[i] == 0) { + opserr << "FiberSectionAsym3d::recvSelf -- failed to allocate double array for material data\n"; + exit(-1); + } + + theMaterials[i]->setDbTag(dbTag); + res += theMaterials[i]->recvSelf(commitTag, theChannel, theBroker); + } + + QzBar = 0.0; + QyBar = 0.0; + Abar = 0.0; + double yLoc, zLoc, Area; + + // Recompute centroid + for (i = 0; i < numFibers; i++) { + yLoc = matData[3*i]; + zLoc = matData[3*i+1]; + Area = matData[3*i+2]; + Abar += Area; + QzBar += yLoc*Area; + QyBar += zLoc*Area; + } + + yBar = QzBar/Abar; + zBar = QyBar/Abar; + } + + return res; +} + +void +FiberSectionAsym3d::Print(OPS_Stream &s, int flag) +{ + if (flag == OPS_PRINT_PRINTMODEL_SECTION || flag == OPS_PRINT_PRINTMODEL_MATERIAL) { + s << "\nFiberSectionAsym3d, tag: " << this->getTag() << endln; + s << "\tSection code: " << code; + s << "\tNumber of Fibers: " << numFibers << endln; + s << "\tCentroid: (" << -yBar << ", " << zBar << ')' << endln; + if (theTorsion != 0) + theTorsion->Print(s, flag); + + if (flag == OPS_PRINT_PRINTMODEL_MATERIAL) { + for (int i = 0; i < numFibers; i++) { + s << "\nLocation (y, z) = (" << matData[3*i] << ", " << matData[3*i+1] << ")"; + s << "\nArea = " << matData[3*i+2] << endln; + theMaterials[i]->Print(s, flag); + + } + } + } + if (flag == 3) { + for (int i = 0; i < numFibers; i++) { + s << theMaterials[i]->getTag() << " " << matData[3*i] << " " << matData[3*i+1] << " " << matData[3*i+2] << " " ; + s << theMaterials[i]->getStress() << " " << theMaterials[i]->getStrain() << endln; + } + } + + if (flag == 4) { + for (int i = 0; i < numFibers; i++) { + s << "add fiber # " << i+1 << " using material # " << theMaterials[i]->getTag() << " to section # 1\n"; + s << "fiber_cross_section = " << matData[3*i+2] << "*m^2\n"; + s << "fiber_location = (" << matData[3*i] << "*m, " << matData[3*i+1] << "*m);\n\n"; + } + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << "\t\t\t{"; + s << "\"name\": \"" << this->getTag() << "\", "; + s << "\"type\": \"FiberSectionAsym3d\", "; + if (theTorsion != 0) + s << "\"torsion\": " << theTorsion->getInitialTangent() << ", "; + s << "\"fibers\": [\n"; + for (int i = 0; i < numFibers; i++) { + s << "\t\t\t\t{\"coord\": [" << matData[3*i] << ", " << matData[3*i+1] << "], "; + s << "\"area\": " << matData[3*i+2] << ", "; + s << "\"material\": \"" << theMaterials[i]->getTag() << "\""; + if (i < numFibers - 1) + s << "},\n"; + else + s << "}\n"; + } + s << "\t\t\t]}"; + } +} + +Response* +FiberSectionAsym3d::setResponse(const char **argv, int argc, OPS_Stream &output) +{ + Response *theResponse = 0; + + if (argc > 2 && strcmp(argv[0],"fiber") == 0) { + + static double yLocs[10000]; + static double zLocs[10000]; + + if (sectionIntegr != 0) { + sectionIntegr->getFiberLocations(numFibers, yLocs, zLocs); + } + else { + for (int i = 0; i < numFibers; i++) { + yLocs[i] = matData[3*i]; + zLocs[i] = matData[3*i+1]; + } + } + + int key = numFibers; + int passarg = 2; + + if (argc <= 3) { // fiber number was input directly + + key = atoi(argv[1]); + + } else if (argc > 4) { // find fiber closest to coord. with mat tag + int matTag = atoi(argv[3]); + double yCoord = atof(argv[1]); + double zCoord = atof(argv[2]); + double closestDist = 0.0; + double ySearch, zSearch, dy, dz; + double distance; + int j; + + // Find first fiber with specified material tag + for (j = 0; j < numFibers; j++) { + if (matTag == theMaterials[j]->getTag()) { + //ySearch = matData[3*j]; + //zSearch = matData[3*j+1]; + ySearch = yLocs[j]; + zSearch = zLocs[j]; + dy = ySearch-yCoord; + dz = zSearch-zCoord; + closestDist = dy*dy + dz*dz; + key = j; + break; + } + } + + // Search the remaining fibers + for ( ; j < numFibers; j++) { + if (matTag == theMaterials[j]->getTag()) { + //ySearch = matData[3*j]; + //zSearch = matData[3*j+1]; + ySearch = yLocs[j]; + zSearch = zLocs[j]; + dy = ySearch-yCoord; + dz = zSearch-zCoord; + distance = dy*dy + dz*dz; + if (distance < closestDist) { + closestDist = distance; + key = j; + } + } + } + passarg = 4; + } + + else { // fiber near-to coordinate specified + double yCoord = atof(argv[1]); + double zCoord = atof(argv[2]); + double closestDist; + double ySearch, zSearch, dy, dz; + double distance; + //ySearch = matData[0]; + //zSearch = matData[1]; + ySearch = yLocs[0]; + zSearch = zLocs[0]; + dy = ySearch-yCoord; + dz = zSearch-zCoord; + closestDist = dy*dy + dz*dz; + key = 0; + for (int j = 1; j < numFibers; j++) { + //ySearch = matData[3*j]; + //zSearch = matData[3*j+1]; + ySearch = yLocs[j]; + zSearch = zLocs[j]; + dy = ySearch-yCoord; + dz = zSearch-zCoord; + distance = dy*dy + dz*dz; + if (distance < closestDist) { + closestDist = distance; + key = j; + } + } + passarg = 3; + } + + if (key < numFibers && key >= 0) { + output.tag("FiberOutput"); + output.attr("yLoc",-matData[3*key]); + output.attr("zLoc",matData[3*key+1]); + output.attr("area",matData[3*key+2]); + + theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); + + output.endTag(); + } + + } else if (strcmp(argv[0],"fiberData") == 0) { + int numData = numFibers*5; + for (int j = 0; j < numFibers; j++) { + output.tag("FiberOutput"); + output.attr("yLoc", matData[3*j]); + output.attr("zLoc", matData[3*j+1]); + output.attr("area", matData[3*j+2]); + output.tag("ResponseType","yCoord"); + output.tag("ResponseType","zCoord"); + output.tag("ResponseType","area"); + output.tag("ResponseType","stress"); + output.tag("ResponseType","strain"); + output.endTag(); + } + Vector theResponseData(numData); + theResponse = new MaterialResponse(this, 5, theResponseData); + + } else if ((strcmp(argv[0],"numFailedFiber") == 0) || + (strcmp(argv[0],"numFiberFailed") == 0)) { + int count = 0; + theResponse = new MaterialResponse(this, 6, count); + + } else if ((strcmp(argv[0],"sectionFailed") == 0) || + (strcmp(argv[0],"hasSectionFailed") == 0) || + (strcmp(argv[0],"hasFailed") == 0)) { + + int count = 0; + theResponse = new MaterialResponse(this, 7, count); + } + + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); + + return theResponse; +} + + +int +FiberSectionAsym3d::getResponse(int responseID, Information §Info) +{ + // Just call the base class method ... don't need to define + // this function, but keeping it here just for clarity + if (responseID == 5) { + int numData = 5*numFibers; + Vector data(numData); + int count = 0; + for (int j = 0; j < numFibers; j++) { + double yLoc, zLoc, A, stress, strain; + yLoc = matData[3*j]; + zLoc = matData[3*j+1]; + A = matData[3*j+2]; + stress = theMaterials[j]->getStress(); + strain = theMaterials[j]->getStrain(); + data(count) = yLoc; data(count+1) = zLoc; data(count+2) = A; + data(count+3) = stress; data(count+4) = strain; + count += 5; + } + return sectInfo.setVector(data); + } else if (responseID == 6) { + int count = 0; + for (int j = 0; j < numFibers; j++) { + if (theMaterials[j]->hasFailed() == true) + count++; + } + return sectInfo.setInt(count); + } else if (responseID == 7) { + int count = 0; + for (int j = 0; j < numFibers; j++) { + if (theMaterials[j]->hasFailed() == true) { + count+=1; + } + } + if (count == numFibers) + count = 1; + else + count = 0; + + return sectInfo.setInt(count); + } + + return SectionForceDeformation::getResponse(responseID, sectInfo); +} + +int +FiberSectionAsym3d::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc < 1) + return -1; + + int result = 0; + + // A material parameter + if (strstr(argv[0],"material") != 0) { + + // Get the tag of the material + int paramMatTag = atoi(argv[1]); + + // Loop over fibers to find the right material(s) + int ok = 0; + for (int i = 0; i < numFibers; i++) + if (paramMatTag == theMaterials[i]->getTag()) { + ok = theMaterials[i]->setParameter(&argv[2], argc-2, param); + if (ok != -1) + result = ok; + } + + if (paramMatTag == theTorsion->getTag()) { + ok = theTorsion->setParameter(&argv[2], argc-2, param); + if (ok != -1) + result = ok; + } + return result; + } + + // Check if it belongs to the section integration + else if (strstr(argv[0],"integration") != 0) { + if (sectionIntegr != 0) + return sectionIntegr->setParameter(&argv[1], argc-1, param); + else + return -1; + } + + int ok = 0; + + // loop over every material + for (int i = 0; i < numFibers; i++) { + ok = theMaterials[i]->setParameter(argv, argc, param); + if (ok != -1) + result = ok; + } + + // Don't really need to do this in "default" mode + //ok = theTorsion->setParameter(argv, argc, param); + //if (ok != -1) + // result = ok; + + if (sectionIntegr != 0) { + ok = sectionIntegr->setParameter(argv, argc, param); + if (ok != -1) + result = ok; + } + + return result; +} + +const Vector & +FiberSectionAsym3d::getSectionDeformationSensitivity(int gradIndex) +{ + static Vector dummy(4); + + dummy.Zero(); + + return dummy; +} + + +const Vector & +FiberSectionAsym3d::getStressResultantSensitivity(int gradIndex, bool conditional) +{ + static Vector ds(4); + + ds.Zero(); + + double y, z, A; + double stress = 0; + double dsigdh = 0; + double sig_dAdh = 0; + double tangent = 0; + + static double yLocs[10000]; + static double zLocs[10000]; + static double fiberArea[10000]; + + if (sectionIntegr != 0) { + sectionIntegr->getFiberLocations(numFibers, yLocs, zLocs); + sectionIntegr->getFiberWeights(numFibers, fiberArea); + } + else { + for (int i = 0; i < numFibers; i++) { + yLocs[i] = matData[3*i]; + zLocs[i] = matData[3*i+1]; + fiberArea[i] = matData[3*i+2]; + } + } + + static double dydh[10000]; + static double dzdh[10000]; + static double areaDeriv[10000]; + + if (sectionIntegr != 0) { + sectionIntegr->getLocationsDeriv(numFibers, dydh, dzdh); + sectionIntegr->getWeightsDeriv(numFibers, areaDeriv); + } + else { + for (int i = 0; i < numFibers; i++) { + dydh[i] = 0.0; + dzdh[i] = 0.0; + areaDeriv[i] = 0.0; + } + } + + for (int i = 0; i < numFibers; i++) { + y = yLocs[i] - yBar; + z = zLocs[i] - zBar; + A = fiberArea[i]; + + dsigdh = theMaterials[i]->getStressSensitivity(gradIndex, conditional); + + ds(0) += dsigdh*A; + ds(1) += -y*dsigdh*A; + ds(2) += z*dsigdh*A; + + if (areaDeriv[i] != 0.0 || dydh[i] != 0.0 || dzdh[i] != 0.0) + stress = theMaterials[i]->getStress(); + + if (dydh[i] != 0.0 || dzdh[i] != 0.0) + tangent = theMaterials[i]->getTangent(); + + if (areaDeriv[i] != 0.0) { + sig_dAdh = stress*areaDeriv[i]; + + ds(0) += sig_dAdh; + ds(1) += -y*sig_dAdh; + ds(2) += z*sig_dAdh; + } + + if (dydh[i] != 0.0) + ds(1) += -dydh[i] * (stress*A); + + if (dzdh[i] != 0.0) + ds(2) += dzdh[i] * (stress*A); + + static Matrix as(1,3); + as(0,0) = 1; + as(0,1) = -y; + as(0,2) = z; + + static Matrix dasdh(1,3); + dasdh(0,1) = -dydh[i]; + dasdh(0,2) = dzdh[i]; + + static Matrix tmpMatrix(3,3); + tmpMatrix.addMatrixTransposeProduct(0.0, as, dasdh, tangent); + + //ds.addMatrixVector(1.0, tmpMatrix, e, A); + ds(0) += (tmpMatrix(0,0)*e(0) + tmpMatrix(0,1)*e(1) + tmpMatrix(0,2)*e(2))*A;//Xinlong: may need to be modified because e is different now. + ds(1) += (tmpMatrix(1,0)*e(0) + tmpMatrix(1,1)*e(1) + tmpMatrix(1,2)*e(2))*A; + ds(2) += (tmpMatrix(2,0)*e(0) + tmpMatrix(2,1)*e(1) + tmpMatrix(2,2)*e(2))*A; + } + + ds(3) = theTorsion->getStressSensitivity(gradIndex, conditional); + + return ds; +} + +const Matrix & +FiberSectionAsym3d::getSectionTangentSensitivity(int gradIndex) +{ + static Matrix something(4,4); + + something.Zero(); + + something(3,3) = theTorsion->getTangentSensitivity(gradIndex); + + return something; +} + +int +FiberSectionAsym3d::commitSensitivity(const Vector& defSens, int gradIndex, int numGrads) +{ + + double d0 = defSens(0); //Xinlong: seems this should be replaced by d0~d7 + double d1 = defSens(1); + double d2 = defSens(2); + double d3 = defSens(3); + + //dedh = defSens; + + static double yLocs[10000]; + static double zLocs[10000]; + + if (sectionIntegr != 0) + sectionIntegr->getFiberLocations(numFibers, yLocs, zLocs); + else { + for (int i = 0; i < numFibers; i++) { + yLocs[i] = matData[3*i]; + zLocs[i] = matData[3*i+1]; + } + } + + static double dydh[10000]; + static double dzdh[10000]; + + if (sectionIntegr != 0) + sectionIntegr->getLocationsDeriv(numFibers, dydh, dzdh); + else { + for (int i = 0; i < numFibers; i++) { + dydh[i] = 0.0; + dzdh[i] = 0.0; + } + } + + double y, z; + + double depsdh = 0; + + for (int i = 0; i < numFibers; i++) { + UniaxialMaterial *theMat = theMaterials[i]; + y = yLocs[i] - yBar; + z = zLocs[i] - zBar; + + // determine material strain and set it + depsdh = d0 - y*d1 + z*d2 - dydh[i]*e(1) + dzdh[i]*e(2); //Xinlong: seems this should be replaced by d0~d7 + + theMat->commitSensitivity(depsdh,gradIndex,numGrads); + } + + theTorsion->commitSensitivity(d3, gradIndex, numGrads); + + return 0; +} + +// AddingSensitivity:END /////////////////////////////////// + + diff --git a/SRC/material/section/FiberSectionAsym3d.h b/SRC/material/section/FiberSectionAsym3d.h new file mode 100644 index 000000000..af074bb06 --- /dev/null +++ b/SRC/material/section/FiberSectionAsym3d.h @@ -0,0 +1,131 @@ +/* ****************************************************************** ** +** 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.14 $ +// $Date: 2008-08-26 16:47:42 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/section/FiberSectionAsym3d.h,v $ + +// Written: fmk +// Created: 04/01 +// +// Description: This file contains the class definition for +// FiberSectionAsym3d.h. FiberSectionAsym3d provides the abstraction of a +// 3d beam section discretized by fibers. The section stiffness and +// stress resultants are obtained by summing fiber contributions. + +// Modified by: Xinlong Du and Jerome F. Hajjar, Northeastern University, USA; Year 2019 +// Description: Modified FiberSection3d.h (from version 3.0.0 on 11/5/2018) +// to include shear center coordinates and high-order longitudinal strain terms. +// References: +// Du, X., & Hajjar, J. (2021). Three-dimensional nonlinear displacement-based beam element +// for members with angle and tee sections. Engineering Structures, 239, 112239. +// Du, X., & Hajjar, J. F. (2021). Three-dimensional nonlinear mixed 6-DOF beam element +// for thin-walled members. Thin-Walled Structures, 164, 107817. + +#ifndef FiberSectionAsym3d_h +#define FiberSectionAsym3d_h + +#include +#include +#include + +class UniaxialMaterial; +class Fiber; +class Response; +class SectionIntegration; + +class FiberSectionAsym3d : public SectionForceDeformation +{ + public: + FiberSectionAsym3d(); + FiberSectionAsym3d(int tag, int numFibers, Fiber **fibers, //Xinlong + UniaxialMaterial *torsion = 0, double ys = 0.0, double zs = 0.0); //Xinlong + FiberSectionAsym3d(int tag, int numFibers, UniaxialMaterial *torsion = 0, double ys=0.0, double zs=0.0); //Xinlong + FiberSectionAsym3d(int tag, int numFibers, UniaxialMaterial **mats, + SectionIntegration &si, UniaxialMaterial *torsion = 0, double ys=0.0, double zs=0.0); //Xinlong + ~FiberSectionAsym3d(); + + const char *getClassType(void) const {return "FiberSectionAsym3d";}; + + int setTrialSectionDeformation(const Vector &deforms); + const Vector &getSectionDeformation(void); + + const Vector &getStressResultant(void); + const Matrix &getSectionTangent(void); + const Matrix &getInitialTangent(void); + + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + SectionForceDeformation *getCopy(void); + const ID &getType (void); + int getOrder (void) const; + + int sendSelf(int cTag, Channel &theChannel); + int recvSelf(int cTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + void Print(OPS_Stream &s, int flag = 0); + + Response *setResponse(const char **argv, int argc, + OPS_Stream &s); + int getResponse(int responseID, Information &info); + + int addFiber(Fiber &theFiber); + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int setParameter(const char **argv, int argc, Parameter ¶m); + + const Vector & getStressResultantSensitivity(int gradIndex, bool conditional); + const Matrix & getSectionTangentSensitivity(int gradIndex); + int commitSensitivity(const Vector& sectionDeformationGradient, int gradIndex, int numGrads); + + const Vector & getSectionDeformationSensitivity(int gradIndex); + // AddingSensitivity:END /////////////////////////////////////////// + + + + protected: + + private: + int numFibers, sizeFibers; // number of fibers in the section + UniaxialMaterial **theMaterials; // array of pointers to materials + double *matData; // data for the materials [yloc, zloc, area] + double kData[25]; // data for ks matrix Xinlong + double sData[5]; // data for s vector Xinlong + + double QzBar, QyBar, Abar; + double yBar; // Section centroid + double zBar; + double ys; //Xinlong: y coord of shear center relative to centroid + double zs; //Xinlong: z coord of shear center relative to centroid + + SectionIntegration *sectionIntegr; + + static ID code; + + Vector e; // trial section deformations + Vector *s; // section resisting forces (axial force, bending moment) + Matrix *ks; // section stiffness + + UniaxialMaterial *theTorsion; +}; + +#endif diff --git a/SRC/material/section/LayeredShellFiberSection.cpp b/SRC/material/section/LayeredShellFiberSection.cpp index 6b09e2d05..bc575d637 100644 --- a/SRC/material/section/LayeredShellFiberSection.cpp +++ b/SRC/material/section/LayeredShellFiberSection.cpp @@ -276,59 +276,9 @@ Response* LayeredShellFiberSection::setResponse(const char **argv, int argc, OPS_Stream &output) { - const ID &type = this->getType(); - int typeSize = this->getOrder(); - Response *theResponse =0; - output.tag("SectionOutput"); - output.attr("secType", this->getClassType()); - output.attr("secTag", this->getTag()); - - // deformations - if (strcmp(argv[0],"deformations") == 0 || strcmp(argv[0],"deformation") == 0) { - 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"); - theResponse = new MaterialResponse(this, 1, this->getSectionDeformation()); - // forces - } else if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0) { - output.tag("ResponseType","p11"); - output.tag("ResponseType","p22"); - output.tag("ResponseType","p12"); - output.tag("ResponseType","m11"); - output.tag("ResponseType","m22"); - output.tag("ResponseType","m12"); - output.tag("ResponseType","q1"); - output.tag("ResponseType","q2"); - theResponse = new MaterialResponse(this, 2, this->getStressResultant()); - - // force and deformation - } else if (strcmp(argv[0],"forceAndDeformation") == 0) { - 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.tag("ResponseType","p11"); - output.tag("ResponseType","p22"); - output.tag("ResponseType","p12"); - output.tag("ResponseType","m11"); - output.tag("ResponseType","m22"); - output.tag("ResponseType","m12"); - output.tag("ResponseType","q1"); - output.tag("ResponseType","q2"); - theResponse = new MaterialResponse(this, 4, Vector(2*this->getOrder())); - } - else if (strcmp(argv[0],"fiber") == 0 || strcmp(argv[0],"Fiber") == 0) { + if (strcmp(argv[0],"fiber") == 0 || strcmp(argv[0],"Fiber") == 0) { if (argc < 3) { opserr << "LayeredShellFiberSection::setResponse() - need to specify more data\n"; return 0; @@ -341,39 +291,22 @@ LayeredShellFiberSection::setResponse(const char **argv, int argc, output.attr("zLoc",0.5*h*sg[pointNum-1]); output.attr("thickness",0.5*h*wg[pointNum-1]); - theResponse = theFibers[pointNum-1]->setResponse(&argv[2], argc-2, output); + theResponse = theFibers[pointNum-1]->setResponse(&argv[2], argc-2, output); output.endTag(); } } - output.endTag(); // SectionOutput + + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); + return theResponse; } int LayeredShellFiberSection::getResponse(int responseID, Information &secInfo) { - switch (responseID) { - case 1: - return secInfo.setVector(this->getSectionDeformation()); - - case 2: - return secInfo.setVector(this->getStressResultant()); - - case 4: { - Vector &theVec = *(secInfo.theVector); - const Vector &e = this->getSectionDeformation(); - const Vector &s = this->getStressResultant(); - for (int i = 0; i < 8; i++) { - theVec(i) = e(i); - theVec(i+8) = s(i); - } - - return secInfo.setVector(theVec); - } - default: - return -1; - } + return SectionForceDeformation::getResponse(responseID, secInfo); } diff --git a/SRC/material/section/LayeredShellFiberSectionThermal.cpp b/SRC/material/section/LayeredShellFiberSectionThermal.cpp index 49403911f..67a0534fe 100644 --- a/SRC/material/section/LayeredShellFiberSectionThermal.cpp +++ b/SRC/material/section/LayeredShellFiberSectionThermal.cpp @@ -203,59 +203,9 @@ Response* LayeredShellFiberSectionThermal::setResponse(const char **argv, int argc, OPS_Stream &output) { - const ID &type = this->getType(); - int typeSize = this->getOrder(); - Response *theResponse =0; - output.tag("SectionOutput"); - output.attr("secType", this->getClassType()); - output.attr("secTag", this->getTag()); - - // deformations - if (strcmp(argv[0],"deformations") == 0 || strcmp(argv[0],"deformation") == 0) { - 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"); - theResponse = new MaterialResponse(this, 1, this->getSectionDeformation()); - // forces - } else if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0) { - output.tag("ResponseType","p11"); - output.tag("ResponseType","p22"); - output.tag("ResponseType","p12"); - output.tag("ResponseType","m11"); - output.tag("ResponseType","m22"); - output.tag("ResponseType","m12"); - output.tag("ResponseType","q1"); - output.tag("ResponseType","q2"); - theResponse = new MaterialResponse(this, 2, this->getStressResultant()); - - // force and deformation - } else if (strcmp(argv[0],"forceAndDeformation") == 0) { - 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.tag("ResponseType","p11"); - output.tag("ResponseType","p22"); - output.tag("ResponseType","p12"); - output.tag("ResponseType","m11"); - output.tag("ResponseType","m22"); - output.tag("ResponseType","m12"); - output.tag("ResponseType","q1"); - output.tag("ResponseType","q2"); - theResponse = new MaterialResponse(this, 4, Vector(2*this->getOrder())); - } - else if (strcmp(argv[0],"fiber") == 0 || strcmp(argv[0],"Fiber") == 0) { + if (strcmp(argv[0],"fiber") == 0 || strcmp(argv[0],"Fiber") == 0) { if (argc < 3) { opserr << "LayeredShellFiberSectionThermal::setResponse() - need to specify more data\n"; return 0; @@ -268,39 +218,22 @@ LayeredShellFiberSectionThermal::setResponse(const char **argv, int argc, output.attr("zLoc",0.5*h*sg[pointNum-1]); output.attr("thickness",0.5*h*wg[pointNum-1]); - theResponse = theFibers[pointNum-1]->setResponse(&argv[2], argc-2, output); + theResponse = theFibers[pointNum-1]->setResponse(&argv[2], argc-2, output); output.endTag(); } } - output.endTag(); // SectionOutput + + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); + return theResponse; } int LayeredShellFiberSectionThermal::getResponse(int responseID, Information &secInfo) { - switch (responseID) { - case 1: - return secInfo.setVector(this->getSectionDeformation()); - - case 2: - return secInfo.setVector(this->getStressResultant()); - - case 4: { - Vector &theVec = *(secInfo.theVector); - const Vector &e = this->getSectionDeformation(); - const Vector &s = this->getStressResultant(); - for (int i = 0; i < 8; i++) { - theVec(i) = e(i); - theVec(i+8) = s(i); - } - - return secInfo.setVector(theVec); - } - default: - return -1; - } + return SectionForceDeformation::getResponse(responseID, secInfo); } diff --git a/SRC/material/section/Makefile b/SRC/material/section/Makefile index d6ea21a23..66db68cf6 100644 --- a/SRC/material/section/Makefile +++ b/SRC/material/section/Makefile @@ -21,19 +21,17 @@ OBJS = SectionForceDeformation.o \ FiberSection2dThermal.o \ FiberSection3d.o \ FiberSectionWarping3d.o \ - FiberSectionGJ.o \ + FiberSectionAsym3d.o \ Bidirectional.o \ Elliptical.o \ Elliptical2.o \ - TimoshenkoSection3d.o \ Isolator2spring.o \ BiaxialHysteretic.o \ McftSection2dfiber.o \ LayeredShellFiberSection.o \ LayeredShellFiberSectionThermal.o \ FiberSection3dThermal.o \ - MembranePlateFiberSectionThermal.o \ - FiberSectionGJThermal.o + MembranePlateFiberSectionThermal.o all: $(OBJS) @$(CD) $(FE)/material/section/repres; $(MAKE); diff --git a/SRC/material/section/MembranePlateFiberSection.cpp b/SRC/material/section/MembranePlateFiberSection.cpp index 3d7882c35..fefc102ec 100644 --- a/SRC/material/section/MembranePlateFiberSection.cpp +++ b/SRC/material/section/MembranePlateFiberSection.cpp @@ -109,6 +109,7 @@ const double MembranePlateFiberSection::wg[] = { 0.1, //null constructor MembranePlateFiberSection::MembranePlateFiberSection( ) : SectionForceDeformation( 0, SEC_TAG_MembranePlateFiberSection ), +h(0.), strainResultant(8) { for ( int i = 0; i < numFibers; i++ ) @@ -515,6 +516,14 @@ MembranePlateFiberSection::sendSelf(int commitTag, Channel &theChannel) // object - don't want to have to do the check if sending data int dataTag = this->getDbTag(); + static Vector vectData(1); + vectData(0) = h; + + res += theChannel.sendVector(dataTag, commitTag, vectData); + if (res < 0) { + opserr << "WARNING MembranePlateFiberSection::sendSelf() - " << this->getTag() << " failed to send vectData\n"; + return res; + } // Now quad sends the ids of its materials int matDbTag; @@ -564,6 +573,16 @@ MembranePlateFiberSection::recvSelf(int commitTag, Channel &theChannel, FEM_Obje int dataTag = this->getDbTag(); + static Vector vectData(1); + res += theChannel.recvVector(dataTag, commitTag, vectData); + + if (res < 0) { + opserr << "WARNING MembranePlateFiberSection::recvSelf() - " << this->getTag() << " failed to recv vectData\n"; + return res; + } + + h = vectData(0); + static ID idData(2*numFibers+1); // Quad now receives the tags of its four external nodes res += theChannel.recvID(dataTag, commitTag, idData); @@ -635,20 +654,21 @@ MembranePlateFiberSection::setResponse(const char **argv, int argc, { Response *theResponse =0; - if (argc > 2 || strcmp(argv[0],"fiber") == 0) { + if (argc > 2 && strcmp(argv[0],"fiber") == 0) { int passarg = 2; int key = atoi(argv[1]); if (key > 0 && key <= numFibers) { - theResponse = theFibers[key-1]->setResponse(&argv[passarg], argc-passarg, output); + theResponse = theFibers[key-1]->setResponse(&argv[passarg], argc-passarg, output); } - return theResponse; } - // If not a fiber response, call the base class method - return SectionForceDeformation::setResponse(argv, argc, output); + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); + + return theResponse; } diff --git a/SRC/material/section/MembranePlateFiberSectionThermal.cpp b/SRC/material/section/MembranePlateFiberSectionThermal.cpp index 15da51307..805c1f1b5 100644 --- a/SRC/material/section/MembranePlateFiberSectionThermal.cpp +++ b/SRC/material/section/MembranePlateFiberSectionThermal.cpp @@ -734,59 +734,9 @@ Response* MembranePlateFiberSectionThermal::setResponse(const char **argv, int argc, OPS_Stream &output) { - const ID &type = this->getType(); - int typeSize = this->getOrder(); - Response *theResponse =0; - output.tag("SectionOutput"); - output.attr("secType", this->getClassType()); - output.attr("secTag", this->getTag()); - - // deformations - if (strcmp(argv[0],"deformations") == 0 || strcmp(argv[0],"deformation") == 0) { - 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"); - theResponse = new MaterialResponse(this, 1, this->getSectionDeformation()); - // forces - } else if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0) { - output.tag("ResponseType","p11"); - output.tag("ResponseType","p22"); - output.tag("ResponseType","p12"); - output.tag("ResponseType","m11"); - output.tag("ResponseType","m22"); - output.tag("ResponseType","m12"); - output.tag("ResponseType","q1"); - output.tag("ResponseType","q2"); - theResponse = new MaterialResponse(this, 2, this->getStressResultant()); - - // force and deformation - } else if (strcmp(argv[0],"forceAndDeformation") == 0) { - 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.tag("ResponseType","p11"); - output.tag("ResponseType","p22"); - output.tag("ResponseType","p12"); - output.tag("ResponseType","m11"); - output.tag("ResponseType","m22"); - output.tag("ResponseType","m12"); - output.tag("ResponseType","q1"); - output.tag("ResponseType","q2"); - theResponse = new MaterialResponse(this, 4, Vector(2*this->getOrder())); - } - else if (strcmp(argv[0],"fiber") == 0 || strcmp(argv[0],"Fiber") == 0) { + if (strcmp(argv[0],"fiber") == 0 || strcmp(argv[0],"Fiber") == 0) { if (argc < 3) { opserr << "MembranePlateFiberSectionThermal::setResponse() - need to specify more data\n"; return 0; @@ -797,38 +747,20 @@ MembranePlateFiberSectionThermal::setResponse(const char **argv, int argc, output.tag("FiberOutput"); output.attr("number",pointNum); - theResponse = theFibers[pointNum-1]->setResponse(&argv[2], argc-2, output); + theResponse = theFibers[pointNum-1]->setResponse(&argv[2], argc-2, output); output.endTag(); } } - output.endTag(); // SectionOutput + + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); + return theResponse; } int MembranePlateFiberSectionThermal::getResponse(int responseID, Information &secInfo) { - switch (responseID) { - case 1: - return secInfo.setVector(this->getSectionDeformation()); - - case 2: - return secInfo.setVector(this->getStressResultant()); - - case 4: { - Vector &theVec = *(secInfo.theVector); - const Vector &e = this->getSectionDeformation(); - const Vector &s = this->getStressResultant(); - for (int i = 0; i < 8; i++) { - theVec(i) = e(i); - theVec(i+8) = s(i); - } - - return secInfo.setVector(theVec); - } - default: - return -1; - } -} - + return SectionForceDeformation::getResponse(responseID, secInfo); +} diff --git a/SRC/material/section/NDFiberSection2d.cpp b/SRC/material/section/NDFiberSection2d.cpp index 998a82a01..acbd33133 100644 --- a/SRC/material/section/NDFiberSection2d.cpp +++ b/SRC/material/section/NDFiberSection2d.cpp @@ -1042,9 +1042,20 @@ Response* NDFiberSection2d::setResponse(const char **argv, int argc, OPS_Stream &output) { - Response *theResponse =0; + Response *theResponse = 0; - if (argc > 2 || strcmp(argv[0],"fiber") == 0) { + if (argc > 2 && strcmp(argv[0],"fiber") == 0) { + + static double fiberLocs[10000]; + + if (sectionIntegr != 0) { + sectionIntegr->getFiberLocations(numFibers, fiberLocs); + } + else { + for (int i = 0; i < numFibers; i++) { + fiberLocs[i] = matData[2*i]; + } + } int key = numFibers; int passarg = 2; @@ -1065,9 +1076,10 @@ NDFiberSection2d::setResponse(const char **argv, int argc, // Find first fiber with specified material tag for (j = 0; j < numFibers; j++) { if (matTag == theMaterials[j]->getTag()) { - ySearch = matData[2*j]; + //ySearch = matData[2*j]; + ySearch = fiberLocs[j]; dy = ySearch-yCoord; - closestDist = fabs(dy); + closestDist = dy*dy; key = j; break; } @@ -1075,9 +1087,10 @@ NDFiberSection2d::setResponse(const char **argv, int argc, // Search the remaining fibers for ( ; j < numFibers; j++) { if (matTag == theMaterials[j]->getTag()) { - ySearch = matData[2*j]; + //ySearch = matData[2*j]; + ySearch = fiberLocs[j]; dy = ySearch-yCoord; - distance = fabs(dy); + distance = dy*dy; if (distance < closestDist) { closestDist = distance; key = j; @@ -1094,15 +1107,17 @@ NDFiberSection2d::setResponse(const char **argv, int argc, double ySearch, dy; double distance; - ySearch = matData[0]; + //ySearch = matData[0]; + ySearch = fiberLocs[0]; dy = ySearch-yCoord; closestDist = fabs(dy); key = 0; for (int j = 1; j < numFibers; j++) { - ySearch = matData[2*j]; + //ySearch = matData[2*j]; + ySearch = fiberLocs[j]; dy = ySearch-yCoord; - distance = fabs(dy); + distance = dy*dy; if (distance < closestDist) { closestDist = distance; key = j; @@ -1117,16 +1132,17 @@ NDFiberSection2d::setResponse(const char **argv, int argc, output.attr("zLoc",0.0); output.attr("area",matData[2*key+1]); - theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); + theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); output.endTag(); } - return theResponse; } - // If not a fiber response, call the base class method - return SectionForceDeformation::setResponse(argv, argc, output); + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); + + return theResponse; } diff --git a/SRC/material/section/NDFiberSection3d.cpp b/SRC/material/section/NDFiberSection3d.cpp index 09d45edc3..5c420fe79 100644 --- a/SRC/material/section/NDFiberSection3d.cpp +++ b/SRC/material/section/NDFiberSection3d.cpp @@ -1233,7 +1233,20 @@ NDFiberSection3d::setResponse(const char **argv, int argc, { Response *theResponse =0; - if (argc > 2 || strcmp(argv[0],"fiber") == 0) { + if (argc > 2 && strcmp(argv[0],"fiber") == 0) { + + static double yLocs[10000]; + static double zLocs[10000]; + + if (sectionIntegr != 0) { + sectionIntegr->getFiberLocations(numFibers, yLocs, zLocs); + } + else { + for (int i = 0; i < numFibers; i++) { + yLocs[i] = matData[3*i]; + zLocs[i] = matData[3*i+1]; + } + } int key = numFibers; int passarg = 2; @@ -1254,11 +1267,13 @@ NDFiberSection3d::setResponse(const char **argv, int argc, // Find first fiber with specified material tag for (j = 0; j < numFibers; j++) { if (matTag == theMaterials[j]->getTag()) { - ySearch = matData[3*j]; - zSearch = matData[3*j+1]; + //ySearch = matData[3*j]; + //zSearch = matData[3*j+1]; + ySearch = yLocs[j]; + zSearch = zLocs[j]; dy = ySearch-yCoord; dz = zSearch-zCoord; - closestDist = sqrt(dy*dy + dz*dz); + closestDist = dy*dy + dz*dz; key = j; break; } @@ -1266,11 +1281,13 @@ NDFiberSection3d::setResponse(const char **argv, int argc, // Search the remaining fibers for ( ; j < numFibers; j++) { if (matTag == theMaterials[j]->getTag()) { - ySearch = matData[3*j]; - zSearch = matData[3*j+1]; + //ySearch = matData[3*j]; + //zSearch = matData[3*j+1]; + ySearch = yLocs[j]; + zSearch = zLocs[j]; dy = ySearch-yCoord; dz = zSearch-zCoord; - distance = sqrt(dy*dy + dz*dz); + distance = dy*dy + dz*dz; if (distance < closestDist) { closestDist = distance; key = j; @@ -1288,18 +1305,22 @@ NDFiberSection3d::setResponse(const char **argv, int argc, double ySearch, zSearch, dy, dz; double distance; - ySearch = matData[0]; - zSearch = matData[1]; + //ySearch = matData[0]; + //zSearch = matData[1]; + ySearch = yLocs[0]; + zSearch = zLocs[0]; dy = ySearch-yCoord; dz = zSearch-zCoord; - closestDist = sqrt(dy*dy + dz*dz); + closestDist = dy*dy + dz*dz; key = 0; for (int j = 1; j < numFibers; j++) { - ySearch = matData[3*j]; - zSearch = matData[3*j+1]; + //ySearch = matData[3*j]; + //zSearch = matData[3*j+1]; + ySearch = yLocs[j]; + zSearch = zLocs[j]; dy = ySearch-yCoord; dz = zSearch-zCoord; - distance = sqrt(dy*dy + dz*dz); + distance = dy*dy + dz*dz; if (distance < closestDist) { closestDist = distance; key = j; @@ -1314,16 +1335,17 @@ NDFiberSection3d::setResponse(const char **argv, int argc, output.attr("zLoc",matData[3*key+1]); output.attr("area",matData[3*key+2]); - theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); + theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); output.endTag(); } - return theResponse; } - // If not a fiber response, call the base class method - return SectionForceDeformation::setResponse(argv, argc, output); + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); + + return theResponse; } diff --git a/SRC/material/section/NDFiberSectionWarping2d.cpp b/SRC/material/section/NDFiberSectionWarping2d.cpp index cbea9480a..4ab9831c4 100644 --- a/SRC/material/section/NDFiberSectionWarping2d.cpp +++ b/SRC/material/section/NDFiberSectionWarping2d.cpp @@ -1306,7 +1306,7 @@ Response* { Response *theResponse =0; - if (argc > 2 || strcmp(argv[0],"fiber") == 0) { + if (argc > 2 && strcmp(argv[0],"fiber") == 0) { int key = numFibers; int passarg = 2; @@ -1329,7 +1329,7 @@ Response* if (matTag == theMaterials[j]->getTag()) { ySearch = matData[2*j]; dy = ySearch-yCoord; - closestDist = fabs(dy); + closestDist = dy*dy; key = j; break; } @@ -1339,7 +1339,7 @@ Response* if (matTag == theMaterials[j]->getTag()) { ySearch = matData[2*j]; dy = ySearch-yCoord; - distance = fabs(dy); + distance = dy*dy; if (distance < closestDist) { closestDist = distance; key = j; @@ -1358,13 +1358,13 @@ Response* ySearch = matData[0]; dy = ySearch-yCoord; - closestDist = fabs(dy); + closestDist = dy*dy; key = 0; for (int j = 1; j < numFibers; j++) { ySearch = matData[2*j]; dy = ySearch-yCoord; - distance = fabs(dy); + distance = dy*dy; if (distance < closestDist) { closestDist = distance; key = j; @@ -1384,16 +1384,17 @@ Response* output.endTag(); } - return theResponse; } - // If not a fiber response, call the base class method - return SectionForceDeformation::setResponse(argv, argc, output); + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); + + return theResponse; } int - NDFiberSectionWarping2d::getResponse(int responseID, Information §Info) +NDFiberSectionWarping2d::getResponse(int responseID, Information §Info) { // Just call the base class method ... don't need to define // this function, but keeping it here just for clarity diff --git a/SRC/material/section/ParallelSection.cpp b/SRC/material/section/ParallelSection.cpp index 8eaf58ef4..132c114b0 100644 --- a/SRC/material/section/ParallelSection.cpp +++ b/SRC/material/section/ParallelSection.cpp @@ -444,26 +444,6 @@ ParallelSection::Print(OPS_Stream &s, int flag) } } -Response* -ParallelSection::setResponse(const char **argv, int argc, OPS_Stream &output) -{ - // See if the response is one of the defaults - Response *res = SectionForceDeformation::setResponse(argv, argc, output); - if (res != 0) - return res; - else - return 0; -} - -int -ParallelSection::getResponse(int responseID, Information &info) -{ - // Just call the base class method ... don't need to define - // this function, but keeping it here just for clarity - return SectionForceDeformation::getResponse(responseID, info); -} - - // AddingSensitivity:BEGIN //////////////////////////////////// int ParallelSection::setParameter(const char **argv, int argc, Parameter ¶m) diff --git a/SRC/material/section/ParallelSection.h b/SRC/material/section/ParallelSection.h index ff7759b6c..0be3a13c0 100644 --- a/SRC/material/section/ParallelSection.h +++ b/SRC/material/section/ParallelSection.h @@ -78,9 +78,6 @@ class ParallelSection : public SectionForceDeformation void Print(OPS_Stream &s, int flag =0); - Response *setResponse(const char **argv, int argc, OPS_Stream &s); - int getResponse(int responseID, Information &info); - // AddingSensitivity:BEGIN ////////////////////////////////////////// int setParameter(const char **argv, int argc, Parameter ¶m); const Vector & getStressResultantSensitivity(int gradIndex, bool diff --git a/SRC/material/section/SectionAggregator.cpp b/SRC/material/section/SectionAggregator.cpp index 380f7af4a..0c925d002 100644 --- a/SRC/material/section/SectionAggregator.cpp +++ b/SRC/material/section/SectionAggregator.cpp @@ -954,51 +954,31 @@ SectionAggregator::setResponse(const char **argv, int argc, OPS_Stream &output) Response *theResponse =0; - if ( (strcmp(argv[0],"deformations") == 0) || (strcmp(argv[0],"deformation") == 0) || - (strcmp(argv[0],"forces") == 0) || (strcmp(argv[0],"force") == 0) || - (strcmp(argv[0],"forceAndDeformation") == 0)) { + if (argc > 2 && (strcmp(argv[0],"addition") == 0) || (strcmp(argv[0],"material") == 0)) { + + // Get the tag of the material + int materialTag = atoi(argv[1]); - return this->SectionForceDeformation::setResponse(argv, argc, output); - } - // by SAJalali - int num = numMats; - if (theSection != 0) - num++; - if ((strcmp(argv[0], "energy") == 0) || (strcmp(argv[0], "Energy") == 0)) { - return theResponse = new MaterialResponse(this, 8, Vector(num)); + // Loop to find the right material + int ok = 0; + for (int i = 0; i < numMats; i++) + if (materialTag == theAdditions[i]->getTag()) + theResponse = theAdditions[i]->setResponse(&argv[2], argc-2, output); } + if (argc > 1 && strcmp(argv[0],"section") == 0) + theResponse = theSection->setResponse(&argv[1], argc-1, output); - if (theSection != 0) - return theSection->setResponse(argv, argc, output); - else - return this->SectionForceDeformation::setResponse(argv, argc, output); - - return 0; + if (theResponse == 0) + return SectionForceDeformation::setResponse(argv, argc, output); + + return theResponse; } -//by SAJalali int SectionAggregator::getResponse(int responseID, Information §Info) { - FiberSection2d* sec = 0; - int num = numMats; - if (theSection != 0) - num++; - Vector res(num); - if (responseID == 8) { - for (int i = 0; i < numMats; i++) - res(i) = theAdditions[i]->getEnergy(); - sec = (FiberSection2d*)theSection; - if (sec != 0) - res(numMats) = sec->getEnergy(); - sectInfo.setVector(res); - //opserr << "energyVect=" << res << "\n"; - } - else - return SectionForceDeformation::getResponse(responseID, sectInfo); - - return 0; + return SectionForceDeformation::getResponse(responseID, sectInfo); } diff --git a/SRC/material/section/SectionAggregator.h b/SRC/material/section/SectionAggregator.h index 01177d25b..b4d1cad51 100644 --- a/SRC/material/section/SectionAggregator.h +++ b/SRC/material/section/SectionAggregator.h @@ -84,8 +84,7 @@ class SectionAggregator : public SectionForceDeformation FEM_ObjectBroker &theBroker); Response *setResponse(const char **argv, int argc, OPS_Stream &s); - //by SAJalali - int getResponse(int responseID, Information &info); + int getResponse(int responseID, Information &info); void Print(OPS_Stream &s, int flag =0); diff --git a/SRC/material/section/TclModelBuilderSectionCommand.cpp b/SRC/material/section/TclModelBuilderSectionCommand.cpp index 5788000c7..04a1b9310 100755 --- a/SRC/material/section/TclModelBuilderSectionCommand.cpp +++ b/SRC/material/section/TclModelBuilderSectionCommand.cpp @@ -56,6 +56,7 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp #include #include #include +#include //#include #include @@ -119,6 +120,10 @@ int TclCommand_addFiberSection (ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv, TclModelBuilder *theBuilder); +int +TclCommand_addFiberSectionAsym (ClientData clientData, Tcl_Interp* interp, int argc, + TCL_Char** argv, TclModelBuilder* theBuilder); + int TclCommand_addFiberIntSection (ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv, TclModelBuilder *theBuilder); @@ -523,6 +528,9 @@ TclModelBuilderSectionCommand (ClientData clientData, Tcl_Interp *interp, int ar return TclCommand_addFiberSection (clientData, interp, argc, argv, theTclBuilder); + else if (strcmp(argv[1], "FiberAsym") == 0 || strcmp(argv[1], "fiberSecAsym") == 0) + return TclCommand_addFiberSectionAsym (clientData, interp, argc, argv, theTclBuilder); //Xinlong + //--- Adding Thermo-mechanical Sections:[BEGIN] by UoE OpenSees Group ---// else if (strcmp(argv[1],"FiberThermal") == 0 || strcmp(argv[1],"fiberSecThermal") == 0) return TclCommand_addFiberSectionThermal (clientData, interp, argc, argv, @@ -952,6 +960,10 @@ int buildSection(Tcl_Interp *interp, TclModelBuilder *theTclModelBuilder, int secTag, UniaxialMaterial &theTorsion); +int +buildSectionAsym(Tcl_Interp* interp, TclModelBuilder* theTclModelBuilder, + int secTag, bool isTorsion, double GJ, double Ys, double Zs); //Xinlong + int buildSectionInt(Tcl_Interp *interp, TclModelBuilder *theTclModelBuilder, int secTag, UniaxialMaterial &theTorsion, @@ -2992,4 +3004,359 @@ int buildSectionThermal(Tcl_Interp *interp, TclModelBuilder *theTclModelBuilder, ///--Adding function for building FiberSectionThermal:[END] by UoE OpenSees Group --/// //Changes made by L.Jiang [SIF] +int +TclCommand_addFiberSectionAsym(ClientData clientData, Tcl_Interp* interp, int argc, + TCL_Char** argv, TclModelBuilder* theTclModelBuilder) +{ + int secTag; + int maxNumPatches = 30; + int maxNumReinfLayers = 30; + + if (argc < 4) + return TCL_ERROR; + + if (Tcl_GetInt(interp, argv[2], &secTag) != TCL_OK) { + opserr << "WARNING bad command - want: \nsection fiberSec secTag { \n\tpatch \n\tlayer \n}\n"; + return TCL_ERROR; + } + + currentSectionTag = secTag; + currentSectionIsND = false; + currentSectionIsWarping = false; + if (strcmp(argv[1], "NDFiber") == 0) + currentSectionIsND = true; + if (strcmp(argv[1], "NDFiberWarping") == 0) { + currentSectionIsND = true; + currentSectionIsWarping = true; + } + + // create the fiber section representation (with the geometric information) + + SectionRepres* fiberSectionRepr = + new FiberSectionRepr(secTag, maxNumPatches, maxNumReinfLayers); + + if (fiberSectionRepr == 0) { + opserr << "WARNING - ran out of memory to create section representation\n"; + return TCL_ERROR; + } + + if (theTclModelBuilder->addSectionRepres(*fiberSectionRepr) < 0) { + opserr << "WARNING - cannot add section representation\n"; + return TCL_ERROR; + } + //Xinlong + double Ys, Zs; //Xinlong: input of coords of shear center relative to centroid + if (Tcl_GetDouble(interp, argv[3], &Ys) != TCL_OK) { + opserr << "WARNING invalid Ys"; + return TCL_ERROR; + } + if (Tcl_GetDouble(interp, argv[4], &Zs) != TCL_OK) { + opserr << "WARNING invalid Zs"; + return TCL_ERROR; + } + //Xinlong + + int brace = 5; // Start of recursive parse //Xinlong + double GJ = 1.0; + bool isTorsion = false; + if (strcmp(argv[5], "-GJ") == 0) { //Xinlong + if (Tcl_GetDouble(interp, argv[6], &GJ) != TCL_OK) { //Xinlong + opserr << "WARNING invalid GJ"; + return TCL_ERROR; + } + isTorsion = true; + brace = 7; //Xinlong + } + + // parse the information inside the braces (patches and reinforcing layers) + if (Tcl_Eval(interp, argv[brace]) != TCL_OK) { + opserr << "WARNING - error reading information in { } \n"; + return TCL_ERROR; + } + + // build the fiber section (for analysis) + if (buildSectionAsym(interp, theTclModelBuilder, secTag, isTorsion, GJ, Ys, Zs) != TCL_OK) { //Xinlong + opserr << "WARNING - error constructing the section\n"; + return TCL_ERROR; + } + + // currentSectionTag = 0; + + return TCL_OK; +} + +int +buildSectionAsym(Tcl_Interp* interp, TclModelBuilder* theTclModelBuilder, + int secTag, bool isTorsion, double GJ, double Ys, double Zs) //Xinlong +{ + SectionRepres* sectionRepres = theTclModelBuilder->getSectionRepres(secTag); + if (sectionRepres == 0) + { + opserr << "WARNING cannot retrieve section\n"; + return TCL_ERROR; + } + + if (sectionRepres->getType() == SEC_TAG_FiberSection) + { + // build the section + + FiberSectionRepr* fiberSectionRepr = (FiberSectionRepr*)sectionRepres; + + int i, j, k; + int numFibers; + + int numPatches; + Patch** patch; + + int numReinfLayers; + ReinfLayer** reinfLayer; + + numPatches = fiberSectionRepr->getNumPatches(); + patch = fiberSectionRepr->getPatches(); + numReinfLayers = fiberSectionRepr->getNumReinfLayers(); + reinfLayer = fiberSectionRepr->getReinfLayers(); + + int numSectionRepresFibers = fiberSectionRepr->getNumFibers(); + Fiber** sectionRepresFibers = fiberSectionRepr->getFibers(); + + numFibers = numSectionRepresFibers; + for (i = 0; i < numPatches; i++) + numFibers += patch[i]->getNumCells(); + + for (i = 0; i < numReinfLayers; i++) + numFibers += reinfLayer[i]->getNumReinfBars(); + + //opserr << "\nnumFibers: " << numFibers; + + static Vector fiberPosition(2); + int matTag; + + ID fibersMaterial(numFibers - numSectionRepresFibers); + Matrix fibersPosition(2, numFibers - numSectionRepresFibers); + Vector fibersArea(numFibers - numSectionRepresFibers); + + int numCells; + Cell** cell; + + k = 0; + for (i = 0; i < numPatches; i++) + { + //opserr << "\nPatch :" << i; + + numCells = patch[i]->getNumCells(); + matTag = patch[i]->getMaterialID(); + + //opserr << "\nmatTag: " << matTag(k); + + cell = patch[i]->getCells(); + + if (cell == 0) + { + opserr << "WARNING out of run to create fibers\n"; + return TCL_ERROR; + } + + //opserr << "\n\tnumCells :" << numCells; + + for (j = 0; j < numCells; j++) + { + fibersMaterial(k) = matTag; + fibersArea(k) = cell[j]->getArea(); + fiberPosition = cell[j]->getCentroidPosition(); + + fibersPosition(0, k) = fiberPosition(0); + fibersPosition(1, k) = fiberPosition(1); + + k++; + } + + for (j = 0; j < numCells; j++) + delete cell[j]; + + delete[] cell; + } + + ReinfBar* reinfBar; + int numReinfBars; + + for (i = 0; i < numReinfLayers; i++) + { + numReinfBars = reinfLayer[i]->getNumReinfBars(); + reinfBar = reinfLayer[i]->getReinfBars(); + matTag = reinfLayer[i]->getMaterialID(); + + for (j = 0; j < numReinfBars; j++) + { + fibersMaterial(k) = matTag; + fibersArea(k) = reinfBar[j].getArea(); + fiberPosition = reinfBar[j].getPosition(); + + fibersPosition(0, k) = fiberPosition(0); + fibersPosition(1, k) = fiberPosition(1); + + k++; + } + delete[] reinfBar; + } + + UniaxialMaterial* material; + NDMaterial* ndmaterial; + // dimension of the structure (1d, 2d, or 3d) + int NDM = theTclModelBuilder->getNDM(); + + Fiber** fiber = new Fiber * [numFibers]; + if (fiber == 0) { + opserr << "WARNING unable to allocate fibers \n"; + return TCL_ERROR; + } + + // copy the section repres fibers + for (i = 0; i < numSectionRepresFibers; i++) + fiber[i] = sectionRepresFibers[i]; + + // creates 2d section + + + if (NDM == 2) { + k = 0; + for (i = numSectionRepresFibers; i < numFibers; i++) { + if (currentSectionIsND) { + ndmaterial = OPS_getNDMaterial(fibersMaterial(k)); + if (ndmaterial == 0) { + opserr << "WARNING invalid NDmaterial ID for patch\n"; + return TCL_ERROR; + } + fiber[i] = new NDFiber2d(k, *ndmaterial, fibersArea(k), fibersPosition(0, k)); + } + else { + material = OPS_getUniaxialMaterial(fibersMaterial(k)); + if (material == 0) { + opserr << "WARNING invalid UniaxialMaterial ID for patch\n"; + return TCL_ERROR; + } + fiber[i] = new UniaxialFiber2d(k, *material, fibersArea(k), fibersPosition(0, k)); + } + if (fiber[i] == 0) { + opserr << "WARNING unable to allocate fiber \n"; + return TCL_ERROR; + } + + //opserr << *fiber[k]; + k++; + } + + + SectionForceDeformation* section = 0; + if (currentSectionIsND) { + if (currentSectionIsWarping) + section = new NDFiberSectionWarping2d(secTag, numFibers, fiber); + else + section = new NDFiberSection2d(secTag, numFibers, fiber); + } + else + section = new FiberSection2d(secTag, numFibers, fiber); + + //SectionForceDeformation *section = new FiberSection(secTag, numFibers, fiber); + + // Delete fibers + for (i = 0; i < numFibers; i++) + delete fiber[i]; + + if (section == 0) + { + opserr << "WARNING - cannot construct section\n"; + return TCL_ERROR; + } + + //if (theTclModelBuilder->addSection (*section) < 0) { + if (OPS_addSectionForceDeformation(section) != true) { + opserr << "WARNING - cannot add section\n"; + return TCL_ERROR; + } + + //opserr << "section: " << *section; + + } + else if (NDM == 3) + { + + static Vector fiberPosition(2); + k = 0; + for (i = numSectionRepresFibers; i < numFibers; i++) { + fiberPosition(0) = fibersPosition(0, k); + fiberPosition(1) = fibersPosition(1, k); + if (currentSectionIsND) { + ndmaterial = OPS_getNDMaterial(fibersMaterial(k)); + if (ndmaterial == 0) { + opserr << "WARNING invalid NDmaterial ID for patch\n"; + return TCL_ERROR; + } + fiber[i] = new NDFiber3d(k, *ndmaterial, fibersArea(k), fiberPosition(0), fiberPosition(1)); + } + else { + material = OPS_getUniaxialMaterial(fibersMaterial(k)); + if (material == 0) { + opserr << "WARNING invalid UniaxialMaterial ID for patch\n"; + return TCL_ERROR; + } + fiber[i] = new UniaxialFiber3d(k, *material, fibersArea(k), fiberPosition); + } + if (fiber[k] == 0) { + opserr << "WARNING unable to allocate fiber \n"; + return TCL_ERROR; + } + k++; + //opserr << *fiber[k]; + } + + //SectionForceDeformation *section = new FiberSection(secTag, numFibers, fiber); + SectionForceDeformation* section = 0; + if (currentSectionIsND) + section = new NDFiberSection3d(secTag, numFibers, fiber); + else if (isTorsion) { + ElasticMaterial theGJ(0, GJ); + //FiberSection3d theFS(0, numFibers, fiber); + //section = new SectionAggregator(secTag, theFS, theGJ, SECTION_RESPONSE_T); + section = new FiberSectionAsym3d(secTag, numFibers, fiber, &theGJ, Ys, Zs); //Xinlong + } + else + section = new FiberSectionAsym3d(secTag, numFibers, fiber, 0, Ys, Zs); //Xinlong + + // Delete fibers + for (i = 0; i < numFibers; i++) + delete fiber[i]; + + if (section == 0) + { + opserr << "WARNING - cannot construct section\n"; + return TCL_ERROR; + } + + //if (theTclModelBuilder->addSection (*section) < 0) { + if (OPS_addSectionForceDeformation(section) != true) { + opserr << "WARNING - cannot add section\n"; + return TCL_ERROR; + } + + //opserr << "section: " << *section; + + } + else + { + opserr << "WARNING NDM = " << NDM << " is imcompatible with available frame elements\n"; + return TCL_ERROR; + } + + // Delete fiber array + delete[] fiber; + + } + else + { + opserr << "WARNING section invalid: can only build fiber sections\n"; + return TCL_ERROR; + } + + return TCL_OK; +} \ No newline at end of file diff --git a/SRC/material/uniaxial/BraceMaterial.cpp b/SRC/material/uniaxial/BraceMaterial.cpp index 5cdb8555a..23f1d0cef 100644 --- a/SRC/material/uniaxial/BraceMaterial.cpp +++ b/SRC/material/uniaxial/BraceMaterial.cpp @@ -39,13 +39,8 @@ static int numBilinMaterials = 0; static int numCastMaterials = 0; void * -OPS_Cast(void) +OPS_BraceMaterial(void) { - if (numCastMaterials == 0) { - numCastMaterials++; - opserr << "Cast Fuse uniaxial material - Written by Dimitrios G. Lignos, Ph.D.\n"; - } - // Pointer to a uniaxial material that will be returned UniaxialMaterial *theMaterial = 0; diff --git a/SRC/material/uniaxial/Concrete02.cpp b/SRC/material/uniaxial/Concrete02.cpp index 9498f726b..2b215dd65 100644 --- a/SRC/material/uniaxial/Concrete02.cpp +++ b/SRC/material/uniaxial/Concrete02.cpp @@ -66,19 +66,22 @@ OPS_Concrete02() numData = OPS_GetNumRemainingInputArgs(); - if (numData != 7) { - opserr << "Invalid #args, want: uniaxialMaterial Concrete02 " << iData[0] << "fpc? epsc0? fpcu? epscu? rat? ft? Ets?\n"; + if (numData != 4 && numData != 7) { + opserr << "Invalid #args, want: uniaxialMaterial Concrete02 " << iData[0] << " fpc? epsc0? fpcu? epscu? \n"; return 0; } if (OPS_GetDoubleInput(&numData, dData) != 0) { - opserr << "Invalid #args, want: uniaxialMaterial Concrete02 " << iData[0] << "fpc? epsc0? fpcu? epscu? rat? ft? Ets?\n"; + opserr << "Invalid #args, want: uniaxialMaterial Concrete02 " << iData[0] << " fpc? epsc0? fpcu? epscu? \n"; return 0; } // Parsing was successful, allocate the material - theMaterial = new Concrete02(iData[0], dData[0], dData[1], dData[2], dData[3], dData[4], dData[5], dData[6]); + if (numData == 7) + theMaterial = new Concrete02(iData[0], dData[0], dData[1], dData[2], dData[3], dData[4], dData[5], dData[6]); + else + theMaterial = new Concrete02(iData[0], dData[0], dData[1], dData[2], dData[3]); if (theMaterial == 0) { opserr << "WARNING could not create uniaxialMaterial of type Concrete02 Material\n"; @@ -104,6 +107,28 @@ Concrete02::Concrete02(int tag, double _fc, double _epsc0, double _fcu, e = 2.0*fc/epsc0; } +Concrete02::Concrete02(int tag, double _fc, double _epsc0, double _fcu, + double _epscu): + UniaxialMaterial(tag, MAT_TAG_Concrete02), + fc(_fc), epsc0(_epsc0), fcu(_fcu), epscu(_epscu) +{ + ecminP = 0.0; + deptP = 0.0; + + eP = 2.0*fc/epsc0; + epsP = 0.0; + sigP = 0.0; + eps = 0.0; + sig = 0.0; + e = 2.0*fc/epsc0; + + rat = 0.1; + ft = 0.1*fc; + if (ft < 0.0) + ft = -ft; + Ets = 0.1*fc/epsc0; +} + Concrete02::Concrete02(void): UniaxialMaterial(0, MAT_TAG_Concrete02) { diff --git a/SRC/material/uniaxial/Concrete02.h b/SRC/material/uniaxial/Concrete02.h index 1a0d128a1..5162921aa 100644 --- a/SRC/material/uniaxial/Concrete02.h +++ b/SRC/material/uniaxial/Concrete02.h @@ -47,6 +47,8 @@ class Concrete02 : public UniaxialMaterial public: Concrete02(int tag, double _fc, double _epsc0, double _fcu, double _epscu, double _rat, double _ft, double _Ets); + Concrete02(int tag, double _fc, double _epsc0, double _fcu, + double _epscu); Concrete02(void); diff --git a/SRC/material/uniaxial/Concrete02IS.cpp b/SRC/material/uniaxial/Concrete02IS.cpp index 4c83d2497..f5ca4fd98 100644 --- a/SRC/material/uniaxial/Concrete02IS.cpp +++ b/SRC/material/uniaxial/Concrete02IS.cpp @@ -68,19 +68,22 @@ OPS_Concrete02IS() numData = OPS_GetNumRemainingInputArgs(); - if (numData != 8) { - opserr << "Invalid #args, want: uniaxialMaterial Concrete02IS " << iData[0] << "E0? fpc? epsc0? fpcu? epscu? rat? ft? Ets?\n"; + if (numData != 5 && numData != 8) { + opserr << "Invalid #args, want: uniaxialMaterial Concrete02IS " << iData[0] << " E0? fpc? epsc0? fpcu? epscu? \n"; return 0; } if (OPS_GetDoubleInput(&numData, dData) != 0) { - opserr << "Invalid #args, want: uniaxialMaterial Concrete02IS " << iData[0] << "E0? fpc? epsc0? fpcu? epscu? rat? ft? Ets?\n"; + opserr << "Invalid #args, want: uniaxialMaterial Concrete02IS " << iData[0] << " E0? fpc? epsc0? fpcu? epscu? \n"; return 0; } // Parsing was successful, allocate the material - theMaterial = new Concrete02IS(iData[0], dData[0], dData[1], dData[2], dData[3], dData[4], dData[5], dData[6], dData[7]); + if (numData == 8) + theMaterial = new Concrete02IS(iData[0], dData[0], dData[1], dData[2], dData[3], dData[4], dData[5], dData[6], dData[7]); + else + theMaterial = new Concrete02IS(iData[0], dData[0], dData[1], dData[2], dData[3], dData[4]); if (theMaterial == 0) { opserr << "WARNING could not create uniaxialMaterial of type Concrete02IS Material\n"; @@ -104,8 +107,30 @@ Concrete02IS::Concrete02IS(int tag, double _E0, double _fc, double _epsc0, doubl eps = 0.0; sig = 0.0; e = E0;//2.0*fc/epsc0; // Marafi Change 2018/01/31 - E0 = E0; + //E0 = E0; +} + +Concrete02IS::Concrete02IS(int tag, double _E0, double _fc, double _epsc0, double _fcu, + double _epscu): + UniaxialMaterial(tag, MAT_TAG_Concrete02IS), + fc(_fc), epsc0(_epsc0), fcu(_fcu), epscu(_epscu), E0(_E0) +{ + ecminP = 0.0; + deptP = 0.0; + + eP = E0;//2.0*fc / epsc0; // Marafi Change 2018/01/31 + epsP = 0.0; + sigP = 0.0; + eps = 0.0; + sig = 0.0; + e = E0;//2.0*fc/epsc0; // Marafi Change 2018/01/31 + //E0 = E0; + rat = 0.1; + ft = 0.1*fc; + if (ft < 0.0) + ft = -ft; + Ets = 0.1*fc/epsc0; } Concrete02IS::Concrete02IS(void): diff --git a/SRC/material/uniaxial/Concrete02IS.h b/SRC/material/uniaxial/Concrete02IS.h index e957045ba..40599cf8e 100644 --- a/SRC/material/uniaxial/Concrete02IS.h +++ b/SRC/material/uniaxial/Concrete02IS.h @@ -49,6 +49,8 @@ class Concrete02IS : public UniaxialMaterial public: Concrete02IS(int tag, double _E0, double _fc, double _epsc0, double _fcu, double _epscu, double _rat, double _ft, double _Ets); + Concrete02IS(int tag, double _E0, double _fc, double _epsc0, double _fcu, + double _epscu); Concrete02IS(void); diff --git a/SRC/material/uniaxial/ENTMaterial.cpp b/SRC/material/uniaxial/ENTMaterial.cpp index 610718bfd..77cc3ea76 100644 --- a/SRC/material/uniaxial/ENTMaterial.cpp +++ b/SRC/material/uniaxial/ENTMaterial.cpp @@ -68,14 +68,14 @@ void* OPS_ENTMaterial() ENTMaterial::ENTMaterial(int tag, double e, double A, double B) :UniaxialMaterial(tag,MAT_TAG_ENTMaterial), - E(e), trialStrain(0.0), parameterID(0),a(A), b(B) + E(e), commitStrain(0.0), trialStrain(0.0), parameterID(0),a(A), b(B) { } ENTMaterial::ENTMaterial() :UniaxialMaterial(0,MAT_TAG_ENTMaterial), - E(0.0), trialStrain(0.0), parameterID(0) + E(0.0), commitStrain(0.0), trialStrain(0.0), parameterID(0), a(0.0), b(1.0) { } @@ -124,20 +124,24 @@ ENTMaterial::getTangent(void) int ENTMaterial::commitState(void) -{ +{ + commitStrain = trialStrain; return 0; } int ENTMaterial::revertToLastCommit(void) { + trialStrain = commitStrain; return 0; } int ENTMaterial::revertToStart(void) { - return 0; + commitStrain = 0.; + trialStrain = 0.; + return 0; } UniaxialMaterial * @@ -153,9 +157,14 @@ int ENTMaterial::sendSelf(int cTag, Channel &theChannel) { int res = 0; - static Vector data(2); + + static Vector data(5); data(0) = this->getTag(); data(1) = E; + data(2) = a; + data(3) = b; + data(4) = commitStrain; + res = theChannel.sendVector(this->getDbTag(), cTag, data); if (res < 0) opserr << "ENTMaterial::sendSelf() - failed to send data\n"; @@ -168,17 +177,24 @@ ENTMaterial::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker) { int res = 0; - static Vector data(2); + static Vector data(5); res = theChannel.recvVector(this->getDbTag(), cTag, data); if (res < 0) { opserr << "ENTMaterial::recvSelf() - failed to receive data\n"; - E = 0; - this->setTag(0); + E = 0; + a = 0; + b = 0; + commitStrain = 0; + this->setTag(0); } else { this->setTag((int)data(0)); E = data(1); + a = data(2); + b = data(3); + commitStrain = data(4); + trialStrain = commitStrain; } return res; diff --git a/SRC/material/uniaxial/ENTMaterial.h b/SRC/material/uniaxial/ENTMaterial.h index 0b9a22f08..81b14e5ed 100644 --- a/SRC/material/uniaxial/ENTMaterial.h +++ b/SRC/material/uniaxial/ENTMaterial.h @@ -84,6 +84,7 @@ class ENTMaterial : public UniaxialMaterial private: double E; + double commitStrain; double trialStrain; // AddingSensitivity:BEGIN ////////////////////////////////////////// diff --git a/SRC/material/uniaxial/HystereticMaterial.cpp b/SRC/material/uniaxial/HystereticMaterial.cpp index acbfa98fc..9e824609b 100644 --- a/SRC/material/uniaxial/HystereticMaterial.cpp +++ b/SRC/material/uniaxial/HystereticMaterial.cpp @@ -32,12 +32,15 @@ // degraded unloading stiffness based on maximum ductility. This // is a modified implementation of Hyster2.f90 by Filippou. #include -#include -#include #include #include + +#include #include +#include +#include +#include #include void * @@ -685,6 +688,110 @@ HystereticMaterial::Print(OPS_Stream &s, int flag) } } +int +HystereticMaterial::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (strcmp(argv[0],"mom1p") == 0 || strcmp(argv[0],"fy") == 0 || strcmp(argv[0],"Fy") == 0) { + param.setValue(mom1p); + return param.addObject(1, this); + } + if (strcmp(argv[0],"rot1p") == 0) { + param.setValue(rot1p); + return param.addObject(2, this); + } + if (strcmp(argv[0],"mom2p") == 0) { + param.setValue(mom2p); + return param.addObject(3, this); + } + if (strcmp(argv[0],"rot2p") == 0) { + param.setValue(rot2p); + return param.addObject(4, this); + } + if (strcmp(argv[0],"mom3p") == 0) { + param.setValue(mom3p); + return param.addObject(5, this); + } + if (strcmp(argv[0],"rot3p") == 0) { + param.setValue(rot3p); + return param.addObject(6, this); + } + if (strcmp(argv[0],"mom1n") == 0) { + param.setValue(mom1n); + return param.addObject(7, this); + } + if (strcmp(argv[0],"rot1n") == 0) { + param.setValue(rot1n); + return param.addObject(8, this); + } + if (strcmp(argv[0],"mom2n") == 0) { + param.setValue(mom2n); + return param.addObject(9, this); + } + if (strcmp(argv[0],"rot2n") == 0) { + param.setValue(rot2n); + return param.addObject(10, this); + } + if (strcmp(argv[0],"mom3n") == 0) { + param.setValue(mom3n); + return param.addObject(11, this); + } + if (strcmp(argv[0],"rot3n") == 0) { + param.setValue(rot3n); + return param.addObject(12, this); + } + + return -1; +} + +int +HystereticMaterial::updateParameter(int parameterID, Information &info) +{ + switch (parameterID) { + case -1: + return -1; + case 1: + this->mom1p = info.theDouble; + break; + case 2: + this->rot1p = info.theDouble; + break; + case 3: + this->mom2p = info.theDouble; + break; + case 4: + this->rot2p = info.theDouble; + break; + case 5: + this->mom3p = info.theDouble; + break; + case 6: + this->rot3p = info.theDouble; + break; + case 7: + this->mom1n = info.theDouble; + break; + case 8: + this->rot1n = info.theDouble; + break; + case 9: + this->mom2n = info.theDouble; + break; + case 10: + this->rot2n = info.theDouble; + break; + case 11: + this->mom3n = info.theDouble; + break; + case 12: + this->rot3n = info.theDouble; + break; + default: + return -1; + } + + return 0; +} + void HystereticMaterial::setEnvelope(void) { diff --git a/SRC/material/uniaxial/HystereticMaterial.h b/SRC/material/uniaxial/HystereticMaterial.h index 9c7387d3f..25964fe3c 100644 --- a/SRC/material/uniaxial/HystereticMaterial.h +++ b/SRC/material/uniaxial/HystereticMaterial.h @@ -76,6 +76,10 @@ class HystereticMaterial : 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); + //by SAJalali double getEnergy() { return CenergyD; } diff --git a/SRC/material/uniaxial/Makefile b/SRC/material/uniaxial/Makefile index 064edec37..56dbafb01 100644 --- a/SRC/material/uniaxial/Makefile +++ b/SRC/material/uniaxial/Makefile @@ -135,6 +135,13 @@ OBJS = UniaxialMaterial.o \ PlateBearingConnectionThermal.o \ DegradingPinchedBW.o \ HystereticPoly.o \ + SMAMaterial.o \ + Masonry.o \ + Masonryt.o \ + Trilinwpd.o \ + Trilinwp.o \ + Trilinwp2.o \ + SteelFractureDI.o \ TclModelBuilderUniaxialMaterialCommand.o all: $(OBJS) diff --git a/SRC/material/uniaxial/Masonry.cpp b/SRC/material/uniaxial/Masonry.cpp new file mode 100644 index 000000000..1678a8be9 --- /dev/null +++ b/SRC/material/uniaxial/Masonry.cpp @@ -0,0 +1,1292 @@ +// +// Written by: Gonzalo Torrisi, UNCuyo, Argentina, 2015 +// +// Description: This file contains the class implementation for Masonry Material, a material model based +// on Crisafulli's Stress-Strain Law originally developed to model cyclic axial behavior of masonry.Masonry +// constitutive law is defined in terms of Axial Force - Axial Displacement, considering varying Area for the +// diagonal strut according to the rate of the Axial deformation. It is thus suitable for elements where Force- +// Deformation relation is considered (e.g. zerolength element) +// +// Developed by: Francisco Crisafulli (1997) +// Written in C++ by: Stavroula Skafida (2013) +// Modified by : Gonzalo Torrisi, Universidad Nacional de Cuyo, 2014 + +#include +#include "Masonry.h" +#include +#include +#include +#include +#include +#include +#include +#include "classTags.h" +#include "elementAPI.h" + +/******************************************************************************* +* GETTING STARTED : Create a new Uniaxial Material class named "Masonry" +*******************************************************************************/ + +static int numMasonry = 0; + +void* OPS_Masonry() +{ + // print out some KUDO's + if (numMasonry == 0) { + opserr << "Masonry unaxial material - Written by Gonzalo Torrisi based on Crisafulli material model, Copyright 2015\n"; + numMasonry =1; + } + // Pointer to a uniaxial material that will be returned + UniaxialMaterial *theMaterial = 0; + // + // parse the input line for the material parameters + // + int iData[1]; + double dData[21]; + int numData; + numData = 1; + if (OPS_GetIntInput(&numData, iData) != 0) { + opserr << "WARNING invalid uniaxialMaterial Masonry tag" << endln; + return 0; + } + numData = 21; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING invalid Masonry Material Parameters\n"; + return 0; + } + // + // create a new material + // + theMaterial = new Masonry(iData[0], dData[0], 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], int(dData[20])); + + if (theMaterial == 0) { + opserr << "WARNING could not create uniaxialMaterial of type Masonry\n"; + return 0; + } + // return the material + return theMaterial; +} +/******************************************************************************* + * PART I: Set material Constructors & Deconstructor & Initialize variables + *******************************************************************************/ +Masonry::Masonry(int tag, double _Fm, double _Ft, + double _Um, double _Uult, double _Ucl, + double _Emo, double _Length, double _Area1, + double _Area2, double _D1, double _D2, + double _Ach, double _Are, double _Ba, + double _Bch, double _Gun, double _Gplu, + double _Gplr, double _Exp1, double _Exp2, + int _IENV): + UniaxialMaterial(tag, MAT_TAG_Masonry), Fm(_Fm), Ft(_Ft), + Um(_Um), Uult(_Uult), Ucl(_Ucl), + Emo(_Emo), Length(_Length), Area1(_Area1), + Area2(_Area2), D1(_D1), D2(_D2), + Ach(_Ach), Are(_Are), Ba(_Ba), + Bch(_Bch), Gun(_Gun), Gplu(_Gplu), + Gplr(_Gplr), Exp1(_Exp1), Exp2(_Exp2), + IENV(_IENV) +{ + // Initialize variables + double A1 = Emo*Um/Fm; + double A2 = 1 - A1*Um/Uult; + double Ko = Area1*Emo/Length; + double DeltaU, Kfactor; + DeltaU = 0.0; + Kfactor = 1; + + // Initialize history variables + K = Ko; + Et = Emo; + Uun = 0.0; + Sun = 0.0; + Eun = Gun*Emo; + Ure = 0.0; + Sre = 0.0; + Ere = Eun; + Uch = 0.0; + Sch = 0.0; + Ech = 0.0; + U1 = 0.0; + S1 = 0.0; + E1 = 0.0; + U2 = 0.0; + S2 = 0.0; + E2 = 0.0; + UunInt = 0.0; + UreInt = 0.0; + Upl = 0.0; + FtRed = Ft; + RuleNo = 3; + IVIR = 1; + InnerCycleNo = 1; + Area = Area1; + + cK = Ko; + cEt = Emo; + cUun = 0.0; + cSun = 0.0; + cEun = Gun*Emo; + cUre = 0.0; + cSre = 0.0; + cEre = Eun; + cUch = 0.0; + cSch = 0.0; + cEch = 0.0; + cU1 = 0.0; + cS1 = 0.0; + cE1 = 0.0; + cU2 = 0.0; + cS2 = 0.0; + cE2 = 0.0; + cUunInt = 0.0; + cUreInt = 0.0; + cUpl = 0.0; + cFtRed = Ft; + cRuleNo = 3; + cIVIR = 1; + cInnerCycleNo = 1; + cArea = Area1; + + this->revertToStart(); + this->revertToLastCommit(); +} + +Masonry::Masonry(void): +UniaxialMaterial(0, MAT_TAG_Masonry), Fm(0), Ft(0), Um(0), Uult(0), Ucl(0), Emo(0), Length(0), Area1(0), Area2(0), D1(0), +D2(0), Ach(0), Are(0), Ba(0), Bch(0), Gun(0), Gplu(0), Gplr(0), Exp1(0), Exp2(0), IENV(0) +{ + } +Masonry::~Masonry(void) +{ + // Does nothing +} +/**************************************************************************** + * PART II : Material State determination --> PROGRAM CORE * + ****************************************************************************/ +int +Masonry::setTrialStrain(double strain, double strainRate) +{ + double A1 = Emo*Um/Fm; + double A2 = 1 - A1*Um/Uult; + double Ko = Area1*Emo/Length; + double DeltaU, Kfactor; + + // retrieve history variables + Uun = cUun; + Sun = cSun; + Eun = cEun; + Ure = cUre; + Sre = cSre; + Ere = cEre; + Uch = cUch; + Sch = cSch; + Ech = cEch; + U1 = cU1; + S1 = cS1; + E1 = cE1; + U2 = cU2; + S2 = cS2; + E2 = cE2; + UunInt = cUunInt; + UreInt = cUreInt; + Upl = cUpl; + FtRed = cFtRed; + RuleNo = cRuleNo; + IVIR = cIVIR; + InnerCycleNo = cInnerCycleNo; + + // calculate current deformation etc + D = strain; + U = D/Length; + DeltaU = U - cU; + if (fabs(DeltaU) <= DBL_EPSILON) // ignore trivial strain change + { + S = cS; + Et = cEt; + } + else + { +// ------------------------------------------------------------------------- +// Find case & Calculate Stress - Tangent: +//-------------------------------------------------------------------------- +this-> Stress_Tangent(U, DeltaU, cU, cS, cEt, + Um, Fm, Emo, Ft, Uult, Ucl, Ach, Are, + Ba, Bch, Gun, Gplu, Gplr, Exp1, Exp2, + U1, S1, E1, U2, S2, E2, S, Et, + FtRed, Upl, UunInt, UreInt, Uun, Sun, + Eun, Ure, Sre, Ere, Uch, Sch, Ech, + RuleNo, InnerCycleNo, IVIR ); + } +// CALCULATE FORCE & STIFFNESS (according to the level of the axial deformation) +if ((Area1 == Area2) || (cArea == Area2)) +{ + Area = Area2; +} +else +{ + if (D > D1) + { + Area = Area1; + } + else if (D < D2) + { + Area = Area2; + } + else + { + Area = Area1-(Area1-Area2)*(D1-D)/(D1-D2); + } +} +cArea = Area; +Kfactor = Et*Area/Emo/Area1; // stiffness coefficient factor +K = Kfactor*Ko; // current stiffness +F = S*Area; // current force +return 0; + +} // end of Part II + +/**************************************************************************** + * PART III : Get Strain - Stress - Tangent + ****************************************************************************/ + double + Masonry::getStrain(void) + { + return D; + } + + double + Masonry::getStress(void) + { + return F; + } + + double + Masonry::getTangent(void) + { + return K; + } + + double +Masonry::getInitialTangent(void) +{ + //return Ko; + return Emo; +} +/****************************************************************************** + * PART IV : 1. Set up commitState(), revertToLastCommit() & revertToStart() + * 2. "getCopy" method -> to provide a clone of the material to a + * calling object (e.g. Element, Fiber, other Material) + ******************************************************************************/ + int + Masonry::commitState(void) + { + cD = D; + cF = F; + cK = K; + cU = U; + cS = S; + cEt = Et; + cUun = Uun; + cSun = Sun; + cEun = Eun; + cUre = Ure; + cSre = Sre; + cEre = Ere; + cUch = Uch; + cSch = Sch; + cEch = Ech; + cU1 = U1; + cS1 = S1; + cE1 = E1; + cU2 = U2; + cS2 = S2; + cE2 = E2; + cUunInt = UunInt; + cUreInt = UreInt; + cUpl = Upl; + cFtRed = FtRed; + cRuleNo = RuleNo; + cIVIR = IVIR; + cInnerCycleNo = InnerCycleNo; + cArea = Area; +return 0; + } + int + Masonry::revertToLastCommit(void) + { + D = cD; + F = cF; + K = cK; + U = cU; + S = cS; + Et = cEt; + Uun = cUun; + Sun = cSun; + Eun = cEun; + Ure = cUre; + Sre = cSre; + Ere = cEre; + Uch = cUch; + Sch = cSch; + Ech = cEch; + U1 = cU1; + S1 = cS1; + E1 = cE1; + U2 = cU2; + S2 = cS2; + E2 = cE2; + UunInt = cUunInt; + UreInt = cUreInt; + Upl = cUpl; + FtRed = cFtRed; + RuleNo = cRuleNo; + IVIR = cIVIR; + InnerCycleNo = cInnerCycleNo; + Area = cArea; +return 0; + } +int + Masonry::revertToStart(void) + { + cD = 0.0; + cF = 0.0; + cK = Ko; + cU = 0.0; + cS = 0.0; + cEt = Emo; + cUun = 0.0; + cSun = 0.0; + cEun = Gun*Emo; + cUre = 0.0; + cSre = 0.0; + cEre = Eun; + cUch = 0.0; + cSch = 0.0; + cEch = 0.0; + cU1 = 0.0; + S1 = 0.0; + cE1 = 0.0; + cU2 = 0.0; + cS2 = 0.0; + cE2 = 0.0; + cUunInt = 0.0; + cUreInt = 0.0; + cUpl = 0.0; + cFtRed = Ft; + cRuleNo = 3; + cIVIR = 1; + cInnerCycleNo = 1; + cArea = Area1; + + D = 0.0; + F = 0.0; + K = Ko; + U = 0.0; + S = 0.0; + Et = Emo; + Uun = 0.0; + Sun = 0.0; + Eun = Gun*Emo; + Ure = 0.0; + Sre = 0.0; + Ere = Eun; + Uch = 0.0; + Sch = 0.0; + Ech = 0.0; + U1 = 0.0; + S1 = 0.0; + E1 = 0.0; + U2 = 0.0; + S2 = 0.0; + E2 = 0.0; + UunInt = 0.0; + UreInt = 0.0; + Upl = 0.0; + FtRed = Ft; + RuleNo = 3; + IVIR = 1; + InnerCycleNo = 1; + Area = Area1; +return 0; + } +UniaxialMaterial* +Masonry::getCopy(void) +{ + Masonry *theCopy = new Masonry(this->getTag(), Fm, Ft, Um, Uult, Ucl, + Emo, Length, Area1, Area2, D1, D2, Ach, Are, + Ba, Bch, Gun, Gplu, Gplr, Exp1, Exp2, IENV); + + theCopy->cD = cD; + theCopy->cF = cF; + theCopy->cK = cK; + theCopy->cU = cU; + theCopy->cS = cS; + theCopy->cEt = cEt; + theCopy->cUun = cUun; + theCopy->cSun = cSun; + theCopy->cEun = cEun; + theCopy->cUre = cUre; + theCopy->cSre = cSre; + theCopy->cEre = cEre; + theCopy->cUch = cUch; + theCopy->cSch = cSch; + theCopy->cEch = cEch; + theCopy->cU1 = cU1; + theCopy->cS1 = cS1; + theCopy->cE1 = cE1; + theCopy->cU2 = cU2; + theCopy->cS2 = cS2; + theCopy->cE2 = cE2; + theCopy->cUunInt = cUunInt; + theCopy->cUreInt = cUreInt; + theCopy->cUpl = cUpl; + theCopy->cFtRed = cFtRed; + theCopy->cRuleNo = cRuleNo; + theCopy->cIVIR = cIVIR; + theCopy->cInnerCycleNo = cInnerCycleNo; + theCopy->cArea = cArea; + + return theCopy; +} +/**************************************************************************** + * PART IV : 1. "sendSelf()", "recvSelf()" methods for parallel processing + * & database program(std::min)g -> inherited from MovableObject + * 2. "Print()" method -> inherited by TaggedObject + ****************************************************************************/ + //1a. + int + Masonry::sendSelf(int commitTag, Channel &theChannel) + { + static Vector data(51); + data(0) = this->getTag(); + data(1) = Fm; + data(2) = Ft; + data(3) = Um; + data(4) = Uult; + data(5) = Ucl; + data(6) = Emo; + data(7) = Length; + data(8) = Area1; + data(9) = Area2; + data(10) = D1; + data(11) = D2; + data(12) = Ach; + data(13) = Are; + data(14) = Ba; + data(15) = Bch; + data(16) = Gun; + data(17) = Gplu; + data(18) = Gplr; + data(19) = Exp1; + data(20) = Exp2; + data(21) = IENV; + data(22) = cD; + data(23) = cF; + data(24) = cK; + data(25) = cU; + data(26) = cS; + data(27) = cEt; + data(28) = cUun; + data(29) = cSun; + data(30) = cEun; + data(31) = cUre; + data(32) = cSre; + data(33) = cEre; + data(34) = cUch; + data(35) = cSch; + data(36) = cEch; + data(37) = cU1; + data(38) = cS1; + data(39) = cE1; + data(40) = cU2; + data(41) = cS2; + data(42) = cE2; + data(43) = cUunInt; + data(44) = cUreInt; + data(45) = cUpl; + data(46) = cFtRed; + data(47) = cRuleNo; + data(48) = cIVIR; + data(49) = cInnerCycleNo; + data(50) = cArea; + + if (theChannel.sendVector(this->getDbTag(), commitTag, data)<0) + { + opserr << "Masonry::sendSelf() - failed to sendSelf\n"; + return -1; + } +return 0; + } + //1b. + int + Masonry::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) + { + static Vector data(51); + if (theChannel.recvVector(this->getDbTag(), commitTag, data)<0) + { + opserr << "Masonry::recvSelf() - failed to recvSelf\n"; + return -1; + } + + this->setTag(int(data(0))); + Fm = data(1); + Ft = data(2); + Um = data(3); + Uult = data(4); + Ucl = data(5); + Emo = data(6); + Length = data(7); + Area1 = data(8); + Area2 = data(9); + D1 = data(10); + D2 = data(11); + Ach = data(12); + Are = data(13); + Ba = data(14); + Bch = data(15); + Gun = data(16); + Gplu = data(17); + Gplr = data(18); + Exp1 = data(19); + Exp2 = data(20); + IENV = int(data(21)); + cD = data(22); + cF = data(23); + cK = data(24); + cU = data(25); + cS = data(26); + cEt = data(27); + cUun = data(28); + cSun = data(29); + cEun = data(30); + cUre = data(31); + cSre = data(32); + cEre = data(33); + cUch = data(34); + cSch = data(35); + cEch = data(36); + cU1 = data(37); + cS1 = data(38); + cE1 = data(39); + cU2 = data(40); + cS2 = data(41); + cE2 = data(42); + cUunInt = data(43); + cUreInt = data(44); + cUpl = data(45); + cFtRed = data(46); + cRuleNo = int(data(47)); + cIVIR = int(data(48)); + cInnerCycleNo = int(data(49)); + cArea = data(50); + + D = cD; + F = cF; + K = cK; + U = cU; + S = cS; + Et = cEt; +return 0; + } + //2. + void + Masonry::Print(OPS_Stream &s, int flag) + { + s << "Masonry:: tag: " << this->getTag() << endln; +// s << "Masonry::(deformation, force, tangent) " << D << " " << F << " " << K << endln; + s<< "Compressive stress f'm= "< +#include +#include +#include +#include +#include +#include +#include "classTags.h" +#include "elementAPI.h" + +/******************************************************************************* +* GETTING STARTED : Create a new Uniaxial Material class named "Masonry" +*******************************************************************************/ +#ifdef _USRDLL +#define OPS_Export extern "C" _declspec(dllexport) +#elif _MACOSX +#define OPS_Export extern "C" __attribute__((visibility("default"))) +#else +#define OPS_Export extern "C" +#endif + +static int numMasonry = 0; +OPS_Export void * +OPS_Masonry() +{ + // print out some KUDO's + if (numMasonry == 0) { + opserr << "Masonry unaxial material - Written by Gonzalo Torrisi based on Crisafulli material model, Copyright 2015\n"; + numMasonry =1; + } + // Pointer to a uniaxial material that will be returned + UniaxialMaterial *theMaterial = 0; + // + // parse the input line for the material parameters + // + int iData[1]; + double dData[21]; + int numData; + numData = 1; + if (OPS_GetIntInput(&numData, iData) != 0) { + opserr << "WARNING invalid uniaxialMaterial Masonry tag" << endln; + return 0; + } + numData = 21; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING invalid Masonry Material Parameters\n"; + return 0; + } + // + // create a new material + // + theMaterial = new Masonry(iData[0], dData[0], 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], int(dData[20])); + + if (theMaterial == 0) { + opserr << "WARNING could not create uniaxialMaterial of type Masonry\n"; + return 0; + } + // return the material + return theMaterial; +} +/******************************************************************************* +* PART I: Set material Constructors & Deconstructor & Initialize variables +*******************************************************************************/ +Masonry::Masonry(int tag, double _Fm, double _Ft, + double _Um, double _Uult, double _Ucl, + double _Emo, double _Length, double _Area1, + double _Area2, double _D1, double _D2, + double _Ach, double _Are, double _Ba, + double _Bch, double _Gun, double _Gplu, + double _Gplr, double _Exp1, double _Exp2, + int _IENV) : + UniaxialMaterial(tag, 0), Fm(_Fm), Ft(_Ft), + Um(_Um), Uult(_Uult), Ucl(_Ucl), + Emo(_Emo), Length(_Length), Area1(_Area1), + Area2(_Area2), D1(_D1), D2(_D2), + Ach(_Ach), Are(_Are), Ba(_Ba), + Bch(_Bch), Gun(_Gun), Gplu(_Gplu), + Gplr(_Gplr), Exp1(_Exp1), Exp2(_Exp2), + IENV(_IENV) +{ + // Initialize variables + double A1 = Emo*Um / Fm; + double A2 = 1 - A1*Um / Uult; + //double Ko = Area1*Emo/Length; + double Ko = Area1*Emo; + double DeltaU, Kfactor; + DeltaU = 0.0; + Kfactor = 1; + // opserr << " Area1 "<revertToStart(); + this->revertToLastCommit(); +} + +Masonry::Masonry(void) : + UniaxialMaterial(0, 0), Fm(0), Ft(0), Um(0), Uult(0), Ucl(0), Emo(0), Length(0), Area1(0), Area2(0), D1(0), + D2(0), Ach(0), Are(0), Ba(0), Bch(0), Gun(0), Gplu(0), Gplr(0), Exp1(0), Exp2(0), IENV(0) +{ +} +Masonry::~Masonry(void) +{ + // Does nothing +} +/**************************************************************************** +* PART II : Material State determination --> PROGRAM CORE * +****************************************************************************/ +int +Masonry::setTrialStrain(double strain, double strainRate) +{ + double A1 = Emo*Um / Fm; + double A2 = 1 - A1*Um / Uult; + //double Ko = Area1*Emo/Length; + double Ko = Area1*Emo; + double DeltaU, Kfactor; + + // retrieve history variables + Uun = cUun; + Sun = cSun; + Eun = cEun; + Ure = cUre; + Sre = cSre; + Ere = cEre; + Uch = cUch; + Sch = cSch; + Ech = cEch; + U1 = cU1; + S1 = cS1; + E1 = cE1; + U2 = cU2; + S2 = cS2; + E2 = cE2; + UunInt = cUunInt; + UreInt = cUreInt; + Upl = cUpl; + FtRed = cFtRed; + RuleNo = cRuleNo; + IVIR = cIVIR; + InnerCycleNo = cInnerCycleNo; + double Uma = Ft / Emo; + + // calculate current deformation etc + D = strain; + //U = D/Length; + U = D; + DeltaU = U - cU; + if (fabs(DeltaU) <= DBL_EPSILON) // ignore trivial strain change + { + S = cS; + Et = cEt; + } + else + { + // ------------------------------------------------------------------------- + // Find case & Calculate Stress - Tangent: + //-------------------------------------------------------------------------- + this->Stress_Tangent(U, DeltaU, cU, cS, cEt, + Um, Fm, Emo, Ft, Uult, Ucl, Ach, Are, + Ba, Bch, Gun, Gplu, Gplr, Exp1, Exp2, + U1, S1, E1, U2, S2, E2, S, Et, + FtRed, Upl, UunInt, UreInt, Uun, Sun, + Eun, Ure, Sre, Ere, Uch, Sch, Ech, + RuleNo, InnerCycleNo, IVIR, UMAXIMA, INDIC, Uma); + } + // CALCULATE FORCE & STIFFNESS (according to the level of the axial deformation) + if ((Area1 == Area2) || (cArea == Area2)) + { + Area = Area2; + } + else + { + if (D > D1) + { + Area = Area1; + } + else if (D < D2) + { + Area = Area2; + } + else + { + Area = Area1 - (Area1 - Area2)*(D1 - D) / (D1 - D2); + } + } + cArea = Area; + Kfactor = Et*Area / Emo / Area1; // stiffness coefficient factor + K = Kfactor*Ko; // current stiffness + F = S*Area; // current force + return 0; + +} // end of Part II + + /**************************************************************************** + * PART III : Get Strain - Stress - Tangent + ****************************************************************************/ +double +Masonry::getStrain(void) +{ + return D; +} + +double +Masonry::getStress(void) +{ + return F; +} + +double +Masonry::getTangent(void) +{ + return K; +} + +double +Masonry::getInitialTangent(void) +{ + //return Ko; + return Emo; +} +/****************************************************************************** +* PART IV : 1. Set up commitState(), revertToLastCommit() & revertToStart() +* 2. "getCopy" method -> to provide a clone of the material to a +* calling object (e.g. Element, Fiber, other Material) +******************************************************************************/ +int +Masonry::commitState(void) +{ + cD = D; + cF = F; + cK = K; + cU = U; + cS = S; + cEt = Et; + cUun = Uun; + cSun = Sun; + cEun = Eun; + cUre = Ure; + cSre = Sre; + cEre = Ere; + cUch = Uch; + cSch = Sch; + cEch = Ech; + cU1 = U1; + cS1 = S1; + cE1 = E1; + cU2 = U2; + cS2 = S2; + cE2 = E2; + cUunInt = UunInt; + cUreInt = UreInt; + cUpl = Upl; + cFtRed = FtRed; + cRuleNo = RuleNo; + cIVIR = IVIR; + cInnerCycleNo = InnerCycleNo; + cArea = Area; + cINDIC = INDIC; + cUMAXIMA = UMAXIMA; + return 0; +} +int +Masonry::revertToLastCommit(void) +{ + D = cD; + F = cF; + K = cK; + U = cU; + S = cS; + Et = cEt; + Uun = cUun; + Sun = cSun; + Eun = cEun; + Ure = cUre; + Sre = cSre; + Ere = cEre; + Uch = cUch; + Sch = cSch; + Ech = cEch; + U1 = cU1; + S1 = cS1; + E1 = cE1; + U2 = cU2; + S2 = cS2; + E2 = cE2; + UunInt = cUunInt; + UreInt = cUreInt; + Upl = cUpl; + FtRed = cFtRed; + RuleNo = cRuleNo; + IVIR = cIVIR; + InnerCycleNo = cInnerCycleNo; + Area = cArea; + UMAXIMA = cUMAXIMA; + INDIC = cINDIC; + + return 0; +} +int +Masonry::revertToStart(void) +{ + cD = 0.0; + cF = 0.0; + cK = Ko; + cU = 0.0; + cS = 0.0; + cEt = Emo; + cUun = 0.0; + cSun = 0.0; + cEun = Gun*Emo; + cUre = 0.0; + cSre = 0.0; + cEre = Eun; + cUch = 0.0; + cSch = 0.0; + cEch = 0.0; + cU1 = 0.0; + S1 = 0.0; + cE1 = 0.0; + cU2 = 0.0; + cS2 = 0.0; + cE2 = 0.0; + cUunInt = 0.0; + cUreInt = 0.0; + cUpl = 0.0; + cFtRed = Ft; + cRuleNo = 3; + cIVIR = 1; + cInnerCycleNo = 1; + cArea = Area1; + cINDIC = 0; + cUMAXIMA = 0; + + + D = 0.0; + F = 0.0; + K = Ko; + U = 0.0; + S = 0.0; + Et = Emo; + Uun = 0.0; + Sun = 0.0; + Eun = Gun*Emo; + Ure = 0.0; + Sre = 0.0; + Ere = Eun; + Uch = 0.0; + Sch = 0.0; + Ech = 0.0; + U1 = 0.0; + S1 = 0.0; + E1 = 0.0; + U2 = 0.0; + S2 = 0.0; + E2 = 0.0; + UunInt = 0.0; + UreInt = 0.0; + Upl = 0.0; + FtRed = Ft; + RuleNo = 3; + IVIR = 1; + InnerCycleNo = 1; + Area = Area1; + Uma = Ft / Emo; + UMAXIMA = 0.0; + return 0; +} +UniaxialMaterial* +Masonry::getCopy(void) +{ + Masonry *theCopy = new Masonry(this->getTag(), Fm, Ft, Um, Uult, Ucl, + Emo, Length, Area1, Area2, D1, D2, Ach, Are, + Ba, Bch, Gun, Gplu, Gplr, Exp1, Exp2, IENV); + + theCopy->cD = cD; + theCopy->cF = cF; + theCopy->cK = cK; + theCopy->cU = cU; + theCopy->cS = cS; + theCopy->cEt = cEt; + theCopy->cUun = cUun; + theCopy->cSun = cSun; + theCopy->cEun = cEun; + theCopy->cUre = cUre; + theCopy->cSre = cSre; + theCopy->cEre = cEre; + theCopy->cUch = cUch; + theCopy->cSch = cSch; + theCopy->cEch = cEch; + theCopy->cU1 = cU1; + theCopy->cS1 = cS1; + theCopy->cE1 = cE1; + theCopy->cU2 = cU2; + theCopy->cS2 = cS2; + theCopy->cE2 = cE2; + theCopy->cUunInt = cUunInt; + theCopy->cUreInt = cUreInt; + theCopy->cUpl = cUpl; + theCopy->cFtRed = cFtRed; + theCopy->cRuleNo = cRuleNo; + theCopy->cIVIR = cIVIR; + theCopy->cInnerCycleNo = cInnerCycleNo; + theCopy->cArea = cArea; + theCopy->cUMAXIMA = cUMAXIMA; + theCopy->cINDIC = cINDIC; + + return theCopy; +} +/**************************************************************************** +* PART IV : 1. "sendSelf()", "recvSelf()" methods for parallel processing +* & database program(std::min)g -> inherited from MovableObject +* 2. "Print()" method -> inherited by TaggedObject +****************************************************************************/ +//1a. +int +Masonry::sendSelf(int commitTag, Channel &theChannel) +{ + static Vector data(53); + data(0) = this->getTag(); + data(1) = Fm; + data(2) = Ft; + data(3) = Um; + data(4) = Uult; + data(5) = Ucl; + data(6) = Emo; + data(7) = Length; + data(8) = Area1; + data(9) = Area2; + data(10) = D1; + data(11) = D2; + data(12) = Ach; + data(13) = Are; + data(14) = Ba; + data(15) = Bch; + data(16) = Gun; + data(17) = Gplu; + data(18) = Gplr; + data(19) = Exp1; + data(20) = Exp2; + data(21) = IENV; + data(22) = cD; + data(23) = cF; + data(24) = cK; + data(25) = cU; + data(26) = cS; + data(27) = cEt; + data(28) = cUun; + data(29) = cSun; + data(30) = cEun; + data(31) = cUre; + data(32) = cSre; + data(33) = cEre; + data(34) = cUch; + data(35) = cSch; + data(36) = cEch; + data(37) = cU1; + data(38) = cS1; + data(39) = cE1; + data(40) = cU2; + data(41) = cS2; + data(42) = cE2; + data(43) = cUunInt; + data(44) = cUreInt; + data(45) = cUpl; + data(46) = cFtRed; + data(47) = cRuleNo; + data(48) = cIVIR; + data(49) = cInnerCycleNo; + data(50) = cArea; + data(51) = cUMAXIMA; + data(52) = cINDIC; + + + if (theChannel.sendVector(this->getDbTag(), commitTag, data)<0) + { + opserr << "Masonry::sendSelf() - failed to sendSelf\n"; + return -1; + } + return 0; +} +//1b. +int +Masonry::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + static Vector data(53); + if (theChannel.recvVector(this->getDbTag(), commitTag, data)<0) + { + opserr << "Masonry::recvSelf() - failed to recvSelf\n"; + return -1; + } + + this->setTag(int(data(0))); + Fm = data(1); + Ft = data(2); + Um = data(3); + Uult = data(4); + Ucl = data(5); + Emo = data(6); + Length = data(7); + Area1 = data(8); + Area2 = data(9); + D1 = data(10); + D2 = data(11); + Ach = data(12); + Are = data(13); + Ba = data(14); + Bch = data(15); + Gun = data(16); + Gplu = data(17); + Gplr = data(18); + Exp1 = data(19); + Exp2 = data(20); + IENV = int(data(21)); + cD = data(22); + cF = data(23); + cK = data(24); + cU = data(25); + cS = data(26); + cEt = data(27); + cUun = data(28); + cSun = data(29); + cEun = data(30); + cUre = data(31); + cSre = data(32); + cEre = data(33); + cUch = data(34); + cSch = data(35); + cEch = data(36); + cU1 = data(37); + cS1 = data(38); + cE1 = data(39); + cU2 = data(40); + cS2 = data(41); + cE2 = data(42); + cUunInt = data(43); + cUreInt = data(44); + cUpl = data(45); + cFtRed = data(46); + cRuleNo = int(data(47)); + cIVIR = int(data(48)); + cInnerCycleNo = int(data(49)); + cArea = data(50); + cUMAXIMA = data(51); + cINDIC = int(data(52)); + + D = cD; + F = cF; + K = cK; + U = cU; + S = cS; + Et = cEt; + return 0; +} +//2. +void +Masonry::Print(OPS_Stream &s, int flag) +{ + s << "Masonry:: tag: " << this->getTag() << endln; + // s << "Masonry::(deformation, force, tangent) " << D << " " << F << " " << K << endln; + s << "Compressive stress f'm= " << Fm << endln; + s << "Tensile stress ft = " << Ft << endln; + s << "Def. at max. Stress eo = " << Um << endln; + s << "Ultimate deform. eu = " << Uult << endln; + s << "Closing deform. ecl= " << Ucl << endln; + s << "Elasticity modulus Emo = " << Emo << endln; + s << "% of Area A2 = " << Area2 / Area1 << endln; + s << "Initial def. Area e1 = " << D1 << endln; + s << "Final def. Area e2 = " << D2 << endln; + s << "Ach = " << Ach << endln; + s << "Are = " << Are << endln; + s << "Ba = " << Ba << endln; + s << "Bch = " << Bch << endln; + s << "Gun = " << Gun << endln; + s << "Gplu = " << Gplu << endln; + s << "Gplr = " << Gplr << endln; + s << "Exp1 = " << Exp1 << endln; + s << "Exp2 = " << Exp2 << endln; + s << "Ienv = " << IENV << endln; +} + +/*************************************************************************** +* PART VI : Define functions used in the main core of the program +* 1. Comp_Envlp : Calculates Stress-Tangent on the +* Compressive envelope, Sargin's equation +* 2. Unload_Reload : Calculates Stress-Tangent using the +* Proposed equations (7.7) & (7.8) +* 3. Plastic_Strain : Calculates Plastic Strain & Reduced +* tensile strength from eq.(7.19) & (7.35) +* 4. Stess_Tangent : Calculates stress & tangent modulus at the +* current step +****************************************************************************/ +//1. +void +Masonry::Comp_Envlp(double Uenv, double Um, double Fm, double Emo, double Uult, int IENV, double + &Senv, double &Eenv) +{ + // Calculate Parameters A1, A2 + + double A1 = Emo*Um / Fm; + double A2 = 1 - A1*Um / Uult; + + if ((Uenv > Um && IENV == 1) || (Uenv > Uult && IENV == 2)) + { + // from Sargin's equations (7.1a) - (7.2a) + + double XX = Uenv / Um; + Senv = Fm*(A1*XX + (A2 - 1)*pow(XX, 2)) / (1 + (A1 - 2)*XX + A2*pow(XX, 2)); + + double EtNom = (Fm / Um) * (A1 + 2 * (A2 - 1)*XX + (2 - A1 - 2 * A2)*pow(XX, 2)); + double EtDen = pow(1 + (A1 - 2)*XX + A2*pow(XX, 2), 2); + + Eenv = (std::max)(EtNom / EtDen, 0.0); + } + else if (IENV == 1) + { + // Parabola for the descending branch (Eq. 7.1b & 7.2b) + + Senv = (std::min)(Fm*(1 - pow((Uenv - Um) / (Uult - Um), 2)), 0.0); + Eenv = -2 * Fm*(Uenv - Um) / pow((Uult - Um), 2); + } + else + { + Senv = 0.0; + Eenv = 0.0; + } + return; +} //End of (1) Comp_Envlp + //-------------------------------------------------------------------------------------------------------------------------- + //2. +void +Masonry::Unload_Reload(double U, double U1, double U2, double S1, double S2, double E1, double E2, + double &S, double &Et) +{ + double Esec = (S2 - S1) / (U2 - U1); + double B1 = E1 / Esec; + double B3 = 2 - E2 / Esec*(1 + B1); // Parameters from eq.(7.9) + double B2 = B1 - B3; + double XX = (U - U1) / (U2 - U1); // Relative strain + + S = S1 + (S2 - S1)*(B1*XX + pow(XX, 2)) / (1 + B2*XX + B3*pow(XX, 2)); + Et = Esec*((B1 + 2 * XX)*(1 + B2*XX + B3*pow(XX, 2)) - (B1*XX + pow(XX, 2))*(B2 + 2 * B3*XX)) / pow(1 + + B2*XX + B3*pow(XX, 2), 2); + return; +} //End of (2) Unload_Reload + //------------------------------------------------------------------------------------------------------------------------------------------ + //3. +void +Masonry::Plastic_Strain(double Uun, double Sun, double Um, double Fm, double Emo, double Ft, double + Ba, double &Upl, double &FtRed) +{ + //GST: se llama AXSS25 + Upl = Uun - (Uun - Ba*fabs(Fm) / Emo)*Sun / (Sun - Ba*fabs(Fm)); + + if (Upl > Um && Upl <= 0.0 && FtRed != 0) + { + FtRed = (std::max)(Ft*(1 - Upl / Um), 0.0); + } + else + { + FtRed = 0.0; + } + return; +} //End of (3) Plastic_Strain +void +Masonry::TRACCION(double Um, double &Upl, double Ft, double Emo, double &Et, double &S, double Uma, double U, double Ucl, double &UMAXIMA, int &INDIC) +{ + + double UDEN = Upl; + double UUTTT = 20 * Ft / Emo; + double FE = 5.0; + double UMAXT = Ft / Emo; + UUTTT2 = (std::max)(Ucl, FE*UMAXT); + + + if (UMAXIMA < UMAXT) + { + UMAXIMA = UMAXT; + } + + UMAXIMAT = UMAXIMA; + if ((UUTTT2 - UMAXT) == 0.0) + { + UUTTT2 = 0.95*UUTTT2; + } + + double FM2 = Ft*(UUTTT2 - UMAXIMAT) / (UUTTT2 - UMAXT); + + if (U > 0.0 && U < UMAXT && INDIC == 0) + { + Et = Emo; + S = Et*U; + INDIC = 1; + } + else if (U > 0.0 && U < UUTTT2 && U >= UMAXT) + { + double FMT3 = Ft; + if (UMAXIMAT > UMAXT) + { + FMT3 = FM2; + } + if (UMAXIMAT == UDEN) + { + UMAXIMAT = 1.05*UMAXIMAT; + } + Et = FM2 / (UMAXIMAT - UDEN); + + double UU3 = UDEN; + if (fabs(UDEN) > fabs(Um)) + { + double UU3 = Um; + } + Et = FM2 / (UMAXIMAT - UU3); + + S = Et*(U - UU3); + double aku = 800 * (U - UMAXT); + double ST2 = Ft / (1 + sqrt(aku)); + FMT3 = ST2; + + if (S > FMT3) + { + S = FMT3; + } + INDIC = 1; + UMAXIMA = U; + if (UMAXIMAT > UMAXIMA) + { + UMAXIMA = UMAXIMAT; + } + } + else if (U > 0.0 && U > UUTTT2) + { + S = 1.0e-20; + Et = 1.0e-20; + } + else if (U<0.0 && U >Um) + { + UMAXT = Ft / Emo; + UDEN = Upl; + if (fabs(UDEN) > fabs(Um)) + { + UDEN = Um; + } + double EMAX = FM2 / (UMAXIMAT - UDEN); + S = EMAX*(U - UDEN); + Et = EMAX; + INDIC = 1; + + } + else if (U < 0.0 && U <= Um) + { + S = 1.0e-20; + Et = 1.0e-20; + } + else if (U > 0.0 && U < UMAXT && INDIC == 1) + { + UDEN = Upl; + double EMAX = FM2 / (UMAXIMAT - UDEN); + S = EMAX*(U - UDEN); + Et = EMAX; + INDIC = 1; + } + else + { + S = 1.0e-20; + Et = 1.0e-20; + } + + + return; +} + + + + + + + + + + +//------------------------------------------------------------------------------------------------------------------------------------------ +//4. +void +Masonry::Stress_Tangent(double U, double DeltaU, double cU, double cS, double cEt, + double Um, double Fm, double Emo, double Ft, double Uult, double Ucl, double Ach, double Are, + double Ba, double Bch, double Gun, double Gplu, double Gplr, double Exp1, double Exp2, + double &U1, double &S1, double &E1, double &U2, double &S2, double &E2, double &S, double &Et, + double &FtRed, double &Upl, double &UunInt, double &UreInt, double &Uun, double &Sun, + double &Eun, double &Ure, double &Sre, double &Ere, double &Uch, double &Sch, double &Ech, + int &RuleNo, int &InnerCycleNo, int &IVIR, double &UMAXIMA, int &INDIC, double Uma) +{ + double Ub, Esec, Eplu, Eplr, Ecl, Senv, Eenv; + + // ----------------------------------------------------------------------------------------------------------------------------------------- + // Find case & Calculate Stress - Tangent: + //----------------------------------------------------------------------------------------------------------------------------------------- + // RULE 1 : Skeleton/Envelope curve in compression (Sargin's equations) + //----------------------------------------------------------------------------------------------------------------------------------------- + if (RuleNo == 1) + { + if (DeltaU < 0.0) // loading in compression + { + //.................................................................................................................... + // CASE 1-3: ultimate strain has been reached => go to zero stress state + //.................................................................................................................... + if (U <= Uult) + { + RuleNo = 3; + // Upl = 1000*Um; + Upl = U; + // S = 1.0e-20; + // Et = 1.0e-20; + return; + } + //.......................................................................... + // CASE 1-1: travels along the envelope curve + //.......................................................................... + else if (U > Uult) + { + this->Comp_Envlp(U, Um, Fm, Emo, Uult, IENV, Senv, Eenv); + S = Senv; + Et = Eenv; + return; + } + } + //............................................................................. + // CASE 1-2: unloading from Rule 1 using Rule 2 + //............................................................................. + else if (DeltaU >= 0.0) + { + RuleNo = 2; + InnerCycleNo = 1; + Uun = cU; + UunInt = Uun; + Sun = cS; + Eun = Gun*Emo; + Ure = Uun; + // Calculate plastic strain & reduced tensile strength + this->Plastic_Strain(Uun, Sun, Um, Fm, Emo, Ft, Ba, Upl, FtRed); + // Calculate the parameters needed to implement Rule 2 + U1 = cU; + S1 = cS; + E1 = Eun; // when unloading from Rule 1, E1=Eun=Gun*Emo; + U2 = (std::max)(U1 - 1.5*S1 / E1, Upl); + S2 = 0.0; + Esec = (S2 - S1) / (U2 - U1); + Eplu = Gplu*Emo / pow((1.0 + Uun / Um), Exp1); // Eq.(7.21) + E2 = (std::min)(Eplu, 0.5*Esec); + // Calculate Stress & Tangent modulus using proposed equations (7.7) & (7.8) + this->Unload_Reload(U, U1, U2, S1, S2, E1, E2, S, Et); + return; + } + }// end of RuleNo==1 + //------------------------------------------------------------------------------------------------------------------------------------------ + // RULE 2 : Unloading from rule 1, 4 or 5 + //------------------------------------------------------------------------------------------------------------------------------------------ + else if (RuleNo == 2) + { + if (U >= U2) // unloading enters tensile-stress state or zero stress state + { + //.............................................................................. + // CASE 2-6: unloading from Rule 2 using Rule 6 + //.............................................................................. + if (FtRed > 0.0) + { + // RuleNo = 6; //GST: R=3 + // U1 = Upl; + //GST: call traccion tengo yo + // Et = Emo*FtRed/Ft; + // S = Et*(U-U1); + // if (S >=FtRed) + // { + // S = FtRed; + // FtRed = 0; + //} + RuleNo = 3; + Upl = U; + this->TRACCION(Um, Upl, Ft, Emo, Et, S, Uma, U, Ucl, UMAXIMA, INDIC); + return; + } + //............................................................................. + // CASE 2-3: unloading from Rule 2 using Rule 3 + //............................................................................. + else if (FtRed == 0.0) + { + RuleNo = 3; + Upl = U; + this->TRACCION(Um, Upl, Ft, Emo, Et, S, Uma, U, Ucl, UMAXIMA, INDIC); + // S = 1.0e-20; + // Et = 1.0e-20; + return; + } + } + else if (U < U2) + { + //...................................................................................... + // CASE 2-2: Typical unloading - travelling along Rule 2 + //...................................................................................... + if (DeltaU > 0.0) + { + // Calculate Stress & Tangent modulus using proposed equations (7.7) & (7.8) + this->Unload_Reload(U, U1, U2, S1, S2, E1, E2, S, Et); + return; + } + // + // Cases for RELOADING from RULE 2 before reaching apl (inner cycle) + // + else if (DeltaU <= 0.0) + { + // Calculate new Reloading point: + + if (UunInt < Upl) + { + UreInt = (std::min)(cU, Upl); // strain at the inner loop at which reloading occurs + Ure = Ure + Are*(UunInt - UreInt) / pow(InnerCycleNo, Exp2); // From Eq.(7.32) + InnerCycleNo = InnerCycleNo + 1; + } + // Reloading point at the envelope curve => Calculate stress-tangent: + this->Comp_Envlp(Ure, Um, Fm, Emo, Uult, IENV, Senv, Eenv); + Sre = Senv; + Ere = Eenv; + + // Calculate new Change point: + Ub = Upl + Ach*(Uun - Sun / Eun - Upl); // From Eq.(7.24) + Ech = Sun / (Uun - Ub); // From Eq.(7.25) + Sch = Bch*Sre / pow(InnerCycleNo, 0.4); // From Eq.(7.33) + Sch = (std::min)(Sch, 0.5*Sre); // limit Eq.(7.34) + Uch = Ub + Sch / Ech; // From Eq.(7.23) + + //................................................................................................................................. + // CASE 2-3: Reloading from Rule 2 to zero-stress after Uult has been reached + //................................................................................................................................. + if (Sre == 0.0) + { + //S = 1.0e-20; + //Et = 1.0e-20; + RuleNo = 3; + //Upl = 1000*Um; + Upl = U; + return; + } + else + { + //............................................................................. + // CASE 2-4: Reloading from Rule 2 using Rule 4 + //............................................................................. + if (cS >= 0.9*Sch && cU >= 0.9*Uch) // Case (A) for reloading from Rule 2, page205 + { + RuleNo = 4; + U1 = Uch; + S1 = Sch; + E1 = Ech; + S2 = cS; + U2 = cU; + E2 = (std::min)(1.2*cEt, 0.9*(S2 - S1) / (U2 - U1)); + } + //............................................................................. + // CASE 2-5: Reloading from Rule 2 using Rule 5 + //............................................................................. + else // Case (B) for reloading from Rule 2, page205 + { + RuleNo = 5; + U1 = cU; + S1 = cS; + U2 = Ure; + S2 = Sre; + E1 = (std::min)((std::max)(2.0*cEt, 1.2*(S2 - S1) / (U2 - U1)), Gun*Emo); + E2 = Ere; + if (E2 <= 0) + { + E2 = 0.5*(S2 - S1) / (U2 - U1); + } + } + // Calculate stress-tangent for reloading cases : + this->Unload_Reload(U, U1, U2, S1, S2, E1, E2, S, Et); + return; + } + } + } + } // end of RuleNo==2 + //----------------------------------------------------------------------------------------------------------------------------- ------------ + // RULE 3 : Zero stress state + //----------------------------------------------------------------------------------------------------------------------------------------- + else if (RuleNo == 3) + { + if (DeltaU >= 0.0) // unloading from zero stress in tension + { + //....................................................................................... + // CASE 3-6: Unloading - Passing from Rule 3 to Rule 6 + //....................................................................................... + // if (FtRed > 0.0) + // { + this->TRACCION(Um, Upl, Ft, Emo, Et, S, Uma, U, Ucl, UMAXIMA, INDIC); + // GST: call traccion + // RuleNo = 6; + // U1 = 0.0; + // Et = Emo; + // Et = Et*FtRed/Ft; + // S = Et*(U-U1); + + // if (S >= FtRed) + // { + // S = FtRed; + // FtRed = 0.0; + // RuleNo = 3; + // } + return; + } + //....................................................................................... + // CASE 3-3un: Unloading - travelling along Rule 3 + //....................................................................................... + // else //if (FtRed == 0.0) + // { + // S = 1.0e-20; + // Et = 1.0e-20; + //return; + // } + //} + else if (DeltaU < 0.0) // reloading from zero stress in compression + { + if ((U <= Upl) || (U <= Ucl)) + { + if (IVIR == 1) + { + //.................................................................................................... + // CASE 3-1: Reloading from Rule 3 to Rule 1 (for the 1st time) + //.................................................................................................... + if (U <= 0) + { + RuleNo = 1; + IVIR = 0; + this->Comp_Envlp(U, Um, Fm, Emo, Uult, IENV, Senv, Eenv); + S = Senv; + Et = Eenv; + return; + } + //................................................................................................................................ + // CASE 3-4i: Reloading from Rule 3 using Rule 4 (when Sargin's not used yet) + //................................................................................................................................ + else if (U > 0) // goes to compression Aa<0 without previous compressive-cycle (IVIR=1) + { // => Rule 4 with special considerations (see page 210 Crisafulli phD) + RuleNo = 4; + U1 = -Ft / Emo; + // Calculate stress & tangent for strain U1 at the Envelope curve + this->Comp_Envlp(U1, Um, Fm, Emo, Uult, IENV, Senv, Eenv); + S1 = Senv; + E1 = Eenv; + + // Define point 2 (see page 210 Crisafulli phD) + U2 = U; + S2 = 0.0; + E2 = 0.01*Emo; + + // Calculate stress-strain at current step according to the proposed equations (7.7) & (7.8) + Esec = (S2 - S1) / (U2 - U1); + this->Unload_Reload(U, U1, U2, S1, S2, E1, E2, S, Et); + return; + } + } + else //if (IVIR == 0) + { + // Calculate New Reloading point: + + if (UunInt < Upl) + { + UreInt = (std::min)(cU, Upl); + Ure = Ure + Are*(UunInt - UreInt) / pow(InnerCycleNo, Exp2); // From Eq.(7.32) + InnerCycleNo = InnerCycleNo + 1; + } + this->Comp_Envlp(Ure, Um, Fm, Emo, Uult, IENV, Senv, Eenv); + Sre = Senv; + Ere = Eenv; + + // Calculate New Change point: + Ub = Upl + Ach*(Uun - Sun / Eun - Upl); // From Eq.(7.24) + Ech = Sun / (Uun - Ub); // From Eq.(7.25) + Sch = Bch*Sre / pow(InnerCycleNo, 0.4); // From Eq.(7.33) + Sch = (std::min)(Sch, 0.5*Sre); // limit Eq.(7.34) + Uch = Ub + Sch / Ech; // From Eq.(7.23) + //........................................................................................................................................ + // CASE 3-4ii: Reloading from Rule 3 using Rule 4 (when Sargin's already used before) + //........................................................................................................................................ + if (Sre < 0.0) + { + RuleNo = 4; + + // Calculate parameters for reloading from Rule 3 + U1 = Uch; + S1 = Sch; + E1 = Ech; + S2 = (std::min)(cS, 0.0); + U2 = cU; + Eplu = Gun*Emo / pow(1 + Uun / Um, Exp1); // Eq.(7.21)- Tangent modulus corresponding to the plastic strain of the unloading curve + Eplr = Gplr*Eplu; // Eq.(7.26)- Reloading modulus from Rule 3 + Esec = (S2 - S1) / (U2 - U1); + + if (Upl > Ucl) + { + E2 = Eplr; + } + else + { + Ecl = 0.15*Eplr; // & now consider cases of Eq.(7.39) + if (Ucl >= U2 && U2>0.0) + { + E2 = Ecl; + } + else + { + E2 = Ecl + fabs(U2 / Upl)*(Eplr - Ecl); + } + } + double E2i = (std::min)(0.2*E1, 0.9*Esec); + E2 = (std::min)(E2i, E2); // Limiting conditions in order to obtain a smooth transition curve + + // Calculate stress-strain at current step according to proposed equations (7.7) & (7.8) + this->Unload_Reload(U, U1, U2, S1, S2, E1, E2, S, Et); + return; + } + //.................................................................................... + // CASE 3-3re: Reloading from Rule 3 using Rule 3 + //.................................................................................... + else + { + RuleNo = 3; // continues in compression under zero-stress + // Upl = 1000*Um; + // S = 1.0e-20; + // Et = 1.0e-20; + Upl = U; + this->TRACCION(Um, Upl, Ft, Emo, Et, S, Uma, U, Ucl, UMAXIMA, INDIC); + return; + } + } + } + //.................................................................................... + // CASE 3-3zs: From Rule 3 to zero-stress condition + //.................................................................................... + else //if (U > Ucl || U > Upl) // zero stress condition + { + // S = 1.0e-20; + // Et = 1.0e-20; + this->TRACCION(Um, Upl, Ft, Emo, Et, S, Uma, U, Ucl, UMAXIMA, INDIC); + return; + } + } + } //end of RuleNo==3 + //----------------------------------------------------------------------------------------------------------------------------- -------------- + // RULE 4 : First part of the reloading curve + //----------------------------------------------------------------------------------------------------------------------------- -------------- + else if (RuleNo == 4) + { + if (DeltaU < 0.0) // Reloading in compression + { + if (U <= U1) + { + //.................................................................................... + // CASE 4-5: Reloading from Rule 4 using Rule 5 + //.................................................................................... + if (IVIR == 0) + { + RuleNo = 5; + U2 = Ure; + S2 = Sre; + E2 = Ere; + if (E2 <= 0) + { + E2 = 0.5*(S2 - S1) / (E2 - E1); + } + // Calculate stress-strain at current step according to proposed equations (7.7) & (7.8) + this->Unload_Reload(U, U1, U2, S1, S2, E1, E2, S, Et); + return; + } + //................................................................................................................... + // CASE 4-1: Reloading from Rule 4 using Rule 1 (1st time Sargin is used) + //.................................................................................................................. + else if (IVIR == 1) // enters Rule(1) for the 1st time + { + RuleNo = 1; + IVIR = 0; + this->Comp_Envlp(U, Um, Fm, Emo, Uult, IENV, Senv, Eenv); + S = Senv; + Et = Eenv; + return; + } + } + //.................................................................................... + // CASE 4-4: Travelling along Rule 4 + //.................................................................................... + else if (U > U1) // travels along Rule (4) + { + this->Unload_Reload(U, U1, U2, S1, S2, E1, E2, S, Et); + return; + } + } + //............................................................................ + // CASE 4-2: Unloading from Rule 4 using Rule 2 + //............................................................................ + else if (DeltaU >= 0.0) // Unloading from Rule (4) using Rule (2) + { + RuleNo = 2; + UunInt = cU; + E1 = (std::min)(2 * cEt, Gun*Emo); + + // Calculate parameters in order to implement Rule 2 + U1 = cU; + S1 = cS; + U2 = (std::max)(U1 - 1.5*S1 / E1, Upl); + S2 = 0.0; + Upl = U2; + Esec = (S2 - S1) / (U2 - U1); + Eplu = Gplu*Emo / pow(1.0 + Uun / Um, Exp1); // Eq.(7.21) + E2 = (std::min)(Eplu, 0.5*Esec); + + // Calculate stress-tangent at the current step according to proposed equations (7.7) & (7.8) + this->Unload_Reload(U, U1, U2, S1, S2, E1, E2, S, Et); + return; + } + } // end of RuleNo==4 + //----------------------------------------------------------------------------------------------------------------------------- ----------- + // RULE 5 : Second part of the reloading curve + //----------------------------------------------------------------------------------------------------------------------------- ----------- + else if (RuleNo == 5) + { + //.......................................................................................................... + // CASE 5-1: Reloading from Rule 5 to the envelope curve (Rule 1) + //.......................................................................................................... + if (U <= Ure) + { + RuleNo = 1; + this->Comp_Envlp(U, Um, Fm, Emo, Uult, IENV, Senv, Eenv); + S = Senv; + Et = Eenv; + return; + } + else if (U > Ure) + { + //............................................................................ + // CASE 5-2: Unloading from Rule 5 using Rule 2 + //............................................................................ + if (DeltaU > 0.0) // Unloading from Rule (5) using Rule (2) + { + RuleNo = 2; + UunInt = cU; + if (Uun > UunInt) + { + Uun = cU; + Ure = Uun; + Sun = cS; + InnerCycleNo = 1; + + // Calculate new plastic strain & reduced tensile strength + this->Plastic_Strain(Uun, Sun, Um, Fm, Emo, Ft, Ba, Upl, FtRed); + } + + Eun = Gun*Emo; + E1 = Eun; + + // Define points 1 & 2 for Rule 2 + U1 = cU; + S1 = cS; + U2 = (std::max)(U1 - 1.5*S1 / E1, Upl); + S2 = 0.0; + Esec = (S2 - S1) / (U2 - U1); + Eplu = Gplu*Emo / pow(1.0 + Uun / Um, Exp1); // Eq.(7.21) + E2 = (std::min)(Eplu, 0.5*Esec); + } + //.......................................................................... + // CASE 5-5: Unloading travelling along Rule 5 + //.......................................................................... + //elseif DeltaU < 0.0, travels along Rule (5) with points 1,2 as already defined, end + + // Calculate stress-tangent at the current step according to proposed equations (7.7) & (7.8) + this->Unload_Reload(U, U1, U2, S1, S2, E1, E2, S, Et); + return; + } + } // end of RuleNo==5 + //------------------------------------------------------------------------------------------------------------------------------------------ + // RULE 6 : Tensile behavior (elastic) + //-------------------------------------------------------------------------------------------------------------- ---------------------------- + else if (RuleNo == 6) + { + // Et = Emo*FtRed/Ft; + // S = Et*(U-U1); + //.......................................................................... + // CASE 6-3: Reloading from Rule 6 to Rule 3 + //.......................................................................... + // if (S >= FtRed) + // { + // RuleNo = 3; + // S = FtRed; + // FtRed = 0; + this->TRACCION(Um, Upl, Ft, Emo, Et, S, Uma, U, Ucl, UMAXIMA, INDIC); + return; + } + if (S > 0.0) + { + RuleNo = 3; + } + //.......................................................................... + // CASE 6-1: Reloading from Rule 6 to Rule 1 + //.......................................................................... + else if (S < 0.0 && IVIR == 1 && U <= 0.0) + { + RuleNo = 1; + IVIR = 0; + this->Comp_Envlp(U, Um, Fm, Emo, Uult, IENV, Senv, Eenv); + S = Senv; + Et = Eenv; + return; + } + else if (S < 0.0) + { + // Define new reloading point + + if (UunInt < Upl) + { + UreInt = (std::min)(cU, Upl); // strain at the inner loop at which reloading occurs + Ure = Ure + Are*(UunInt - UreInt) / pow(InnerCycleNo, Exp2); // From Eq.(7.32) + InnerCycleNo = InnerCycleNo + 1; + } + // Calculate reloading strain & tangent + + this->Comp_Envlp(Ure, Um, Fm, Emo, Uult, IENV, Senv, Eenv); + Sre = Senv; + Ere = Eenv; + + // Define new Change point + + Ub = Upl + Ach*(Uun - Sun / Eun - Upl); // From Eq.(7.24) + Ech = Sun / (Uun - Ub); // From Eq.(7.25) + Sch = Bch*Sre / pow(InnerCycleNo, 0.4); // From Eq.(7.33) + Sch = (std::min)(Sch, 0.5*Sre); // limit Eq.(7.34) + Uch = Ub + Sch / Ech; // From Eq.(7.23) + //.......................................................................... + // CASE 6-4: Reloading from Rule 6 using Rule 4 + //.......................................................................... + if (Sre < 0.0) + { + RuleNo = 4; + // Define points 1 & 2 (SS27) + U1 = Uch; + S1 = Sch; + E1 = Ech; + S2 = (std::min)(cS, 0.0); + U2 = cU; + Eplu = Gun*Emo / pow(1 + Uun / Um, Exp1); // Eq.(7.21) + Eplr = Gplr*Eplu; // Eq.(7.26) + Esec = (S2 - S1) / (U2 - U1); + + if (Upl > Ucl) + { + E2 = Eplr; + } + else + { + Ecl = 0.15*Eplr; // & now consider cases of Eq.(7.39) + if (Ucl >= U2 && U2>0.0) + { + E2 = Ecl; + } + else { + E2 = Ecl + fabs(U2 / Upl)*(Eplr - Ecl); + } + } + double E2i = (std::min)(0.2*E1, 0.9*Esec); + E2 = (std::min)(E2i, E2); // Limiting conditions in order to obtain a smooth transition curve + + // Calculate stress-tangent at the current step according to proposed equations (7.7) & (7.8) + + Esec = (S2 - S1) / (U2 - U1); + this->Unload_Reload(U, U1, U2, S1, S2, E1, E2, S, Et); + return; + } + //.......................................................................... + // CASE 6-3: Reloading from Rule 6 using Rule 3 + //.......................................................................... + else //if (Sre >= 0.0) // accumulates strains under zero-stress + { + RuleNo = 3; + // Upl = 1000*Um; + // S = 1.0e-20; + // Et = 1.0e-20; + Upl = U; + this->TRACCION(Um, Upl, Ft, Emo, Et, S, Uma, U, Ucl, UMAXIMA, INDIC); + return; + } + return; + } +} // end of RuleNo==6 + diff --git a/SRC/material/uniaxial/Masonry2.h b/SRC/material/uniaxial/Masonry2.h new file mode 100644 index 000000000..cff40c22f --- /dev/null +++ b/SRC/material/uniaxial/Masonry2.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.2 $ +// $Date: 2007-06-28 21:46:43 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/Masonry.h,v $ + +// Written: Gonzalo Torrisi, UNCuyo +// Created: 10/2014 +// +// Description: This file contains the class defination for Uniaxial material Masonry +// + +#ifndef Masonry_h +#define Masonry_h + +#include + + +class Masonry : public UniaxialMaterial +{ + public: + Masonry (int tag, double _Fm, double _Ft, + double _Um, double _Uult, double _Ucl, + double _Emo, double _Length, double _Area1, + double _Area2, double _D1, double _D2, + double _Ach, double _Are, double _Ba, + double _Bch, double _Gun, double _Gplu, + double _Gplr, double _Exp1, double _Exp2, + int _IENV); + Masonry (); + ~Masonry(); + + int setTrialStrain(double strain, double strainRate = 0.0); +// int setTrial (double strain, double &stress, double &tangent, double strainRate = 0.0); + double getStrain(void); + double getStress(void); + double getTangent(void); + double getInitialTangent(void) ; + + 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 Properties ***/ + double Fm; + double Ft; + double Um; + double Uult; + double Ucl; + double Emo; + double Length; + double Area1; + double Area2; + double D1; + double D2; + double Ach; + double Are; + double Ba; + double Bch; + double Gun; + double Gplu; + double Gplr; + double Exp1; + double Exp2; + int IENV ; + + double A1; + double A2; + double Ko; + double DeltaU, Kfactor; + + double K; +double Ec; + double Et; + double Uun; + double Sun; + double Eun ; + double Ure ; + double Sre ; + double Ere ; + double Uch ; + double Sch ; + double Ech ; + double U1 ; + double S1 ; + double E1 ; + double U2 ; + double S2 ; + double E2 ; + double UunInt; + double UreInt ; + double Upl ; + double FtRed ; + int RuleNo ; + int IVIR ; + int InnerCycleNo ; + double Area ; + double D; + double U; + double F; + double S; + double UMAXIMA; + int INDIC; + double Uma; + double UMAXIMAT; + double UUTTT2; + + double cD ; + double cF ; + double cK ; + double cU ; + double cS ; + double cEt ; + double cUun ; + double cSun ; + double cEun ; + double cUre ; + double cSre ; + double cEre ; + double cUch ; + double cSch ; + double cEch ; + double cU1 ; + double cS1 ; + double cE1 ; + double cU2 ; + double cS2 ; + double cE2 ; + double cUunInt ; + double cUreInt ; + double cUpl ; + double cFtRed ; + int cRuleNo ; + int cIVIR ; + int cInnerCycleNo ; + double cArea ; + double cUMAXIMA; + int cINDIC; + + + + void Comp_Envlp (double Uenv, double Um, double Fm, double Emo, double Uult, int IENV, double +&Senv, double &Eenv ) ; + +void Unload_Reload( double U, double U1, double U2, double S1, double S2, double E1, double E2, +double &S, double &Et ) ; + +void Plastic_Strain( double Uun, double Sun, double Um, double Fm, double Emo, double Ft, double +Ba, double &Upl, double &FtRed ) ; + +void Stress_Tangent(double U, double DeltaU, double cU, double cS, double cEt, + double Um, double Fm, double Emo, double Ft, double Uult, double Ucl, double Ach, double Are, + double Ba, double Bch, double Gun, double Gplu, double Gplr, double Exp1, double Exp2, + double &U1, double &S1, double &E1, double &U2, double &S2, double &E2,double &S, double &Et, + double &FtRed, double &Upl, double &UunInt, double &UreInt, double &Uun, double &Sun, + double &Eun, double &Ure, double &Sre, double &Ere, double &Uch, double &Sch, double &Ech, + int &RuleNo, int &InnerCycleNo, int &IVIR, double &UMAXIMA, int &INDIC, double Uma); + +void TRACCION(double Um, double &Upl, double Ft, double Emo, double &Et, double &S, double Uma, double U, double Ucl, double &UMAXIMA, int &INDIC); + +}; + +#endif diff --git a/SRC/material/uniaxial/Masonryt.cpp b/SRC/material/uniaxial/Masonryt.cpp new file mode 100644 index 000000000..e780fde69 --- /dev/null +++ b/SRC/material/uniaxial/Masonryt.cpp @@ -0,0 +1,1442 @@ +// +// Written by: Gonzalo Torrisi, UNCuyo, Argentina, 2015 +// +// Description: This file contains the class implementation for Masonryt Material, a material model based +// on Crisafulli's Stress-Strain Law originally developed to model cyclic axial behavior of Masonryt.Masonryt +// constitutive law is defined in terms of Axial Force - Axial Displacement, considering varying Area for the +// diagonal strut according to the rate of the Axial deformation. It is thus suitable for elements where Force- +// Deformation relation is considered (e.g. zerolength element) + +#include +#include "Masonryt.h" +#include +#include +#include +#include +#include +#include +#include +#include "classTags.h" +#include "elementAPI.h" + +/******************************************************************************* +* GETTING STARTED : Create a new Uniaxial Material class named "Masonryt" +*******************************************************************************/ +void* OPS_Masonryt() +{ + + // Pointer to a uniaxial material that will be returned + //UniaxialMaterial *theMaterial = 0; + // + // parse the input line for the material parameters + // + int iData[1]; + double dData[21]; + int numData; + numData = 1; + if (OPS_GetIntInput(&numData, iData) != 0) { + opserr << "WARNING invalid uniaxialMaterial Masonryt tag" << endln; + return 0; + } + numData = 21; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING invalid Masonryt Material Parameters\n"; + return 0; + } + // + // create a new material + // + UniaxialMaterial* mat = new Masonryt(iData[0], dData[0], 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], int(dData[20])); + + if (mat == 0) { + opserr << "WARNING could not create uniaxialMaterial of type Masonryt\n"; + return 0; + } + // return the material + return mat; +} +/******************************************************************************* + * PART I: Set material Constructors & Deconstructor & Initialize variables + *******************************************************************************/ +Masonryt::Masonryt(int tag, double _Fm, double _Ft, + double _Um, double _Uult, double _Ucl, + double _Emo, double _Length, double _Area1, + double _Area2, double _D1, double _D2, + double _Ach, double _Are, double _Ba, + double _Bch, double _Gun, double _Gplu, + double _Gplr, double _Exp1, double _Exp2, + int _IENV): + UniaxialMaterial(tag, MAT_TAG_Masonryt), Fm(_Fm), Ft(_Ft), + Um(_Um), Uult(_Uult), Ucl(_Ucl), + Emo(_Emo), Length(_Length), Area1(_Area1), + Area2(_Area2), D1(_D1), D2(_D2), + Ach(_Ach), Are(_Are), Ba(_Ba), + Bch(_Bch), Gun(_Gun), Gplu(_Gplu), + Gplr(_Gplr), Exp1(_Exp1), Exp2(_Exp2), + IENV(_IENV) +{ + // Initialize variables + double A1 = Emo*Um/Fm; + double A2 = 1 - A1*Um/Uult; + //double Ko = Area1*Emo/Length; + double Ko = Area1*Emo; + double DeltaU, Kfactor; + DeltaU = 0.0; + Kfactor = 1; +// opserr << " Area1 "<revertToStart(); + this->revertToLastCommit(); +} + +Masonryt::Masonryt(void): +UniaxialMaterial(0, MAT_TAG_Masonryt), Fm(0), Ft(0), Um(0), Uult(0), Ucl(0), Emo(0), Length(0), Area1(0), Area2(0), D1(0), +D2(0), Ach(0), Are(0), Ba(0), Bch(0), Gun(0), Gplu(0), Gplr(0), Exp1(0), Exp2(0), IENV(0) +{ + } +Masonryt::~Masonryt(void) +{ + // Does nothing +} +/**************************************************************************** + * PART II : Material State determination --> PROGRAM CORE * + ****************************************************************************/ +int +Masonryt::setTrialStrain(double strain, double strainRate) +{ + double A1 = Emo*Um/Fm; + double A2 = 1 - A1*Um/Uult; + //double Ko = Area1*Emo/Length; + double Ko = Area1*Emo; + double DeltaU, Kfactor; + + // retrieve history variables + Uun = cUun; + Sun = cSun; + Eun = cEun; + Ure = cUre; + Sre = cSre; + Ere = cEre; + Uch = cUch; + Sch = cSch; + Ech = cEch; + U1 = cU1; + S1 = cS1; + E1 = cE1; + U2 = cU2; + S2 = cS2; + E2 = cE2; + UunInt = cUunInt; + UreInt = cUreInt; + Upl = cUpl; + FtRed = cFtRed; + RuleNo = cRuleNo; + IVIR = cIVIR; + InnerCycleNo = cInnerCycleNo; + double Uma = Ft / Emo; + + // calculate current deformation etc + D = strain; + //U = D/Length; + U = D; + DeltaU = U - cU; + if (fabs(DeltaU) <= DBL_EPSILON) // ignore trivial strain change + { + S = cS; + Et = cEt; + } + else + { +// ------------------------------------------------------------------------- +// Find case & Calculate Stress - Tangent: +//-------------------------------------------------------------------------- +this-> Stress_Tangent(U, DeltaU, cU, cS, cEt, + Um, Fm, Emo, Ft, Uult, Ucl, Ach, Are, + Ba, Bch, Gun, Gplu, Gplr, Exp1, Exp2, + U1, S1, E1, U2, S2, E2, S, Et, + FtRed, Upl, UunInt, UreInt, Uun, Sun, + Eun, Ure, Sre, Ere, Uch, Sch, Ech, + RuleNo, InnerCycleNo, IVIR ,UMAXIMA, INDIC, Uma); + } +// CALCULATE FORCE & STIFFNESS (according to the level of the axial deformation) +if ((Area1 == Area2) || (cArea == Area2)) +{ + Area = Area2; +} +else +{ + if (D > D1) + { + Area = Area1; + } + else if (D < D2) + { + Area = Area2; + } + else + { + Area = Area1-(Area1-Area2)*(D1-D)/(D1-D2); + } +} +cArea = Area; +Kfactor = Et*Area/Emo/Area1; // stiffness coefficient factor +K = Kfactor*Ko; // current stiffness +F = S*Area; // current force +return 0; + +} // end of Part II + +/**************************************************************************** + * PART III : Get Strain - Stress - Tangent + ****************************************************************************/ + double + Masonryt::getStrain(void) + { + return D; + } + + double + Masonryt::getStress(void) + { + return F; + } + + double + Masonryt::getTangent(void) + { + return K; + } + + double +Masonryt::getInitialTangent(void) +{ + //return Ko; + return Emo; +} +/****************************************************************************** + * PART IV : 1. Set up commitState(), revertToLastCommit() & revertToStart() + * 2. "getCopy" method -> to provide a clone of the material to a + * calling object (e.g. Element, Fiber, other Material) + ******************************************************************************/ + int + Masonryt::commitState(void) + { + cD = D; + cF = F; + cK = K; + cU = U; + cS = S; + cEt = Et; + cUun = Uun; + cSun = Sun; + cEun = Eun; + cUre = Ure; + cSre = Sre; + cEre = Ere; + cUch = Uch; + cSch = Sch; + cEch = Ech; + cU1 = U1; + cS1 = S1; + cE1 = E1; + cU2 = U2; + cS2 = S2; + cE2 = E2; + cUunInt = UunInt; + cUreInt = UreInt; + cUpl = Upl; + cFtRed = FtRed; + cRuleNo = RuleNo; + cIVIR = IVIR; + cInnerCycleNo = InnerCycleNo; + cArea = Area; + cINDIC = INDIC; + cUMAXIMA = UMAXIMA; +return 0; + } + int + Masonryt::revertToLastCommit(void) + { + D = cD; + F = cF; + K = cK; + U = cU; + S = cS; + Et = cEt; + Uun = cUun; + Sun = cSun; + Eun = cEun; + Ure = cUre; + Sre = cSre; + Ere = cEre; + Uch = cUch; + Sch = cSch; + Ech = cEch; + U1 = cU1; + S1 = cS1; + E1 = cE1; + U2 = cU2; + S2 = cS2; + E2 = cE2; + UunInt = cUunInt; + UreInt = cUreInt; + Upl = cUpl; + FtRed = cFtRed; + RuleNo = cRuleNo; + IVIR = cIVIR; + InnerCycleNo = cInnerCycleNo; + Area = cArea; + UMAXIMA = cUMAXIMA; + INDIC = cINDIC; + +return 0; + } +int + Masonryt::revertToStart(void) + { + cD = 0.0; + cF = 0.0; + cK = Ko; + cU = 0.0; + cS = 0.0; + cEt = Emo; + cUun = 0.0; + cSun = 0.0; + cEun = Gun*Emo; + cUre = 0.0; + cSre = 0.0; + cEre = Eun; + cUch = 0.0; + cSch = 0.0; + cEch = 0.0; + cU1 = 0.0; + S1 = 0.0; + cE1 = 0.0; + cU2 = 0.0; + cS2 = 0.0; + cE2 = 0.0; + cUunInt = 0.0; + cUreInt = 0.0; + cUpl = 0.0; + cFtRed = Ft; + cRuleNo = 3; + cIVIR = 1; + cInnerCycleNo = 1; + cArea = Area1; + cINDIC = 0; + cUMAXIMA = 0; + + + D = 0.0; + F = 0.0; + K = Ko; + U = 0.0; + S = 0.0; + Et = Emo; + Uun = 0.0; + Sun = 0.0; + Eun = Gun*Emo; + Ure = 0.0; + Sre = 0.0; + Ere = Eun; + Uch = 0.0; + Sch = 0.0; + Ech = 0.0; + U1 = 0.0; + S1 = 0.0; + E1 = 0.0; + U2 = 0.0; + S2 = 0.0; + E2 = 0.0; + UunInt = 0.0; + UreInt = 0.0; + Upl = 0.0; + FtRed = Ft; + RuleNo = 3; + IVIR = 1; + InnerCycleNo = 1; + Area = Area1; + Uma = Ft / Emo; + UMAXIMA = 0.0; +return 0; + } +UniaxialMaterial* +Masonryt::getCopy(void) +{ + Masonryt *theCopy = new Masonryt(this->getTag(), Fm, Ft, Um, Uult, Ucl, + Emo, Length, Area1, Area2, D1, D2, Ach, Are, + Ba, Bch, Gun, Gplu, Gplr, Exp1, Exp2, IENV); + + theCopy->cD = cD; + theCopy->cF = cF; + theCopy->cK = cK; + theCopy->cU = cU; + theCopy->cS = cS; + theCopy->cEt = cEt; + theCopy->cUun = cUun; + theCopy->cSun = cSun; + theCopy->cEun = cEun; + theCopy->cUre = cUre; + theCopy->cSre = cSre; + theCopy->cEre = cEre; + theCopy->cUch = cUch; + theCopy->cSch = cSch; + theCopy->cEch = cEch; + theCopy->cU1 = cU1; + theCopy->cS1 = cS1; + theCopy->cE1 = cE1; + theCopy->cU2 = cU2; + theCopy->cS2 = cS2; + theCopy->cE2 = cE2; + theCopy->cUunInt = cUunInt; + theCopy->cUreInt = cUreInt; + theCopy->cUpl = cUpl; + theCopy->cFtRed = cFtRed; + theCopy->cRuleNo = cRuleNo; + theCopy->cIVIR = cIVIR; + theCopy->cInnerCycleNo = cInnerCycleNo; + theCopy->cArea = cArea; + theCopy->cUMAXIMA = cUMAXIMA; + theCopy->cINDIC = cINDIC; + + return theCopy; +} +/**************************************************************************** + * PART IV : 1. "sendSelf()", "recvSelf()" methods for parallel processing + * & database program(std::min)g -> inherited from MovableObject + * 2. "Print()" method -> inherited by TaggedObject + ****************************************************************************/ + //1a. + int + Masonryt::sendSelf(int commitTag, Channel &theChannel) + { + static Vector data(53); + data(0) = this->getTag(); + data(1) = Fm; + data(2) = Ft; + data(3) = Um; + data(4) = Uult; + data(5) = Ucl; + data(6) = Emo; + data(7) = Length; + data(8) = Area1; + data(9) = Area2; + data(10) = D1; + data(11) = D2; + data(12) = Ach; + data(13) = Are; + data(14) = Ba; + data(15) = Bch; + data(16) = Gun; + data(17) = Gplu; + data(18) = Gplr; + data(19) = Exp1; + data(20) = Exp2; + data(21) = IENV; + data(22) = cD; + data(23) = cF; + data(24) = cK; + data(25) = cU; + data(26) = cS; + data(27) = cEt; + data(28) = cUun; + data(29) = cSun; + data(30) = cEun; + data(31) = cUre; + data(32) = cSre; + data(33) = cEre; + data(34) = cUch; + data(35) = cSch; + data(36) = cEch; + data(37) = cU1; + data(38) = cS1; + data(39) = cE1; + data(40) = cU2; + data(41) = cS2; + data(42) = cE2; + data(43) = cUunInt; + data(44) = cUreInt; + data(45) = cUpl; + data(46) = cFtRed; + data(47) = cRuleNo; + data(48) = cIVIR; + data(49) = cInnerCycleNo; + data(50) = cArea; + data(51) = cUMAXIMA; + data(52) = cINDIC; + + + if (theChannel.sendVector(this->getDbTag(), commitTag, data)<0) + { + opserr << "Masonryt::sendSelf() - failed to sendSelf\n"; + return -1; + } +return 0; + } + //1b. + int + Masonryt::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) + { + static Vector data(53); + if (theChannel.recvVector(this->getDbTag(), commitTag, data)<0) + { + opserr << "Masonryt::recvSelf() - failed to recvSelf\n"; + return -1; + } + + this->setTag(int(data(0))); + Fm = data(1); + Ft = data(2); + Um = data(3); + Uult = data(4); + Ucl = data(5); + Emo = data(6); + Length = data(7); + Area1 = data(8); + Area2 = data(9); + D1 = data(10); + D2 = data(11); + Ach = data(12); + Are = data(13); + Ba = data(14); + Bch = data(15); + Gun = data(16); + Gplu = data(17); + Gplr = data(18); + Exp1 = data(19); + Exp2 = data(20); + IENV = int(data(21)); + cD = data(22); + cF = data(23); + cK = data(24); + cU = data(25); + cS = data(26); + cEt = data(27); + cUun = data(28); + cSun = data(29); + cEun = data(30); + cUre = data(31); + cSre = data(32); + cEre = data(33); + cUch = data(34); + cSch = data(35); + cEch = data(36); + cU1 = data(37); + cS1 = data(38); + cE1 = data(39); + cU2 = data(40); + cS2 = data(41); + cE2 = data(42); + cUunInt = data(43); + cUreInt = data(44); + cUpl = data(45); + cFtRed = data(46); + cRuleNo = int(data(47)); + cIVIR = int(data(48)); + cInnerCycleNo = int(data(49)); + cArea = data(50); + cUMAXIMA = data(51); + cINDIC = int(data(52)); + + D = cD; + F = cF; + K = cK; + U = cU; + S = cS; + Et = cEt; +return 0; + } + //2. + void + Masonryt::Print(OPS_Stream &s, int flag) + { + s << "Masonryt:: tag: " << this->getTag() << endln; +// s << "Masonryt::(deformation, force, tangent) " << D << " " << F << " " << K << endln; + s<< "Compressive stress f'm= "< #include +#include // Controls on internal iteration between spring components const int PYmaxIterations = 20; const double PYtolerance = 1.0e-12; +void* OPS_PySimple2() +{ + int numdata = OPS_GetNumRemainingInputArgs(); + if (numdata < 5) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: uniaxialMaterial PySimple2 tag? soilType? pult? y50? drag? dashpot?\n"; + return 0; + } + + int idata[2]; + numdata = 2; + if (OPS_GetIntInput(&numdata, idata) < 0) { + opserr << "WARNING invalid int inputs\n"; + return 0; + } + + double ddata[4] = {0,0,0,0}; + numdata = OPS_GetNumRemainingInputArgs(); + if (numdata > 4) numdata = 4; + if (OPS_GetDoubleInput(&numdata, ddata) < 0) { + opserr << "WARNING invalid double inputs\n"; + return 0; + } + + UniaxialMaterial *theMaterial = 0; + theMaterial = new PySimple2(idata[0], MAT_TAG_PySimple1, idata[1], ddata[0], ddata[1], + ddata[2], ddata[3]); + + return theMaterial; +} + + ///////////////////////////////////////////////////////////////////// // Constructor with data diff --git a/SRC/material/uniaxial/PY/QzLiq1.cpp b/SRC/material/uniaxial/PY/QzLiq1.cpp new file mode 100644 index 000000000..1a3f3fe57 --- /dev/null +++ b/SRC/material/uniaxial/PY/QzLiq1.cpp @@ -0,0 +1,762 @@ + +/*** ********************************************************************* +** Module: QzLiq1.cpp +** +** Purpose: Q-z material that incorporates liquefaction effects. It gets +** the pore pressure from a specified element that contains a +** PorousFluidSolid or from provided mean effective stress as a +** timeseries data. +** +** Developed by Sumeet Kumar Sinha +** (C) Copyright 2020, All Rights Reserved. +** +** ****************************************************************** */ + + +// $Revision: 1.0 +// $Date: 2020/6/12 +// $Source: /OpenSees/SRC/material/uniaxial/QzLiq1.cpp +// Written: Sumeet Kumar Sinha +// Created: June 2020 +// Revision: A +// +// Description: This file contains the class implementation for QzLiq1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Control on internal iteration between spring components +const int QZmaxIterations = 20; +const double QZtolerance = 1.0e-12; + +int QzLiq1::loadStage = 0; +Vector QzLiq1::stressV3(3); +int QzConstructorType = 0; + +void* OPS_QzLiq1() +{ + UniaxialMaterial* theMat = 0; + + int numdata = OPS_GetNumRemainingInputArgs(); + if (numdata < 8) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: uniaxialMaterial QzLiq1 tag? qzType? qult? z50? suction? dashpot? alpha? solidElem1? solidElem2?\n"; + opserr << "or: uniaxialMaterial QzLiq1 tag? qzType? qult? z50? suction? dashpot? alpha? -timeSeries seriesTag?\n"; + return 0; + } + + int idata[2]; + numdata = 2; + if (OPS_GetIntInput(&numdata, idata) < 0) { + opserr << "WARNING invalid int inputs\n"; + return 0; + } + + double ddata[5]; + numdata = 5; + if (OPS_GetDoubleInput(&numdata, ddata) < 0) { + opserr << "WARNING invalid double inputs\n"; + return 0; + } + + const char* arg = OPS_GetString(); + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return 0; + + if (strcmp(arg, "-timeSeries") == 0) { + int tsTag; + numdata = 1; + if (OPS_GetIntInput(&numdata, &tsTag) < 0) { + opserr << "WARNING invalid time series tag\n"; + return 0; + } + TimeSeries* theSeries = OPS_getTimeSeries(tsTag); + theMat = new QzLiq1(idata[0], idata[1], ddata[0], ddata[1], ddata[2], ddata[3], ddata[4], + theDomain,theSeries); + + + } else { + + // back one arg + OPS_ResetCurrentInputArg(-1); + + int eleTags[2]; + numdata = 2; + if (OPS_GetIntInput(&numdata, eleTags) < 0) { + opserr << "WARNING invalid element tags\n"; + return 0; + } + + theMat = new QzLiq1(idata[0], idata[1], ddata[0], ddata[1], ddata[2], ddata[3], ddata[4], + eleTags[0],eleTags[1],theDomain); + } + + return theMat; +} + +///////////////////////////////////////////////////////////////////// +// Constructor with data + +QzLiq1::QzLiq1(int tag, int qz_type, double q_ult, double z_50, double suction, + double dash_pot, double alpha, int solid_elem1, int solid_elem2, Domain *the_Domain) +:QzSimple1(tag, qz_type, q_ult, z_50, suction, dash_pot), alpha(alpha), +solidElem1(solid_elem1), solidElem2(solid_elem2), theDomain(the_Domain) +{ + // Initialize QzSimple variables and history variables + // + this->revertToStart(); + initialTangent = Tangent; + QzConstructorType = 1; +} +QzLiq1::QzLiq1(int tag, int qz_type, double q_ult, double z_50, double suction, + double dash_pot, double alpha, Domain *the_Domain, TimeSeries *the_Series) +:QzSimple1(tag, qz_type, q_ult, z_50, suction, dash_pot),alpha(alpha), +theDomain(the_Domain), theSeries(the_Series) +{ + // Initialize QzSimple variables and history variables + // + this->revertToStart(); + initialTangent = Tangent; + QzConstructorType = 2; +} +///////////////////////////////////////////////////////////////////// +// Default constructor + +QzLiq1::QzLiq1() +:QzSimple1(), solidElem1(0), solidElem2(0), theDomain(0) +{ +} +///////////////////////////////////////////////////////////////////// +// Default destructor +QzLiq1::~QzLiq1() +{ + // Call QzSimple1 destructor even though it does nothing. + // + // QzSimple1::~QzSimple1(); +} + +///////////////////////////////////////////////////////////////////// +int +QzLiq1::setTrialStrain (double newz, double zRate) +{ + // Call the base class QzSimple1 to take care of the basic q-z behavior. + // + QzSimple1::setTrialStrain(newz, zRate); + Tz = newz; + + // Reset mean consolidation stress if loadStage switched from 0 to 1 + // Note: currently assuming y-axis is vertical, and that the + // out-of-plane normal stress equals sigma-xx. + // + if(lastLoadStage ==0 && loadStage ==1){ + + if(QzConstructorType==2) + meanConsolStress = getEffectiveStress(theSeries); + else + meanConsolStress = getEffectiveStress(); + if(meanConsolStress == 0.0){ + opserr << "WARNING meanConsolStress is 0 in solid elements, ru will divide by zero"; + opserr << "QzLiq1: " << endln; + if(QzConstructorType==2) + opserr << "Effective Stress file seriesTag: " << theSeries->getTag() << endln; + else + opserr << "Adjacent solidElems: " << solidElem1 << ", " << solidElem2 << endln; + exit(-1); + } + } + lastLoadStage = loadStage; + + // Obtain the mean effective stress from the adjacent solid elements, + // and calculate ru for scaling of q-z base relation. + // + double meanStress; + if(loadStage == 1) { + if(QzConstructorType==2) + meanStress = getEffectiveStress(theSeries); + else + meanStress = getEffectiveStress(); + if(meanStress>meanConsolStress) + meanStress=meanConsolStress; + Tru = 1.0 - meanStress/meanConsolStress; + if(Tru > 0.999) Tru = 0.999; + if(Tru < 0) Tru = 0; + } + else { + Tru = 0.0; + } + + // Call the base class QzSimple1 to get basic q-z response, + // + double baseT = QzSimple1::getStress(); + double baseTangent = QzSimple1::getTangent(); + + // Check: Only update Hru if not yet converged (avoiding small changes in Tru). + // + if(Tz !=Cz || Tt !=Ct) Hru = Tru; + + // During dilation of the soil (ru dropping), provide a stiff transition + // between the old and new scaled q-z relations. This avoids illogical + // hardening of the q-z relation (i.e., negative stiffnesses). + // + if (Tru < Cru){ + + maxTangent = (QzSimple1::Qult/QzSimple1::z50)*pow(1.0-Cru,alpha); + + // If unloading, follow the old scaled q-z relation until t=0. + // + if(Cz>0.0 && Tz0.0){ + Hru = Cru; + } + if(Cz<0.0 && Tz>Cz && baseT<0.0){ + Hru = Cru; + } + + // If above the stiff transition line (between Tru & Cru scaled surfaces) + + // double zref = Cz + baseT*(Cru-Hru)/maxTangent; + double zref = Cz + baseT*(pow(1-Hru,alpha)-pow(1-Cru,alpha))/maxTangent; + if(Cz>0.0 && Tz>Cz && Tzzref){ + Hru = 1.0 - pow((Ct + (Tz-Cz)*maxTangent)/baseT,1.0/alpha); + } + + if(Hru > Cru) Hru = Cru; + if(Hru < Tru) Hru = Tru; + } + + // Now set the tangent and Tt values accordingly + // + + Tt = baseT*pow(1.0-Hru,alpha); + if(Hru==Cru || Hru==Tru){ + Tangent = pow(1.0-Hru,alpha)*baseTangent; + } + else { + Tangent = maxTangent; + } + + return 0; +} +///////////////////////////////////////////////////////////////////// +double +QzLiq1::getStress(void) +{ + double dashForce = getStrainRate()*this->getDampTangent(); + + // Limit the combined force to qult*(1-ru). + // + double tmax = (1.0-QZtolerance)*QzSimple1::Qult*pow(1.0-Hru,alpha); + if(fabs(Tt + dashForce) >= tmax) + return tmax*(Tt+dashForce)/fabs(Tt+dashForce); + else return Tt + dashForce; + +} +///////////////////////////////////////////////////////////////////// +double +QzLiq1::getTangent(void) +{ + return this->Tangent; + +} +///////////////////////////////////////////////////////////////////// +double +QzLiq1::getInitialTangent(void) +{ + return this->initialTangent; +} +///////////////////////////////////////////////////////////////////// +double +QzLiq1::getDampTangent(void) +{ + // Call the base class QzSimple1 to get basic q-z response, + // and then scale by (1-ru). + // + double dampTangent = QzSimple1::getDampTangent(); + return dampTangent*pow(1.0-Hru,alpha); +} +///////////////////////////////////////////////////////////////////// +double +QzLiq1::getStrain(void) +{ + double strain = QzSimple1::getStrain(); + return strain; +} +///////////////////////////////////////////////////////////////////// +double +QzLiq1::getStrainRate(void) +{ + double strainrate = QzSimple1::getStrainRate(); + return strainrate; +} +///////////////////////////////////////////////////////////////////// +int +QzLiq1::commitState(void) +{ + // Call the QzSimple1 base function to take care of details. + // + QzSimple1::commitState(); + Cz = Tz; + Ct = Tt; + Cru= Hru; + + return 0; +} + +///////////////////////////////////////////////////////////////////// +int +QzLiq1::revertToLastCommit(void) +{ + // reset to committed values + // + QzSimple1::revertToLastCommit(); + Tz = Cz; + Tt = Ct; + Hru= Cru; + + return 0; +} + +///////////////////////////////////////////////////////////////////// +int +QzLiq1::revertToStart(void) +{ + // Call the QzSimple1 base function to take care of most details. + // + QzSimple1::revertToStart(); + Tz = 0.0; + Tt = 0.0; + maxTangent = (QzSimple1::Qult/QzSimple1::z50); + + // Excess pore pressure ratio and pointers + // + Tru = 0.0; + Hru = 0.0; + meanConsolStress = -QzSimple1::Qult; + lastLoadStage = 0; + loadStage = 0; + elemFlag.assign("NONE"); + + // Now get all the committed variables initiated + // + commitState(); + + return 0; +} + +///////////////////////////////////////////////////////////////////// +double +QzLiq1::getEffectiveStress(TimeSeries *theSeries) +{ + return theSeries->getFactor(theDomain->getCurrentTime()); +} + +double +QzLiq1::getEffectiveStress(void) +{ + // Default value for meanStress + double meanStress = meanConsolStress; + + // if theDomain pointer is nonzero, then set pointers to attached soil elements. + // + if(theDomain != 0) + { + Element *theElement1 = theDomain->getElement(solidElem1); + Element *theElement2 = theDomain->getElement(solidElem2); + if (theElement1 == 0 || theElement2 == 0) { + opserr << "WARNING solid element not found in getEffectiveStress" << endln; + opserr << "QzLiq1: " << endln; + opserr << "Adjacent solidElems: " << solidElem1 << ", " << solidElem2 << endln; + exit(-1); + } + + // Check that the class tags for the solid elements are either for a FourNodeQuad object, a FourNodeQuadUP object, + // a 9_4_QuadUP object, a SSPquadUP object, or a SSPquad object + if(theElement1->getClassTag()!=ELE_TAG_FourNodeQuad && theElement1->getClassTag()!=ELE_TAG_FourNodeQuadUP && + theElement1->getClassTag()!=ELE_TAG_Nine_Four_Node_QuadUP && theElement1->getClassTag()!=ELE_TAG_SSPquadUP && theElement1->getClassTag()!=ELE_TAG_SSPquad) + { + opserr << "Element: " << theElement1->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + if(theElement2->getClassTag()!=ELE_TAG_FourNodeQuad && theElement2->getClassTag()!=ELE_TAG_FourNodeQuadUP && + theElement2->getClassTag()!=ELE_TAG_Nine_Four_Node_QuadUP && theElement2->getClassTag()!=ELE_TAG_SSPquadUP && theElement2->getClassTag()!=ELE_TAG_SSPquad) + { + opserr << "Element: " << theElement2->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + + double excessPorePressure = 0.0; + meanStress = 0.0; + + // get mean stress from element1 if it is a FourNodeQuad object + if(theElement1->getClassTag()==ELE_TAG_FourNodeQuad) + { + // It's safe to cast *theElement1 onto the FourNodeQuad class because we already + // checked the class tags. + FourNodeQuad *theElement1 = (FourNodeQuad *)(theDomain->getElement(solidElem1)); + + // If the element is a quad, check that the class tag for the material at each gauss point is 100 for FluidSolidPorous object + meanStress = 0.0; + for(int i=0;i<4;i++) + { + NDMaterial *NDM = theElement1->theMaterial[i]; + if(NDM->getClassTag()!=ND_TAG_FluidSolidPorousMaterial){ + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + FluidSolidPorousMaterial *theFSPM = (FluidSolidPorousMaterial *)(NDM); + meanStress += 1.0/8.0*(2.0/3.0*(NDM->getStress())[0] + 1.0/3.0*(NDM->getStress())[1] - theFSPM->trialExcessPressure); + } + } + // get mean stress from element2 if it is a FourNodeQuad object + if(theElement2->getClassTag()==ELE_TAG_FourNodeQuad) + { + // It's safe to cast *theElement1 onto the FourNodeQuad class because we already + // checked the class tags. + FourNodeQuad *theElement2 = (FourNodeQuad *)(theDomain->getElement(solidElem2)); + for(int i=0;i<4;i++) + { + NDMaterial *NDM = theElement2->theMaterial[i]; + if(NDM->getClassTag()!=ND_TAG_FluidSolidPorousMaterial){ + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + FluidSolidPorousMaterial *theFSPM = (FluidSolidPorousMaterial *)(NDM); + meanStress += 1.0/8.0*(2.0/3.0*(NDM->getStress())[0] + 1.0/3.0*(NDM->getStress())[1] - theFSPM->trialExcessPressure); + } + } + + // get mean stress from element1 if it is a FourNodeQuadUP object + if(theElement1->getClassTag()==ELE_TAG_FourNodeQuadUP) { + // It's safe to cast *theElement1 onto the FourNodeQuadUP class because we already checked the class tags. + FourNodeQuadUP *theElement1 = (FourNodeQuadUP *)(theDomain->getElement(solidElem1)); + meanStress=0.0; + + for(int i=0;i<4;i++) { + NDMaterial *NDM = theElement1->theMaterial[i]; + if(NDM->getClassTag()==ND_TAG_InitialStateAnalysisWrapper) { + InitialStateAnalysisWrapper *NDM = (InitialStateAnalysisWrapper *)(theElement1->theMaterial); + if(NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield02) { + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + } else if(NDM->getClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getClassTag() !=ND_TAG_PressureDependMultiYield02){ + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + meanStress += 1.0/8.0*(2.0/3.0*(NDM->getStress())[0] + 1.0/3.0*(NDM->getStress())[1]); + } + } + // get mean stress from element 2 if it is a FourNodeQuadUP object + if(theElement2->getClassTag()==ELE_TAG_FourNodeQuadUP) { + // It's safe to cast *theElement2 onto the FourNodeQuadUP class because we already checked the class tags. + FourNodeQuadUP *theElement2 = (FourNodeQuadUP *)(theDomain->getElement(solidElem2)); + for(int i=0;i<4;i++) { + NDMaterial *NDM = theElement2->theMaterial[i]; + if(NDM->getClassTag()==ND_TAG_InitialStateAnalysisWrapper) { + InitialStateAnalysisWrapper *NDM = (InitialStateAnalysisWrapper *)(theElement2->theMaterial); + if(NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield02) { + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + } else if(NDM->getClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getClassTag() !=ND_TAG_PressureDependMultiYield02){ + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + meanStress += 1.0/8.0*(2.0/3.0*(NDM->getStress())[0] + 1.0/3.0*(NDM->getStress())[1]); + } + } + + // get mean stress from element1 if it is a 9_4_QuadUP object + if(theElement1->getClassTag()==ELE_TAG_Nine_Four_Node_QuadUP) { + // It's safe to cast *theElement1 onto the 9_4_QuadUP class because we already checked the class tags. + NineFourNodeQuadUP *theElement1 = (NineFourNodeQuadUP *)(theDomain->getElement(solidElem1)); + meanStress=0.0; + + for(int i=0;i<9;i++) { + NDMaterial *NDM = theElement1->theMaterial[i]; + if(NDM->getClassTag()==ND_TAG_InitialStateAnalysisWrapper) { + InitialStateAnalysisWrapper *NDM = (InitialStateAnalysisWrapper *)(theElement1->theMaterial); + if(NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield02) { + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + } else if(NDM->getClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getClassTag() !=ND_TAG_PressureDependMultiYield02){ + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + meanStress += 1.0/18.0*(2.0/3.0*(NDM->getStress())[0] + 1.0/3.0*(NDM->getStress())[1]); + } + } + // get mean stress from element2 if it is a 9_4_QuadUP object + if(theElement2->getClassTag()==ELE_TAG_Nine_Four_Node_QuadUP) { + // It's safe to cast *theElement2 onto the 9_4_QuadUP class because we already checked the class tags. + NineFourNodeQuadUP *theElement2 = (NineFourNodeQuadUP *)(theDomain->getElement(solidElem2)); + for(int i=0;i<9;i++) { + NDMaterial *NDM = theElement2->theMaterial[i]; + if(NDM->getClassTag()==ND_TAG_InitialStateAnalysisWrapper) { + InitialStateAnalysisWrapper *NDM = (InitialStateAnalysisWrapper *)(theElement2->theMaterial); + if(NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield02) { + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + } else if(NDM->getClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getClassTag() !=ND_TAG_PressureDependMultiYield02) { + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + meanStress += 1.0/18.0*(2.0/3.0*(NDM->getStress())[0] + 1.0/3.0*(NDM->getStress())[1]); + } + } + + // get mean stress from element1 if it is a SSPquadUP object + if(theElement1->getClassTag()==ELE_TAG_SSPquadUP) { + // It's safe to cast *theElement1 onto the SSPquadUP class because we already checked the class tags. + SSPquadUP *theElement1 = (SSPquadUP *)(theDomain->getElement(solidElem1)); + meanStress = 0.0; + + NDMaterial *NDM = theElement1->theMaterial; + if(NDM->getClassTag()==ND_TAG_InitialStateAnalysisWrapper) { + InitialStateAnalysisWrapper *NDM = (InitialStateAnalysisWrapper *)(theElement1->theMaterial); + if(NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield02) { + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + } else if(NDM->getClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getClassTag()!=ND_TAG_PressureDependMultiYield02) { + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + meanStress += 1.0/2.0*(2.0/3.0*(NDM->getStress())[0] + 1.0/3.0*(NDM->getStress())[1]); + } + // get mean stress from element 2 if it is a SSPquadUP object + if(theElement2->getClassTag()==ELE_TAG_SSPquadUP) { + // It's safe to cast *theElement1 onto the SSPquadUP class because we already checked the class tags. + SSPquadUP *theElement2 = (SSPquadUP *)(theDomain->getElement(solidElem2)); + + NDMaterial *NDM = theElement2->theMaterial; + if(NDM->getClassTag()==ND_TAG_InitialStateAnalysisWrapper) { + InitialStateAnalysisWrapper *NDM = (InitialStateAnalysisWrapper *)(theElement2->theMaterial); + if(NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getMainClassTag()!=ND_TAG_PressureDependMultiYield02) { + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + } else if(NDM->getClassTag()!=ND_TAG_PressureDependMultiYield && NDM->getClassTag()!=ND_TAG_PressureDependMultiYield02){ + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + meanStress += 1.0/2.0*(2.0/3.0*(NDM->getStress())[0] + 1.0/3.0*(NDM->getStress())[1]); + } + + // get mean stress from element1 if it is a SSPquad object + if(theElement1->getClassTag()==ELE_TAG_SSPquad) { + // It's safe to cast *theElement1 onto the SSPquad class because we already checked the class tags. + SSPquad *theElement1 = (SSPquad *)(theDomain->getElement(solidElem1)); + + // If the element is a SSPquad, check that the class tag for the material at each gauss point is FluidSolidPorous object + meanStress = 0.0; + + NDMaterial *NDM = theElement1->theMaterial; + if(NDM->getClassTag()!=ND_TAG_FluidSolidPorousMaterial){ + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + FluidSolidPorousMaterial *theFSPM = (FluidSolidPorousMaterial *)(NDM); + meanStress += 1.0/2.0*(2.0/3.0*(NDM->getStress())[0] + 1.0/3.0*(NDM->getStress())[1] - theFSPM->trialExcessPressure); + } + // get mean stress from element2 if it is a SSPquad object + if(theElement2->getClassTag()==ELE_TAG_SSPquad) { + // It's safe to cast *theElement2 onto the SSPquad class because we already checked the class tags. + SSPquad *theElement2 = (SSPquad *)(theDomain->getElement(solidElem2)); + + // If the element is a SSPquad, check that the class tag for the material at each gauss point is FluidSolidPorous object + NDMaterial *NDM = theElement2->theMaterial; + if(NDM->getClassTag()!=ND_TAG_FluidSolidPorousMaterial){ + opserr << "Material: " << NDM->getTag() << " cannot be used to read effective stress for a QzLiq1 material." << endln; + exit(-1); + } + FluidSolidPorousMaterial *theFSPM = (FluidSolidPorousMaterial *)(NDM); + meanStress += 1.0/2.0*(2.0/3.0*(NDM->getStress())[0] + 1.0/3.0*(NDM->getStress())[1] - theFSPM->trialExcessPressure); + } + + } + + return meanStress; +} + +int QzLiq1::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc >= 2) + if (strcmp(argv[0],"updateMaterialStage") == 0 && atoi(argv[1]) == this->getTag()) { + return param.addObject(1, this); + } + + return -1; +} + +///////////////////////////////////////////////////////////////////// +int +QzLiq1::updateParameter(int snum,Information &eleInformation) +{ + // TclUpdateMaterialStageCommand will call this routine with the + // command: + // + // updateMaterialStage - material tag -stage snum + // + // If snum = 0; running linear elastic for soil elements, + // so excess pore pressure should be zero. + // If snum = 1; running plastic soil element behavior, + // so this marks the end of the "consol" gravity loading. + + if(snum !=0 && snum !=1){ + opserr << "WARNING updateMaterialStage for QzLiq1 material must be 0 or 1"; + opserr << endln; + exit(-1); + } + loadStage = snum; + + return 0; +} + +///////////////////////////////////////////////////////////////////// +UniaxialMaterial * +QzLiq1::getCopy(void) +{ + // Make a new instance of this class and then assign it "this" to make a copy. + // + QzLiq1 *clone; // pointer to a QzLiq1 class + clone = new QzLiq1(); // pointer gets a new instance of QzLiq1 + *clone = *this; // the clone (dereferenced pointer) = dereferenced this. + + return clone; +} + +///////////////////////////////////////////////////////////////////// +int +QzLiq1::sendSelf(int cTag, Channel &theChannel) +{ + // I'm following an example by Frank here. + // + int res =0; + + static Vector data(17); + + QzSimple1::sendSelf(cTag, theChannel); + + data(0) = this->getTag(); + data(1) = Tz; + data(2) = Cz; + data(3) = Tt; + data(4) = Ct; + data(5) = Tangent; + data(6) = maxTangent; + data(7) = Tru; + data(8) = Cru; + data(9) = Hru; + data(10) = alpha; + if(QzConstructorType==2) + { + data(11) = theSeriesTag; + data(12) = 0.0; + } + if(QzConstructorType==1) + { + data(11) = solidElem1; + data(12) = solidElem2; + } + data(13) = meanConsolStress; + data(14) = loadStage; + data(15) = lastLoadStage; + data(16) = initialTangent; + + res = theChannel.sendVector(this->getDbTag(), cTag, data); + if (res < 0) + opserr << "QzLiq1::sendSelf() - failed to send data\n"; + + return res; +} + +///////////////////////////////////////////////////////////////////// +int +QzLiq1::recvSelf(int cTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + + static Vector data(17); + res = theChannel.recvVector(this->getDbTag(), cTag, data); + + if (res < 0) { + opserr << "QzLiq1::recvSelf() - failed to receive data\n"; + this->setTag(0); + } + else { + this->setTag((int)data(0)); + + QzSimple1::recvSelf(cTag, theChannel, theBroker); + + Tz = data(1); + Cz = data(2); + Tt = data(3); + Ct = data(4); + Tangent = data(5); + maxTangent =data(6); + Tru = data(7); + Cru = data(8); + Hru = data(9); + alpha = data(10); + if(QzConstructorType==1) + { + solidElem1 = (int)data(11); + solidElem2 = (int)data(12); + } + if(QzConstructorType==2) + { + theSeriesTag = (int)data(11); + } + meanConsolStress = data(13); + loadStage = (int)data(14); + lastLoadStage = (int)data(15); + initialTangent = data(16); + + // set the trial quantities + this->revertToLastCommit(); + } + + return res; +} + +///////////////////////////////////////////////////////////////////// +void +QzLiq1::Print(OPS_Stream &s, int flag) +{ + s << "QzLiq1, tag: " << this->getTag() << endln; + s << " QzType: " << QzType << endln; + s << " Qult: " << Qult << endln; + s << " z50: " << z50 << endln; + s << " dashpot: " << dashpot << endln; + s << " alpha: " << alpha << endln; + if(QzConstructorType==1) + { + s << " solidElem1: " << solidElem1 << endln; + s << " solidElem2: " << solidElem2 << endln; + } + if(QzConstructorType==2) + { + s << " Time Series Tag: " << theSeries->getTag() << endln; + } + +} + + + + diff --git a/SRC/material/uniaxial/PY/QzLiq1.h b/SRC/material/uniaxial/PY/QzLiq1.h new file mode 100644 index 000000000..936cd1c7d --- /dev/null +++ b/SRC/material/uniaxial/PY/QzLiq1.h @@ -0,0 +1,120 @@ +/* ********************************************************************* +** Module: QzLiq1.h +** +** Purpose: Provide a q-z material that gets pore pressure from a +** specified element that contains a PorousFluidSolid. +** +** +** Developed by Sumeet Kumar Sinha +** (C) Copyright 2002, All Rights Reserved. +** +** ****************************************************************** */ + +// $Revision: 1.0 +// $Date: 2020/6/12 +// $Source: /OpenSees/SRC/material/uniaxial/QzLiq1.h + +#ifndef QZLIQ1_H +#define QZLIQ1_H + +// Written: RWB +// Created: Feb 2002 +// +// Description: This file contains the class definition for QzLiq1. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class QzLiq1 : public QzSimple1 +{ + public: + QzLiq1(int tag, int qzType, double tult, double z50, double suction, + double dashpot, double alpha, int solidElem1, int solidElem2, Domain *theDomain); + QzLiq1(int tag, int qzType, double tult, double z50, double suction, + double dashpot, double alpha, Domain *theDomain, TimeSeries *theSeries); + QzLiq1(); + ~QzLiq1(); + + const char *getClassType(void) const {return "QzLiq1";}; + + int setTrialStrain(double y, double yRate); + double getStrain(void); + double getStress(void); + double getTangent(void); + double getStrainRate(void); + double getDampTangent(void); + double getInitialTangent(void); + + 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); + + // Command for initiating vertConsolStress from TclUpdateMaterialStageCommand + int setParameter(const char **argv, int argc, Parameter ¶m); + int updateParameter(int snum, Information &eleInformation); + + void Print(OPS_Stream &s, int flag =0); + + + protected: + + private: + + // Committed and trial values for q, z, and ru + double Tz; // Trial z (displacement) + double Cz; // Commit z (displacement) + double Tt; // Trial load + double Ct; // Commit load + double Tangent; // Tangent + double maxTangent; // maximum tangent + double Tru; // Trial ru + double Cru; // Commit ru + double Hru; // + double alpha; // factor (1-ru)^alpha + + // Solid element from which pore pressures are obtained, domain pointer + // and stage information to get the initial vertical effective stress. + int solidElem1; + int solidElem2; + int theSeriesTag; + + double meanConsolStress; + double ru; + + static int loadStage; + int lastLoadStage; + std::string elemFlag; + Domain *theDomain; + TimeSeries *theSeries; + FourNodeQuad *theQuad1; + FourNodeQuad *theQuad2; + + // Initial tangent + double initialTangent; + + // Function for obtaining effective stresses from adjoining solid soil elements + double getEffectiveStress(void); + double getEffectiveStress(TimeSeries *theSeries); + static Vector stressV3; + +}; + +#endif // QZLIQ1_H + + + diff --git a/SRC/material/uniaxial/PY/QzSimple1.cpp b/SRC/material/uniaxial/PY/QzSimple1.cpp index af0747579..8bd142e15 100644 --- a/SRC/material/uniaxial/PY/QzSimple1.cpp +++ b/SRC/material/uniaxial/PY/QzSimple1.cpp @@ -178,7 +178,7 @@ void QzSimple1::getClosure(double zlast, double dz) // if(TClose_z > 0.0) { - TClose_tang = 0.001*Qult/z50; + TClose_tang = 1e-6*Qult/z50; TClose_Q = TClose_z * TClose_tang; } @@ -374,6 +374,7 @@ void QzSimple1::getNearField(double zlast, double dz, double dz_old) int QzSimple1::setTrialStrain (double newz, double zRate) { + // Set trial values for displacement and load in the material // based on the last Tangent modulus. // diff --git a/SRC/material/uniaxial/PY/QzSimple1.h b/SRC/material/uniaxial/PY/QzSimple1.h index ab1637904..3cc054f9e 100644 --- a/SRC/material/uniaxial/PY/QzSimple1.h +++ b/SRC/material/uniaxial/PY/QzSimple1.h @@ -89,15 +89,6 @@ class QzSimple1 : public UniaxialMaterial protected: - - private: - - // Functions to get Q & z for each component individually - void getGap(double zlast, double dz, double dz_old); - void getClosure(double zlast, double dz); - void getSuction(double zlast, double zy); - void getNearField(double zlast, double dz, double dz_old); - void getFarField(double z); // Material parameters int QzType; // Q-z relation selection @@ -110,6 +101,17 @@ class QzSimple1 : public UniaxialMaterial double maxElast; // max size of elastic range (in terms of dQ/Qult) double nd; // exponent for hardening shape of suction component double dashpot; // dashpot on the far-field (elastic) component + + private: + + // Functions to get Q & z for each component individually + void getGap(double zlast, double dz, double dz_old); + void getClosure(double zlast, double dz); + void getSuction(double zlast, double zy); + void getNearField(double zlast, double dz, double dz_old); + void getFarField(double z); + + // Generated parameters or constants (not user input) double NFkrig; // stiffness of the "rigid" portion of Near Field diff --git a/SRC/material/uniaxial/PY/QzSimple2.cpp b/SRC/material/uniaxial/PY/QzSimple2.cpp index 8c86d5f0a..e3db364ea 100644 --- a/SRC/material/uniaxial/PY/QzSimple2.cpp +++ b/SRC/material/uniaxial/PY/QzSimple2.cpp @@ -55,11 +55,43 @@ #include "QzSimple2.h" #include #include +#include // Controls on internal iterations between spring components const int QZmaxIterations = 20; const double QZtolerance = 1.0e-12; +void* OPS_QzSimple2() +{ + int numdata = OPS_GetNumRemainingInputArgs(); + if (numdata < 4) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: uniaxialMaterial QzSimple2 tag? qzType? qult? z50? suction? c?\n"; + return 0; + } + + int idata[2]; + numdata = 2; + if (OPS_GetIntInput(&numdata, idata) < 0) { + opserr << "WARNING invalid int inputs\n"; + return 0; + } + + double ddata[4] = {0,0,0,0}; + numdata = OPS_GetNumRemainingInputArgs(); + if (numdata > 4) numdata = 4; + if (OPS_GetDoubleInput(&numdata, ddata) < 0) { + opserr << "WARNING invalid double inputs\n"; + return 0; + } + + UniaxialMaterial *theMaterial = 0; + theMaterial = new QzSimple2(idata[0], idata[1], ddata[0], ddata[1], + ddata[2], ddata[3]); + + return theMaterial; +} + ///////////////////////////////////////////////////////////////////// // Constructor with data @@ -146,7 +178,7 @@ void QzSimple2::getClosure(double zlast, double dz) // if(TClose_z > 0.0) { - TClose_tang = 0.001*Qult/z50; + TClose_tang = 1e-6*Qult/z50; TClose_Q = TClose_z * TClose_tang; } diff --git a/SRC/material/uniaxial/PY/TclPyTzQzMaterialCommand.cpp b/SRC/material/uniaxial/PY/TclPyTzQzMaterialCommand.cpp index ffc4aef9d..0cf99efe0 100644 --- a/SRC/material/uniaxial/PY/TclPyTzQzMaterialCommand.cpp +++ b/SRC/material/uniaxial/PY/TclPyTzQzMaterialCommand.cpp @@ -33,6 +33,7 @@ #include #include // RWB #include // RWB +#include // Sumeet #include #include #include @@ -153,7 +154,7 @@ TclModelBuilder_addPyTzQzMaterial(ClientData clientData, Tcl_Interp *interp, int opserr << "WARNING insufficient arguments\n"; printCommand(argc,argv); opserr << "Want: uniaxialMaterial PyLiq1 tag? soilType? pult? y50? drag? dashpot? pRes? solidElem1? solidElem2?" << endln; - opserr << "or: uniaxialMaterial PyLiq1 tag? soilType? pult? y50? drag? dashpot? -timeSeries seriesTag?" << endln; + opserr << "or: uniaxialMaterial PyLiq1 tag? soilType? pult? y50? drag? dashpot? pRes? -timeSeries seriesTag?" << endln; return 0; } @@ -302,7 +303,97 @@ TclModelBuilder_addPyTzQzMaterial(ClientData clientData, Tcl_Interp *interp, int theMaterial = new QzSimple2(tag, QzType, Qult, z50, suction, dashpot); } + // INSERTING THE EXTRA LINES FOR QzLiq1 ////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// + else if (strcmp(argv[1],"QzLiq1") == 0) { + if (argc < 11) { + opserr << "WARNING insufficient arguments\n"; + printCommand(argc,argv); + opserr << "Want: uniaxialMaterial QzLiq1 tag? qzType? qult? z50? suction? dashpot? alpha solidElem1? solidElem2?" << endln; + opserr << "or: uniaxialMaterial QzLiq1 tag? qzType? qult? z50? suction? dashpot? alpha -timeSeries seriesTag?" << endln; + return 0; + } + + int tag, qzType, solidElem1, solidElem2, seriesTag; + double qult, z50, suction, dashpot, alpha; + + if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { + opserr << "WARNING invalid uniaxialMaterial QzLiq1 tag" << endln; + return 0; + } + + if (Tcl_GetInt(interp, argv[3], &qzType) != TCL_OK) { + opserr << "WARNING invalid qzType\n"; + opserr << "uniaxialMaterial QzLiq1: " << tag << endln; + return 0; + } + + if (Tcl_GetDouble(interp, argv[4], &qult) != TCL_OK) { + opserr << "WARNING invalid qult\n"; + opserr << "uniaxialMaterial QzLiq1: " << tag << endln; + return 0; + } + + if (Tcl_GetDouble(interp, argv[5], &z50) != TCL_OK) { + opserr << "WARNING invalid z50\n"; + opserr << "uniaxialMaterial QzLiq1: " << tag << endln; + return 0; + } + + if (Tcl_GetDouble(interp, argv[6], &suction) != TCL_OK) { + opserr << "WARNING invalid suction\n"; + opserr << "uniaxialMaterial QzLiq1: " << tag << endln; + return 0; + } + + if (Tcl_GetDouble(interp, argv[7], &dashpot) != TCL_OK) { + opserr << "WARNING invalid dashpot\n"; + opserr << "uniaxialMaterial QzLiq1: " << tag << endln; + return 0; + } + + if (Tcl_GetDouble(interp, argv[8], &alpha) != TCL_OK) { + opserr << "WARNING invalid alpha\n"; + opserr << "uniaxialMaterial QzLiq1: " << tag << endln; + return 0; + } + + if (strcmp(argv[9],"-timeSeries")!=0) + { + if (Tcl_GetInt(interp, argv[9], &solidElem1) != TCL_OK) { + opserr << "WARNING invalid solidElem\n"; + opserr << "uniaxialMaterial QzLiq1: " << tag << endln; + return 0; + } + + if (Tcl_GetInt(interp, argv[10], &solidElem2) != TCL_OK) { + opserr << "WARNING invalid solidElem\n"; + opserr << "uniaxialMaterial QzLiq1: " << tag << endln; + return 0; + } + + // Parsing was successful, allocate the material + theMaterial = new QzLiq1(tag, qzType, qult, z50, suction, dashpot,alpha, + solidElem1, solidElem2, theDomain); + } + else + { + if (Tcl_GetInt(interp, argv[10], &seriesTag) != TCL_OK) { + opserr << "WARNING time Series\n"; + opserr << "uniaxialMaterial QzLiq1: " << tag << endln; + return 0; + + } + theSeries = OPS_getTimeSeries(seriesTag); + + // Parsing was successful, allocate the material + theMaterial = new QzLiq1(tag, qzType, qult, z50, suction, dashpot,alpha, + theDomain, theSeries); + } + + } + // INSERTING THE EXTRA LINES FOR TzSimple1 ////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/SRC/material/uniaxial/PY/TzLiq1.cpp b/SRC/material/uniaxial/PY/TzLiq1.cpp index 89b24406a..e3e13b730 100644 --- a/SRC/material/uniaxial/PY/TzLiq1.cpp +++ b/SRC/material/uniaxial/PY/TzLiq1.cpp @@ -191,8 +191,11 @@ TzLiq1::setTrialStrain (double newz, double zRate) meanStress = getEffectiveStress(theSeries); else meanStress = getEffectiveStress(); + if(meanStress>meanConsolStress) + meanStress=meanConsolStress; Tru = 1.0 - meanStress/meanConsolStress; if(Tru > 0.999) Tru = 0.999; + if(Tru < 0) Tru = 0; } else { Tru = 0.0; @@ -235,8 +238,8 @@ TzLiq1::setTrialStrain (double newz, double zRate) } } - // Now set the tangent and Tt values accordingly - // + // Now set the tangent and Tt values accordingly + Tt = baseT*(1.0-Hru); if(Hru==Cru || Hru==Tru){ diff --git a/SRC/material/uniaxial/PY/TzSimple1.cpp b/SRC/material/uniaxial/PY/TzSimple1.cpp index a336d13af..7d7447743 100644 --- a/SRC/material/uniaxial/PY/TzSimple1.cpp +++ b/SRC/material/uniaxial/PY/TzSimple1.cpp @@ -144,7 +144,7 @@ void TzSimple1::getFarField(double z) ///////////////////////////////////////////////////////////////////// void TzSimple1::getNearField(double zlast, double dz, double dz_old) { - // Limit "dz" step size if it is osillating and not shrinking. + // Limit "dz" step size if it is oscillating and not shrinking. // if(dz*dz_old < 0.0 && fabs(dz/dz_old) > 0.5) dz = -dz_old/2.0; diff --git a/SRC/material/uniaxial/PY/TzSimple2.cpp b/SRC/material/uniaxial/PY/TzSimple2.cpp index 12f7afd05..72cb9547e 100644 --- a/SRC/material/uniaxial/PY/TzSimple2.cpp +++ b/SRC/material/uniaxial/PY/TzSimple2.cpp @@ -56,11 +56,43 @@ #include #include #include +#include // Controls on internal iteration between spring components const int TZmaxIterations = 20; const double TZtolerance = 1.0e-12; +void* OPS_TzSimple2() +{ + int numdata = OPS_GetNumRemainingInputArgs(); + if (numdata < 4) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: uniaxialMaterial TzSimple2 tag? tzType? tult? z50? dashpot?\n"; + return 0; + } + + int idata[2]; + numdata = 2; + if (OPS_GetIntInput(&numdata, idata) < 0) { + opserr << "WARNING invalid int inputs\n"; + return 0; + } + + double ddata[3] = {0,0,0}; + numdata = OPS_GetNumRemainingInputArgs(); + if (numdata > 3) numdata = 3; + if (OPS_GetDoubleInput(&numdata, ddata) < 0) { + opserr << "WARNING invalid double inputs\n"; + return 0; + } + + UniaxialMaterial *theMaterial = 0; + theMaterial = new TzSimple2(idata[0], MAT_TAG_PySimple1, idata[1], ddata[0], ddata[1], + ddata[2]); + + return theMaterial; +} + ///////////////////////////////////////////////////////////////////// // Constructor with data diff --git a/SRC/material/uniaxial/SMAMaterial.cpp b/SRC/material/uniaxial/SMAMaterial.cpp new file mode 100644 index 000000000..dce9a18ec --- /dev/null +++ b/SRC/material/uniaxial/SMAMaterial.cpp @@ -0,0 +1,450 @@ +/* ****************************************************************** ** +** 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) ** +** ** +** ****************************************************************** */ + +// Description: This file contains the class implementation for SMAMaterial. + +#include +#include +#include +#include +#include + +void* OPS_SMAMaterial() +{ + int numdata = OPS_GetNumRemainingInputArgs(); + if (numdata < 7) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: uniaxialMaterial SMA matTag? E? eps_L? sig_AM_s? sig_AM_f? sig_MA_s? sig_MA_f?" << endln; + return 0; + } + + int tag; + numdata = 1; + if (OPS_GetIntInput(&numdata,&tag) < 0) { + opserr << "WARNING: failed to read tag\n"; + return 0; + } + + double data[6]; + numdata = 6; + if (OPS_GetDoubleInput(&numdata,data)) { + opserr << "WARNING: failed to read data\n"; + return 0; + } + + UniaxialMaterial* mat = new SMAMaterial(tag,data[0],data[1],data[2],data[3],data[4],data[5]); + if (mat == 0) { + opserr << "WARNING: failed to create SMAMaterial\n"; + return 0; + } + + return mat; +} + +SMAMaterial::SMAMaterial(int tag, double e, double el, double s_as_s, double s_as_f, + double s_sa_s, double s_sa_f) + :UniaxialMaterial(tag,MAT_TAG_SMA), + E(e), eps_L(el), sig_AS_s(s_as_s), sig_AS_f(s_as_f), sig_SA_s(s_sa_s), sig_SA_f(s_sa_f), + Tcsi(0.0), Tstrain(0.0), Tstress(0.0), Ttangent(0.0) +{ + // Initialize varibles + this->revertToStart(); +} + +SMAMaterial::SMAMaterial() + :UniaxialMaterial(0,MAT_TAG_SMA), + E(0.0), eps_L(0.0), sig_AS_s(0.0), sig_AS_f(0.0), sig_SA_s(0.0), sig_SA_f(0.0), + Tcsi(0.0), Tstrain(0.0), Tstress(0.0), Ttangent(0.0) +{ + // Initialize variables + this->revertToStart(); +} + +SMAMaterial::~SMAMaterial() +{ + // does nothing +} + +int +SMAMaterial::setTrialStrain(double strain, double strainRate) +{ + Tstrain = strain; + + //------------------------------------------------------------------------------------- + // A ---> S transformation (loading), sigma > 0 and epsilon > 0 + //------------------------------------------------------------------------------------- + + if ((Tstrain - Cstrain) > 0 && Tstrain > 0) { + + double eps_AS_s = sig_AS_s/E + Ccsi*eps_L; + double eps_AS_f = sig_AS_f/E + eps_L; + + if (Tstrain <= eps_AS_s) { + + Tcsi = Ccsi; + Tstress = E*(Tstrain - Tcsi*eps_L); + Ttangent = E; + + } + + else if (Tstrain > eps_AS_s && Tstrain < eps_AS_f) { + + if (Cstress <= sig_AS_s) { + + Tcsi = (Ccsi*E*Tstrain - Ccsi*sig_AS_f - E*Tstrain + sig_AS_s)/(-sig_AS_f + Ccsi*E*eps_L - E*eps_L + sig_AS_s); + Tstress = E*(Tstrain - Tcsi*eps_L); + double H = -(1 - Ccsi)*E/((1 - Ccsi)*(-E*eps_L) + sig_AS_s - sig_AS_f); + Ttangent = E*(1 - eps_L*H); + + } + + else { + + Tcsi = (Ccsi*E*Tstrain - Ccsi*sig_AS_f - E*Tstrain + Cstress)/(-sig_AS_f + Ccsi*E*eps_L - E*eps_L + Cstress); + Tstress = E*(Tstrain - Tcsi*eps_L); + double H = -(1 - Ccsi)*E/((1 - Ccsi)*(-E*eps_L) + Cstress - sig_AS_f); + Ttangent = E*(1 - eps_L*H); + + } + + } + + else { + + Tcsi = 1; + Tstress = E*(Tstrain - Tcsi*eps_L); + Ttangent = E; + + } + + } + + //------------------------------------------------------------------------------------- + // S ---> A transformation (unloading), sigma > 0 and epsilon > 0 + //------------------------------------------------------------------------------------- + + if ((Tstrain - Cstrain) < 0 && Tstrain > 0) { + + double eps_SA_s = sig_SA_s/E + Ccsi*eps_L; + double eps_SA_f = sig_SA_f/E; + + if (Tstrain >= eps_SA_s) { + + Tcsi = Ccsi; + Tstress = E*(Tstrain - Tcsi*eps_L); + Ttangent = E; + + } + + else if (Tstrain < eps_SA_s && Tstrain >= eps_SA_f) { + + if (Cstress > sig_SA_s) { + + Tcsi = (Ccsi*E*Tstrain - Ccsi*sig_SA_f)/(-sig_SA_f + Ccsi*E*eps_L + sig_SA_s); + Tstress = E*(Tstrain - Tcsi*eps_L); + double H = (Ccsi*E)/(- Ccsi*(-E*eps_L) + sig_SA_s - sig_SA_f); + Ttangent = E*(1 - eps_L*H); + + } + + else { + + Tcsi = (Ccsi*E*Tstrain - Ccsi*sig_SA_f)/(-sig_SA_f + Ccsi*E*eps_L + Cstress); + Tstress = E*(Tstrain - Tcsi*eps_L); + double H = (Ccsi*E)/(-Ccsi*(-E*eps_L) + Cstress - sig_SA_f); + Ttangent = E*(1 - eps_L*H); + + } + + } + + else { + + Tcsi = 0; + Tstress = E*(Tstrain); + Ttangent = E; + + } + + } + + //------------------------------------------------------------------------------------- + // S ---> A transformation (loading), sigma < 0 and epsilon < 0 + //------------------------------------------------------------------------------------- + + if ((Tstrain - Cstrain) < 0 && Tstrain < 0.0) { + + double eps_AS_s = -sig_AS_s/E - Ccsi*eps_L; + double eps_AS_f = -sig_AS_f/E - eps_L; + + if (Tstrain >= eps_AS_s) { + + Tcsi = Ccsi; + Tstress = E*(Tstrain + Tcsi*eps_L); + Ttangent = E; + + } + + else if (Tstrain < eps_AS_s && Tstrain > eps_AS_f) { + + if (Cstress >= -sig_AS_s) { + + Tcsi = (Ccsi*E*Tstrain + Ccsi*sig_AS_f - E*Tstrain - sig_AS_s)/(sig_AS_f - Ccsi*E*eps_L + E*eps_L - sig_AS_s); + Tstress = E*(Tstrain + Tcsi*eps_L); + double H = (1 - Ccsi)*E/((1 - Ccsi)*(E*eps_L) - sig_AS_s + sig_AS_f); + Ttangent = E*(1 - eps_L*H); + + } + + else { + + Tcsi = (Ccsi*E*Tstrain + Ccsi*sig_AS_f - E*Tstrain + Cstress)/(sig_AS_f - Ccsi*E*eps_L + E*eps_L + Cstress); + Tstress = E*(Tstrain + Tcsi*eps_L); + double H = (1 - Ccsi)*E/((1 - Ccsi)*(E*eps_L) + Cstress + sig_AS_f); + Ttangent = E*(1 - eps_L*H); + + } + + } + + else { + + Tcsi = 1; + Tstress = E*(Tstrain + Tcsi*eps_L); + Ttangent = E; + + } + + } + + //------------------------------------------------------------------------------------- + // S ---> A transformation (unloading), sigma < 0 and epsilon < 0 + //------------------------------------------------------------------------------------- + + if ((Tstrain - Cstrain) > 0 && Tstrain < 0.0) { + + double eps_SA_s = -sig_SA_s/E - Ccsi*eps_L; + double eps_SA_f = -sig_SA_f/E; + + if (Tstrain <= eps_SA_s) { + + Tcsi = Ccsi; + Tstress = E*(Tstrain + Tcsi*eps_L); + Ttangent = E; + + } + + else if (Tstrain > eps_SA_s && Tstrain <= eps_SA_f) { + + if (Cstress < -sig_SA_s) { + + Tcsi = (Ccsi*E*Tstrain + Ccsi*sig_SA_f)/(sig_SA_f - Ccsi*E*eps_L - sig_SA_s); + Tstress = E*(Tstrain + Tcsi*eps_L); + double H = -(Ccsi*E)/(-Ccsi*(E*eps_L) - sig_SA_s + sig_SA_f); + Ttangent = E*(1 - eps_L*H); + + } + + else { + + Tcsi = (Ccsi*E*Tstrain + Ccsi*sig_SA_f)/(sig_SA_f - Ccsi*E*eps_L + Cstress); + Tstress = E*(Tstrain + Tcsi*eps_L); + double H = -(Ccsi*E)/(-Ccsi*(E*eps_L) + Cstress + sig_SA_f); + Ttangent = E*(1 - eps_L*H); + + } + + } + + else { + + Tcsi = 0; + Tstress = E*(Tstrain); + Ttangent = E; + + } + + } + + return 0; + +} + +double +SMAMaterial::getStress(void) +{ + return Tstress; +} + +double +SMAMaterial::getTangent(void) +{ + return Ttangent; +} + +double +SMAMaterial::getInitialTangent(void) +{ + return E; +} + +double +SMAMaterial::getStrain(void) +{ + return Tstrain; +} + +int +SMAMaterial::commitState(void) +{ + + // Commit trial state variables + + Cstrain = Tstrain; + Cstress = Tstress; + Ccsi = Tcsi; + + return 0; +} + +int +SMAMaterial::revertToLastCommit(void) +{ + return 0; +} + +int +SMAMaterial::revertToStart(void) +{ + + // Reset committed history variables + + Cstrain = 0.0; + Cstress = 0.0; + Ccsi = 0.0; + + // Reset trial history variables + + // Initialize state variables + + Tcsi = 0.0; + Tstrain = 0.0; + Tstress = 0.0; + Ttangent = E; + + return 0; +} + +UniaxialMaterial * +SMAMaterial::getCopy(void) +{ + SMAMaterial *theCopy = new SMAMaterial(this->getTag(), E, eps_L, sig_AS_s, sig_AS_f, sig_SA_s, sig_SA_f); + + // Copy committed history variables + + theCopy->Cstrain = Cstrain; + theCopy->Cstress = Cstress; + theCopy->Ccsi = Ccsi; + + // Copy trial state variables + + theCopy->Tcsi = Tcsi; + theCopy->Tstrain = Tstrain; + theCopy->Tstress = Tstress; + theCopy->Ttangent = Ttangent; + + return theCopy; +} + +int +SMAMaterial::sendSelf(int cTag, Channel &theChannel) +{ + int res = 0; + + static Vector data(11); + + data(0) = this->getTag(); + data(1) = E; + data(2) = eps_L; + data(3) = sig_AS_s; + data(4) = sig_AS_f; + data(5) = sig_SA_s; + data(6) = sig_SA_f; + data(7) = Cstrain; + data(8) = Cstress; + data(9) = Ccsi; + data(10) = Ttangent; + + res = theChannel.sendVector(this->getDbTag(), cTag, data); + if (res < 0) + opserr << "SMAMaterial::sendSelf() - failed to send data\n"; + + return res; +} + +int +SMAMaterial::recvSelf(int cTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + + static Vector data(11); + res = theChannel.recvVector(this->getDbTag(), cTag, data); + + if (res < 0) { + opserr << "SMAMaterial::recvSelf() - failed to receive data\n"; + E = 0; + this->setTag(0); + } + else { + this->setTag((int)data(0)); + E = data(1); + eps_L = data(2); + sig_AS_s = data(3); + sig_AS_f = data(4); + sig_SA_s = data(5); + sig_SA_f = data(6); + Cstrain = data(7); + Cstress = data(8); + Ccsi = data(9); + Ttangent = data(10); + + Tstrain = Cstrain; + Tstress = Cstress; + Tcsi = Ccsi; + } + + return res; +} + +void +SMAMaterial::Print(OPS_Stream &s, int flag) +{ + s << "SMAMaterial, tag: " << this->getTag() << endln; + s << " E: " << E << endln; + s << " eps_L: " << eps_L << endln; + s << " sig_AS_s: " << sig_AS_s << endln; + s << " sig_AS_f: " << sig_AS_f << endln; + s << " sig_SA_s: " << sig_SA_s << endln; + s << " sig_SA_f: " << sig_SA_f << endln; + return; +} + + diff --git a/SRC/material/uniaxial/SMAMaterial.h b/SRC/material/uniaxial/SMAMaterial.h new file mode 100644 index 000000000..bfb9fd985 --- /dev/null +++ b/SRC/material/uniaxial/SMAMaterial.h @@ -0,0 +1,86 @@ +/* ****************************************************************** ** +** 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) ** +** ** +** ****************************************************************** */ + +// $Revison +// $Date +// $Source + +// written by: Davide Fugazza + +// Description: This file contains the class definition for SMAMaterial. + +#ifndef SMAMaterial_h +#define SMAMaterial_h + +#include + +class SMAMaterial : public UniaxialMaterial +{ + public: + SMAMaterial(int tag, double E, double eps_L, double sig_AS_s, double sig_AS_f, double sig_SA_s, double sig_SA_f); + SMAMaterial(); + ~SMAMaterial(); + + int setTrialStrain(double strain, double strainRate = 0.0); + double getStrain(void); + double getStress(void); + double getTangent(void); + double getInitialTangent(void); + + 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 + double E; // elastic modulus for austenite and martensite + double eps_L; // plateau length (ex. 0.08 means 8%) + double sig_AS_s; // forward transformation stress start + double sig_AS_f; // forward transformation stress finish + double sig_SA_s; // reverse transformation stress start + double sig_SA_f; // reverse transformation stress finish + + // Committed history variables + double Cstrain; // strain at time t_n (previous time step) + double Cstress; // stress at time t_n (previous time step) + double Ccsi; // martensite fraction at time t_n (previous time step) + + // Trial history variables + double Tcsi; // trial martensite fraction at time t (current time step) + + // Trial state variables + double Tstrain; // trial strain at time t (current time step) + double Tstress; // trial stress at time t (current time step) + double Ttangent; // tangent at time t (current time step) +}; + +#endif + diff --git a/SRC/material/uniaxial/SmoothPSConcrete.cpp b/SRC/material/uniaxial/SmoothPSConcrete.cpp index d238eaafe..09da550b6 100755 --- a/SRC/material/uniaxial/SmoothPSConcrete.cpp +++ b/SRC/material/uniaxial/SmoothPSConcrete.cpp @@ -611,7 +611,7 @@ void SmoothPSConcrete::Print (OPS_Stream& s, int flag) /*Response* -SmoothPSConcrete::setResponse(const char **argv, int argc, Information &matInfo) +SmoothPSConcrete::setResponse(const char **argv, int argc, OPS_Stream &output) { @@ -628,7 +628,7 @@ SmoothPSConcrete::setResponse(const char **argv, int argc, Information &matInfo) //by default, See if the response is one of the defaults - Response *res = UniaxialMaterial::setResponse(argv, argc, matInfo); + Response *res = UniaxialMaterial::setResponse(argv, argc, output); if (res != 0) return res; else return 0; } diff --git a/SRC/material/uniaxial/SmoothPSConcrete.h b/SRC/material/uniaxial/SmoothPSConcrete.h index c4d7aaef6..38ae21ac8 100755 --- a/SRC/material/uniaxial/SmoothPSConcrete.h +++ b/SRC/material/uniaxial/SmoothPSConcrete.h @@ -73,7 +73,7 @@ class SmoothPSConcrete : public UniaxialMaterial void Print(OPS_Stream &s, int flag =0); -// Response* setResponse(const char **argv, int argc, Information &matInfo); +// Response* setResponse(const char **argv, int argc, OPS_Stream &output); // int getResponse(int responseID, Information &matInfo); // AddingSensitivity:BEGIN ////////////////////////////////////////// diff --git a/SRC/material/uniaxial/SteelFractureDI.cpp b/SRC/material/uniaxial/SteelFractureDI.cpp new file mode 100644 index 000000000..8ae752a22 --- /dev/null +++ b/SRC/material/uniaxial/SteelFractureDI.cpp @@ -0,0 +1,805 @@ +/* ****************************************************************** ** +** 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: 2021-05-18 00:17:20 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/SteelFractureDI.cpp,v $ + +// Written: Francisco A. Galvis and Wen-Yi Yen +// Created: 05/2021 +// +// Description: This file contains the class implementation of SteelFractureDI. +// SteelFractureDI is based on the source code for Steel02 +// + +#include + +#include +#include "SteelFractureDI.h" +#include +#include // for recorder +#include +#include + + +#include +#include + + +void * +OPS_SteelFractureDI() +{ + // Pointer to a uniaxial material that will be returned + UniaxialMaterial *theMaterial = 0; + + int iData[1]; + double dData[14]; + int numData = 1; + + if (OPS_GetIntInput(&numData, iData) != 0) { + opserr << "WARNING invalid uniaxialMaterial SteelFractureDI tag" << endln; + return 0; + } + + numData = OPS_GetNumRemainingInputArgs(); + + if (numData != 14) { + opserr << "Invalid #args, want: uniaxialMaterial SteelFractureDI " << iData[0] << + " fy? E? b? R0? cR1? cR2? a1? a2? a3? a4? sigcr? m? sigmin? FI_lim?" << endln; + return 0; + } + else { + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "Invalid arggs: uniaxialMaterial SteelFractureDI " << iData[0] << + " fy? E? b? R0? cR1? cR2? a1? a2? a3? a4? sigcr? m? sigmin? FI_lim?" << endln; + return 0; + } + theMaterial = new SteelFractureDI(iData[0], dData[0], 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]); + } + + + + if (theMaterial == 0) { + opserr << "WARNING could not create uniaxialMaterial of type SteelFractureDI Material\n"; + return 0; + } + + return theMaterial; +} + + + +SteelFractureDI::SteelFractureDI(int tag, + double _Fy, double _E0, double _b, + double _R0, double _cR1, double _cR2, + double _a1, double _a2, double _a3, double _a4, double _sigcr, double _m, double _sigmin, double _FI_lim): + UniaxialMaterial(tag, MAT_TAG_SteelFractureDI), + //UniaxialMaterial(tag, 0), + Fy(_Fy), E0(_E0), b(_b), R0(_R0), cR1(_cR1), cR2(_cR2), a1(_a1), a2(_a2), a3(_a3), a4(_a4), + sigcr(_sigcr), m(_m), sigmin(_sigmin), FI_lim(_FI_lim) +{ + konP = 0; + kon = 0; + eP = E0; + epsP = 0.0; + sigP = 0.0; + sig = 0.0; + eps = 0.0; + e = E0; + + epsmaxP = Fy / E0; + epsminP = -epsmaxP; + epsplP = 0.0; + epss0P = 0.0; + sigs0P = 0.0; + epssrP = 0.0; + sigsrP = 0.0; + + // ************** added for fracture *************** + epsCont = 0.0; + konf = 0; + konC = 0; + + epsContP = 0.0; + eps_0 = 0.0; + eps_1 = 0.0; + eps_r = 0; + konfP = 0; + konCP = 0; + // ************** added for fracture *************** + // ************** added for DI ******************** + DIP = 0.0; + isStartP = 1; + sigPDIP = 0.0; + slopePP = 0.0; + sumTenPP = 0.0; + sumCompPP = 0.0; + + DI = 0.0; + isStart = 1; + sigPDI = 0.0; + slopeP = 0.0; + sumTenP = 0.0; + sumCompP = 0.0; + + // ************** added for DI ******************** + +} + + +SteelFractureDI::SteelFractureDI(void) : + UniaxialMaterial(0, MAT_TAG_SteelFractureDI) + // UniaxialMaterial(0, 0) +{ + konP = 0; +} + +SteelFractureDI::~SteelFractureDI(void) +{ + // Does nothing +} + +UniaxialMaterial* +SteelFractureDI::getCopy(void) +{ + //Steel02 *theCopy = new Steel02(this->getTag(), Fy, E0, b, R0, cR1, cR2, a1, a2, a3, a4, sigini); + SteelFractureDI *theCopy = new SteelFractureDI(this->getTag(), Fy, E0, b, R0, cR1, cR2, a1, a2, a3, a4, sigcr, m, sigmin, FI_lim); + + return theCopy; +} + +double +SteelFractureDI::getInitialTangent(void) +{ + return E0; +} + +int +SteelFractureDI::setTrialStrain(double trialStrain, double strainRate) +{ + double Esh = b * E0; + double epsy = Fy / E0; + + eps = trialStrain; + double deps = eps - epsP; + + epsmax = epsmaxP; + epsmin = epsminP; + epspl = epsplP; + epss0 = epss0P; + sigs0 = sigs0P; + epsr = epssrP; + sigr = sigsrP; + kon = konP; + // ************** added for fracture *************** + epsCont = epsContP; + eps_0 = eps_0P; + eps_1 = eps_1P; + eps_r = eps_rP; + konf = konfP; + konC = konCP; + // ************** added for fracture *************** + // ************** added for DI ******************** + DI = DIP; + isStart = isStartP; + sigPDI = sigPDIP; + slopeP = slopePP; + sumTenP = sumTenPP; + sumCompP = sumCompPP; + + // ************** added for DI ******************** + + if (kon == 0 || kon == 3) { // modified C-P. Lamarche 2006 + + + if (fabs(deps) < 10.0*DBL_EPSILON) { + + e = E0; + //sig = sigini; // modified C-P. Lamarche 2006 + sig = 0; + kon = 3; // modified C-P. Lamarche 2006 flag to impose initial stess/strain + return 0; + + } + else { + + epsmax = epsy; + epsmin = -epsy; + if (deps < 0.0) { + kon = 2; + epss0 = epsmin; + sigs0 = -Fy; + epspl = epsmin; + } + else { + kon = 1; + epss0 = epsmax; + sigs0 = Fy; + epspl = epsmax; + } + } + } + + // in case of load reversal from negative to positive strain increment, + // update the minimum previous strain, store the last load reversal + // point and calculate the stress and strain (sigs0 and epss0) at the + // new intersection between elastic and strain hardening asymptote + // To include isotropic strain hardening shift the strain hardening + // asymptote by sigsft before calculating the intersection point + // Constants a3 and a4 control this stress shift on the tension side + + if (kon == 2 && deps > 0.0) { + + + kon = 1; + epsr = epsP; + sigr = sigP; + //epsmin = min(epsP, epsmin); + if (epsP < epsmin) + epsmin = epsP; + double d1 = (epsmax - epsmin) / (2.0*(a4 * epsy)); + double shft = 1.0 + a3 * pow(d1, 0.8); + epss0 = (Fy * shft - Esh * epsy * shft - sigr + E0 * epsr) / (E0 - Esh); + sigs0 = Fy * shft + Esh * (epss0 - epsy * shft); + epspl = epsmax; + + } + else if (kon == 1 && deps < 0.0) { + + // update the maximum previous strain, store the last load reversal + // point and calculate the stress and strain (sigs0 and epss0) at the + // new intersection between elastic and strain hardening asymptote + // To include isotropic strain hardening shift the strain hardening + // asymptote by sigsft before calculating the intersection point + // Constants a1 and a2 control this stress shift on compression side + + kon = 2; + epsr = epsP; + sigr = sigP; + // epsmax = max(epsP, epsmax); + if (epsP > epsmax) + epsmax = epsP; + + double d1 = (epsmax - epsmin) / (2.0*(a2 * epsy)); + double shft = 1.0 + a1 * pow(d1, 0.8); + epss0 = (-Fy * shft + Esh * epsy * shft - sigr + E0 * epsr) / (E0 - Esh); + sigs0 = -Fy * shft + Esh * (epss0 + epsy * shft); + epspl = epsmin; + } + + + // calculate current stress sig and tangent modulus E + if (kon != 4) { // non-fracture case + double xi = fabs((epspl - epss0) / epsy); + double R = R0 * (1.0 - (cR1*xi) / (cR2 + xi)); + double epsrat = (eps - epsr) / (epss0 - epsr); + double dum1 = 1.0 + pow(fabs(epsrat), R); + double dum2 = pow(dum1, (1 / R)); + + sig = b * epsrat + (1.0 - b)*epsrat / dum2; + sig = sig * (sigs0 - sigr) + sigr; + + e = b + (1.0 - b) / (dum1*dum2); + e = e * (sigs0 - sigr) / (epss0 - epsr); + + // calculate DI + calcDI(sigcr, m, sigmin, FI_lim, isStart, sig, sigPDI, DI, slopeP, sumTenP, sumCompP); + + // check if fractured + if (DI >= FI_lim) { + kon = 4; + konf = 1; + + // Point at compression yield envelope + eps_1 = (-Fy + Esh * epsy - sigP + E0 * epsP) / (E0 - Esh); + sig_1 = -Fy + Esh * (eps_1 + epsy); + + // Points at horizontal axis + eps_0 = epsP - sigP / E0; + epsCont = 2 * eps_0 - eps_1; + eps_r = epsCont; + epsr = eps_r; + sigr = 0; + + konC = 1; + + // After fracture goes to zero stress + sig = 0.0; + e = 0.0; + } + //else { + // DI = DI_cache; + //} + + } + else if (kon == 4) { // fractured case + if (eps >= epsCont) { // not contacted + sig = 0.0; + e = 0.0; + if (deps > 0) { + konf = 2; + } + else { + konf = 1; + } + konC = 0; + } + else if (eps < epsCont) { // contacted + if (!konC) { // at first contact + konC = 1; + konf = 2; + } + if (konf == 2 && deps > 0) { // compression --> tension so update variables + konf = 1; // konf = 1 means tensile now + + // Only update if it is out of the linear branch + if (sig < 0.7*sig_1) { + // New properties for unloading and reloading + eps_0 = epsP - sigP / E0; // new interception is at reversal point minus elastic unloading + sigs0 = 0; // new interception always at horizontal axis since flange fractured + + eps_1 = (-Fy + Esh * epsy + E0 * eps_0) / (E0 - Esh); // Point at compression yield envelope + sig_1 = -Fy + Esh * (eps_1 + epsy); + + eps_r = 2 * eps_0 - eps_1; // Point at zero stress and e + } + } + else if (konf == 1 && deps < 0) { // tension --> compression so update variables + konf = 2; // konf == 2 means compression now + } + + // compute sig and e + if (konf == 1) { // compute if is decompressing + // Functional form of first half of the compression load curve all the way until complete unload + double R = 14; + double epsrat = (eps - eps_1) / (eps_1 - eps_0); + double dum1 = 1.0 + pow(fabs(epsrat), R); + double dum2 = pow(dum1, (1 / R)); + + // Functional form for b = 0 since tend to zero stress + sig = sig_1 * (epsrat / dum2 + 1); + e = sig_1 / (eps_1 - eps_0) * (1 / (dum1*dum2)); + + if (eps > eps_r) { + sig = 0; + e = 0; + } + + } + else { // compute if is compressing + double R = 14; + if (eps >= (eps_0 + eps_1) / 2) { + // Update strain for zero stress and e + // Functional form of first half of the compression load curve (b = 0 since tends to horizontal axis) + double epsrat = (eps - eps_1) / (eps_1 - eps_0); + double dum1 = 1.0 + pow(fabs(epsrat), R); + double dum2 = pow(dum1, (1 / R)); + + sig = sig_1 * (epsrat / dum2 + 1); + e = sig_1 / (eps_1 - eps_0) * (1 / (dum1*dum2)); + + if (eps > eps_r) { + sig = 0; + e = 0; + } + } + else { + double epsrat = (eps - eps_0) / (eps_1 - eps_0); + double dum1 = 1.0 + pow(fabs(epsrat), R); + double dum2 = pow(dum1, (1 / R)); + + sig = b * epsrat + (1.0 - b)*epsrat / dum2; + sig = sig * sig_1; + + e = b + (1.0 - b) / (dum1*dum2); + e = e * sig_1 / (eps_1 - eps_0); + } + } + } + } + + return 0; +} + +void +SteelFractureDI::calcDI(double sigcr, double m, double sigmin, double FI_lim, int& isStart, double sig, double& sigPDI, double& DI, double& slopeP, double& sumTenP, double& sumCompP) +{ + // initialize variables **** + double slope; + double currSign; + double sumComp; + double sumTen; + + // Already fractured + if (DI > FI_lim) { + return; + } + + // if is starting point + if (isStart) { + isStart = 0; + sigPDI = sig; + return; + } + + // determine slope sign + slope = sig - sigPDI; + if (slope == 0) { + currSign = returnSign(slopeP); + } + else { + currSign = returnSign(slope); + } + + // Accumulate compressive and tensile stresses + if (fabs(sig) > sigmin) { + // Accumulate only if stress exceeds a threshold + + if (currSign == 1 && sig > sigmin) { + // Tensile excursion (only accumulates in actual tension) + sumComp = sumCompP; + sumTen = sumTenP + fabs(slope); + } + else { + // Compressive excursion + sumTen = sumTenP; + if (sumCompP + fabs(slope) < sumTen) { + // Only considers compression when there is damage to heal + sumComp = sumCompP + fabs(slope); + } + else { + sumComp = sumCompP; + } + } + } + else { + // If below threshold keep same cumulative stresses + sumComp = sumCompP; + sumTen = sumTenP; + } + + DI = (sumTen - sumComp * m) / sigcr; + + if (DI < 0) { + DI = 0; + } + + // update variables + sigPDI = sig; + slopeP = slope; + sumCompP = sumComp; + sumTenP = sumTen; +} + + +int +SteelFractureDI::returnSign(double v) { + if (v < 0) return -1; + if (v > 0) return 1; + return 0; +} + +double +SteelFractureDI::getStrain(void) +{ + return eps; +} + +double +SteelFractureDI::getStress(void) +{ + return sig; +} + +double +SteelFractureDI::getTangent(void) +{ + return e; +} + +double +SteelFractureDI::getDI(void) +{ + return DI; +} + +int +SteelFractureDI::commitState(void) +{ + epsminP = epsmin; + epsmaxP = epsmax; + epsplP = epspl; + epss0P = epss0; + sigs0P = sigs0; + epssrP = epsr; + sigsrP = sigr; + konP = kon; + + eP = e; + sigP = sig; + epsP = eps; + + // ************** added for fracture *************** + epsContP = epsCont; + eps_0P = eps_0; + eps_1P = eps_1; + eps_rP = eps_r; + konfP = konf; + konCP = konC; + // ************** added for fracture *************** + // ************** added for DI ******************** + DIP = DI; + isStartP = isStart; + sigPDIP = sigPDI; + slopePP = slopeP; + sumTenPP = sumTenP; + sumCompPP = sumCompP; + // ************** added for DI ******************** + return 0; +} + +int +SteelFractureDI::revertToLastCommit(void) +{ + epsmin = epsminP; + epsmax = epsmaxP; + epspl = epsplP; + epss0 = epss0P; + sigs0 = sigs0P; + epsr = epssrP; + sigr = sigsrP; + kon = konP; + + e = eP; + sig = sigP; + eps = epsP; + + // ************** added for fracture *************** + epsCont = epsContP; + eps_0 = eps_0P; + eps_1 = eps_0P; + eps_r = eps_rP; + konf = konfP; + konC = konCP; + // ************** added for fracture *************** + // ************** added for DI ******************** + DI = DIP; + isStart = isStartP; + sigPDI = sigPDIP; + slopeP = slopePP; + sumTenP = sumTenPP; + sumCompP = sumCompPP; + // ************** added for DI ******************** + + return 0; +} + +int +SteelFractureDI::revertToStart(void) +{ + konP = 0; + kon = 0; + eP = E0; + epsP = 0.0; + sigP = 0.0; + sig = 0.0; + eps = 0.0; + e = E0; + + epsmaxP = Fy / E0; + epsminP = -epsmaxP; + epsplP = 0.0; + epss0P = 0.0; + sigs0P = 0.0; + epssrP = 0.0; + sigsrP = 0.0; + + // ************** added for fracture *************** + epsCont = 0.0; + eps_0 = 0.0; + eps_1 = 0.0; + eps_r = 0.0; + konf = 0.0; + konC = 0.0; + + epsContP = 0.0; + eps_0P = 0.0; + eps_1P = 0.0; + eps_rP = 0.0; + konfP = 0.0; + konCP = 0.0; + // ************** added for fracture *************** + // ************** added for DI ******************** + DIP = 0.0; + isStartP = 1; + sigPDIP = 0.0; + slopePP = 0.0; + sumTenPP = 0.0; + sumCompPP = 0.0; + + DI = 0.0; + isStart = 1; + sigPDI = 0.0; + slopeP = 0.0; + sumTenP = 0.0; + sumCompP = 0.0; + // ************** added for DI ******************** + + return 0; +} + +int +SteelFractureDI::sendSelf(int commitTag, Channel &theChannel) +{ + return -1; +} + +int +SteelFractureDI::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + + return -1; +} + +void +SteelFractureDI::Print(OPS_Stream &s, int flag) +{ + if (flag == OPS_PRINT_PRINTMODEL_MATERIAL) { + // s << "Steel02:(strain, stress, tangent) " << eps << " " << sig << " " << e << endln; + s << "SteelFracture tag: " << this->getTag() << endln; + s << " fy: " << Fy << ", "; + s << " E0: " << E0 << ", "; + s << " b: " << b << ", "; + s << " R0: " << R0 << ", "; + s << " cR1: " << cR1 << ", "; + s << " cR2: " << cR2 << ", "; + s << " a1: " << a1 << ", "; + s << " a2: " << a2 << ", "; + s << " a3: " << a3 << ", "; + s << " a4: " << a4 << ", "; + s << " sigcr: " << sigcr << ", "; + s << " m: " << m << ", "; + s << " sigmin: " << sigmin << ", "; + s << " FI_lim: " << FI_lim << ", "; + } + + if (flag == OPS_PRINT_PRINTMODEL_JSON) { + s << "\t\t\t{"; + s << "\"name\": \"" << this->getTag() << "\", "; + s << "\"type\": \"SteelFracture\", "; + s << "\"E\": " << E0 << ", "; + s << "\"fy\": " << Fy << ", "; + s << "\"b\": " << b << ", "; + s << "\"R0\": " << R0 << ", "; + s << "\"cR1\": " << cR1 << ", "; + s << "\"cR2\": " << cR2 << ", "; + s << "\"a1\": " << a1 << ", "; + s << "\"a2\": " << a2 << ", "; + s << "\"a3\": " << a3 << ", "; + s << "\"a4\": " << a4 << ", "; + s << " sigcr: " << sigcr << ", "; + s << " m: " << m << ", "; + s << " sigmin: " << sigmin << ", "; + s << " FI_lim: " << FI_lim << ", "; + } +} + +Response* +SteelFractureDI::setResponse(const char **argv, int argc, OPS_Stream &theOutput) +{ + if (argc == 0) + return 0; + + Response *theResponse = 0; + + theOutput.tag("UniaxialMaterialOutput"); + theOutput.attr("matType", this->getClassType()); + theOutput.attr("matTag", this->getTag()); + + + // stress + if (strcmp(argv[0], "stress") == 0) { + theOutput.tag("ResponseType", "sigma11"); + theResponse = new MaterialResponse(this, 1, this->getStress()); + } + // tangent + else if (strcmp(argv[0], "tangent") == 0) { + theOutput.tag("ResponseType", "C11"); + theResponse = new MaterialResponse(this, 2, this->getTangent()); + } + + // strain + else if (strcmp(argv[0], "strain") == 0) { + theOutput.tag("ResponseType", "eps11"); + theResponse = new MaterialResponse(this, 3, this->getStrain()); + } + + // strain + else if ((strcmp(argv[0], "stressStrain") == 0) || + (strcmp(argv[0], "stressANDstrain") == 0)) { + theOutput.tag("ResponseType", "sig11"); + theOutput.tag("ResponseType", "eps11"); + theResponse = new MaterialResponse(this, 4, Vector(2)); + } + + // damage + else if (strcmp(argv[0], "damage") == 0) { + theResponse = new MaterialResponse(this, 5, this->getDI()); + theOutput.tag("ResponseType", "DI"); + // added 6/9/2006 + } + + else if (strcmp(argv[0], "failure") == 0) { + int res = 0; + theResponse = new MaterialResponse(this, 6, res); + theOutput.tag("ResponseType", "Failure"); + } + // end add + + + theOutput.endTag(); + return theResponse; +} + +int +SteelFractureDI::getResponse(int responseID, Information &matInfo) +{ + static Vector stressStrain(2); + static Vector cyclesAndRange(6); + + // each subclass must implement its own stuff + switch (responseID) { + case 1: + matInfo.setDouble(this->getStress()); + return 0; + + case 2: + matInfo.setDouble(this->getTangent()); + return 0; + + case 3: + matInfo.setDouble(this->getStrain()); + return 0; + + case 4: + stressStrain(0) = this->getStress(); + stressStrain(1) = this->getStrain(); + matInfo.setVector(stressStrain); + return 0; + + case 5: + matInfo.setDouble(this->getDI()); + return 0; + + case 6: + if (DI > FI_lim) + matInfo.setInt(1); + else + matInfo.setInt(0); + return 0; + + default: + return -1; + + } +} diff --git a/SRC/material/uniaxial/SteelFractureDI.h b/SRC/material/uniaxial/SteelFractureDI.h new file mode 100644 index 000000000..78faecc4c --- /dev/null +++ b/SRC/material/uniaxial/SteelFractureDI.h @@ -0,0 +1,177 @@ +/* ****************************************************************** ** +** 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: 2021-05-18 00:17:20 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/SteelFractureDI.cpp,v $ + +// Written: Francisco A. Galvis and Wen-Yi Yen +// Created: 05/2021 +// +// Description: This file contains the class implementation of SteelFractureDI. +// SteelFractureDI is based on the source code for Steel02 +// + + +#ifndef SteelFractureDI_h +#define SteelFractureDI_h + +#include +#include + +class SteelFractureDI : public UniaxialMaterial +{ +public: + SteelFractureDI(int tag, + double fy, double E0, double b, + double R0, double cR1, double cR2, + double a1, double a2, double a3, double a4, double sigcr, double m, double sigmin, double FI_lim); + /*SteelFracture(int tag, + double fy, double E0, double b);*/ + + // Constructor for no isotropic hardening + //SteelFracture(int tag, + // double fy, double E0, double b, + // double R0, double cR1, double cR2); + + //// Constructor for no isotropic hardening + //// Also provides default values for R0, cR1, and cR2 + //SteelFracture(int tag, double fy, double E0, double b); + + SteelFractureDI(void); + virtual ~SteelFractureDI(); + + + const char *getClassType(void) const { return "SteelFracture"; }; + + double getInitialTangent(void); + UniaxialMaterial *getCopy(void); + + int setTrialStrain(double strain, double strainRate = 0.0); + double getStrain(void); + double getStress(void); + double getTangent(void); + double getDI(void); + + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + + void Print(OPS_Stream &s, int flag = 0); + + // counting function + void calcDI(double sigcr, double m, double sigmin, double FI_lim, int &isStart, double sig, double &sigPDI, double &DI, double &slopeP, double& sumTenP, double& sumCompP); + int returnSign(double v); + + // override get-response function + Response *setResponse(const char **argv, int argc, OPS_Stream &s); + int getResponse(int responseID, Information &matInformation); + +protected: + +private: + // matpar : STEEL FIXED PROPERTIES + double Fy; // = matpar(1) : yield stress + double E0; // = matpar(2) : initial stiffness + double b; // = matpar(3) : hardening ratio (Esh/E0) + double R0; // = matpar(4) : exp transition elastic-plastic + double cR1; // = matpar(5) : coefficient for changing R0 to R + double cR2; // = matpar(6) : coefficient for changing R0 to R + double a1; // = matpar(7) : coefficient for isotropic hardening in compression + double a2; // = matpar(8) : coefficient for isotropic hardening in compression + double a3; // = matpar(9) : coefficient for isotropic hardening in tension + double a4; // = matpar(10) : coefficient for isotropic hardening in tension + //double sigini; // initial + // hstvP : STEEL HISTORY VARIABLES + double epsminP; // = hstvP(1) : max eps in compression + double epsmaxP; // = hstvP(2) : max eps in tension + double epsplP; // = hstvP(3) : plastic excursion + double epss0P; // = hstvP(4) : eps at asymptotes intersection + double sigs0P; // = hstvP(5) : sig at asymptotes intersection + double sig_1P; // = hstvP(5) : sig at asymptotes intersection + double epssrP; // = hstvP(6) : eps at last inversion point + double sigsrP; // = hstvP(7) : sig at last inversion point + int konP; // = hstvP(8) : index for loading/unloading + // hstv : STEEL HISTORY VARIABLES + double epsP; // = strain at previous converged step + double sigP; // = stress at previous converged step + double eP; // stiffness modulus at last converged step; + + + + double epsmin; + double epsmax; + double epspl; + double epss0; + double sigs0; + double sig_1; + double epsr; + double sigr; + int kon; + double sig; + double e; + double eps; // = strain at current step + + // ************** added for fracture *************** + double epsContP; + double eps_0P; + double eps_1P; + double eps_rP; + int konfP; + int konCP; + + double epsCont; + double eps_0; + double eps_1; + double eps_r; + int konf; + int konC; + + // ************** added for fracture *************** + // ************** added for DI ******************** + double sigcr; + double m; + double FI_lim; + double sigmin; + + double DIP; + int isStartP; + double sigPDIP; + double slopePP; + double sumTenPP; + double sumCompPP; + + double DI; + int isStart; + double sigPDI; + double slopeP; + double sumTenP; + double sumCompP; + + // ************** added for DI ******************** +}; + + +#endif + diff --git a/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp b/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp index 7546322fc..113e46856 100644 --- a/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp +++ b/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp @@ -71,7 +71,11 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp * inter #include #include -// #include // Davide Fugazza +#include // Davide Fugazza +#include +#include +#include +#include #include #include @@ -96,6 +100,7 @@ extern void *OPS_Bilin02(void); extern void *OPS_Steel01(void); extern void *OPS_FRPConfinedConcrete02(void); extern void *OPS_Steel02(void); +extern void *OPS_SteelFractureDI(void); // galvisf extern void *OPS_Steel02Fatigue(void); extern void *OPS_RambergOsgoodSteel(void); extern void *OPS_ReinforcingSteel(void); @@ -172,7 +177,12 @@ extern void *OPS_ElasticPowerFunc(void); extern void *OPS_UVCuniaxial(void); extern void *OPS_DegradingPinchedBW(void); extern void *OPS_SLModel(void); +extern void *OPS_SMAMaterial(void); extern void* OPS_HystereticPoly(void); // Salvatore Sessa 14-Jan-2021 Mail: salvatore.sessa2@unina.it +extern void *OPS_Masonry(void); +extern void *OPS_Trilinwp(void); +extern void *OPS_Trilinwp2(void); +extern void *OPS_Masonryt(void); //extern int TclCommand_ConfinedConcrete02(ClientData clientData, Tcl_Interp *interp, int argc, // TCL_Char **argv, TclModelBuilder *theTclBuilder); @@ -323,6 +333,15 @@ TclModelBuilderUniaxialMaterialCommand (ClientData clientData, Tcl_Interp *inter theMaterial = (UniaxialMaterial *)theMat; else return TCL_ERROR; + + } + else if (strcmp(argv[1], "SteelFractureDI") == 0) { + void* theMat = OPS_SteelFractureDI(); + if (theMat != 0) + theMaterial = (UniaxialMaterial*)theMat; + else + return TCL_ERROR; + } else if (strcmp(argv[1],"Steel02Fatigue") == 0) { void *theMat = OPS_Steel02Fatigue(); if (theMat != 0) @@ -815,6 +834,36 @@ TclModelBuilderUniaxialMaterialCommand (ClientData clientData, Tcl_Interp *inter else return TCL_ERROR; + } + else if (strcmp(argv[1], "Masonry") == 0) { + void *theMat = OPS_Masonry(); + if (theMat != 0) + theMaterial = (UniaxialMaterial *)theMat; + else + return TCL_ERROR; + } + else if (strcmp(argv[1], "Trilinwp") == 0) { + void *theMat = OPS_Trilinwp(); + if (theMat != 0) + theMaterial = (UniaxialMaterial *)theMat; + else + return TCL_ERROR; + } + else if (strcmp(argv[1], "Trilinwp2") == 0) { + void *theMat = OPS_Trilinwp2(); + if (theMat != 0) + theMaterial = (UniaxialMaterial *)theMat; + else + return TCL_ERROR; + } + else if (strcmp(argv[1], "Masonryt") == 0) { + void *theMat = OPS_Masonryt(); + if (theMat != 0) + theMaterial = (UniaxialMaterial *)theMat; + else + return TCL_ERROR; + + } else if (strcmp(argv[1],"Elastic2") == 0) { if (argc < 4 || argc > 5) { opserr << "WARNING invalid number of arguments\n"; @@ -2441,67 +2490,13 @@ TclModelBuilderUniaxialMaterialCommand (ClientData clientData, Tcl_Interp *inter } } - /* else if (strcmp(argv[1],"SMA") == 0) { - - if (argc < 9) { - opserr << "Warning insufficient arguments\n"; - printCommand(argc,argv); - opserr << "Want: uniaxialMaterialSMA tag E eps_L sig_AS_s sig_AS_f sig_SA_s sig_SA_f" << endln; - - return TCL_ERROR; - } - - int tag; - double E, eps_L, sig_AS_s, sig_AS_f, sig_SA_s, sig_SA_f; - - if (Tcl_GetInt(interp,argv[2], &tag) != TCL_OK){ - opserr << "warning invalid uniaxialMaterial SMA tag" << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp,argv[3], &E) != TCL_OK){ - opserr << "warning invalid E\n"; - opserr << "uniaxialMaterial SMA: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp,argv[4], &eps_L) != TCL_OK){ - opserr << "warning invalid eps_L\n"; - opserr << "uniaxialMaterial SMA: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp,argv[5], &sig_AS_s) != TCL_OK){ - opserr << "warning invalid sig_AS_s\n"; - opserr << "uniaxialMaterial SMA: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp,argv[6], &sig_AS_f) != TCL_OK){ - opserr << "warning invalid sig_AS_f\n"; - opserr << "uniaxialMaterial SMA: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp,argv[7], &sig_SA_s) != TCL_OK){ - opserr << "warning invalid sig_SA_s\n"; - opserr << "uniaxialMaterial SMA: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp,argv[8], &sig_SA_f) != TCL_OK){ - opserr << "warning invalid sig_SA_f\n"; - opserr << "uniaxialMaterial SMA: " << tag << endln; - return TCL_ERROR; - } - - // Parsing was successful, allocate the material - - theMaterial = new SMAMaterial(tag, E, eps_L, sig_AS_s, sig_AS_f, sig_SA_s, sig_SA_f); - + void *theMat = OPS_SMAMaterial(); + if (theMat != 0) + theMaterial = (UniaxialMaterial *)theMat; + else + return TCL_ERROR; } - */ else if (strcmp(argv[1],"ECC01") == 0) { if (argc < 16) { diff --git a/SRC/material/uniaxial/Trilinwp.cpp b/SRC/material/uniaxial/Trilinwp.cpp new file mode 100644 index 000000000..e9c2edeaf --- /dev/null +++ b/SRC/material/uniaxial/Trilinwp.cpp @@ -0,0 +1,938 @@ +/* ****************************************************************** ** +** 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.7 $ +// $Date: 2009/03/23 23:17:04 $ +// $Source: /usr/local/cvs/OpenSees/PACKAGES/NewMaterial/cpp/Trilinwp.cpp,v $ + +#include +#include + +#include +#include +#include +#include + + + +void* OPS_Trilinwp() +{ + // print out some KUDO's + //if (numTrilinwp == 0) { + // opserr << "Trilineal with pinching unaxial material - Written by GST UNcuyo Copyright 2017 - Use at your Own Peril\n"; + // numTrilinwp =1; + // } + + // Pointer to a uniaxial material that will be returned + //UniaxialMaterial *theMaterial = 0; + + // + // parse the input line for the material parameters + // + + int iData[2]; + double dData[19]; + int numData; + int numDatatot; + + numData = 1; + if (OPS_GetIntInput(&numData, &iData[0]) != 0) { + opserr << "WARNING invalid uniaxialMaterial Trilinwp tag" << endln; + return 0; + } + numDatatot=numData; + numData = 19; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING invalid parameters\n"; + return 0; + } + numDatatot=numDatatot+numData; + numData = 1; + if (OPS_GetIntInput(&numData, &iData[1]) != 0) { + opserr << "WARNING invalid uniaxialMaterial Trilinwp type" << endln; + return 0; + } + + numDatatot=numDatatot+numData; + if (numDatatot != 21 ) { + opserr << "Invalid Args want: uniaxialMaterial Trilinwp tag? Fcrp? dcrp? Fyp? dyp? Fup? dup? Fcrn? dcrn? Fyn? dyn? Fun? dun? px? py? d1? d2? beta? Pt? Pb? itype? "; + return 0; + } + + int itype=iData[1]; + + // + // create a new material + // + + UniaxialMaterial* mat= new Trilinwp(iData[0], dData[0], 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], iData[1]); + + + if (mat == 0) { + opserr << "WARNING could not create uniaxialMaterial of type Trilinwp\n"; + return 0; + } + + // return the material + return mat; +} + + + + +Trilinwp::Trilinwp(int tag, + double m1p, double r1p, double m2p, double r2p, double m3p, double r3p, + double m1n, double r1n, double m2n, double r2n, double m3n, double r3n, + double px, double py, double d1, double d2, double b, double ptn, double pbn, int it) : + UniaxialMaterial(tag, MAT_TAG_Trilinwp), + pinchX(px), pinchY(py), damfc1(d1), damfc2(d2), beta(b), + mom1p(m1p), rot1p(r1p), mom2p(m2p), rot2p(r2p), mom3p(m3p), rot3p(r3p), + mom1n(m1n), rot1n(r1n), mom2n(m2n), rot2n(r2n), mom3n(m3n), rot3n(r3n), pt(ptn), pb(pbn), itype(it) +{ + bool error = false; + // Positive backbone parameters + if (rot1p <= 0.0) + error = true; + + if (rot2p <= rot1p) + error = true; + + if (rot3p <= rot2p) + error = true; + + // Negative backbone parameters + if (rot1n >= 0.0) + error = true; + + if (rot2n >= rot1n) + error = true; + + if (rot3n >= rot2n) + error = true; + + if (error) { + opserr << "Trilinwp::Trilinwp -- input backbone is not unique (one-to-one)\n"; + exit(-1); + } + mom1pi=mom1p; + mom2pi=mom2p; + mom3pi=mom3p; + mom1ni=mom1n; + mom2ni=mom2n; + mom3ni=mom3n; + rot1pi = rot1p; + rot2pi = rot2p; + rot3pi = rot3p; + energyA = 0.5 * (rot1p*mom1p + (rot2p-rot1p)*(mom2p+mom1p) + (rot3p-rot2p)*(mom3p+mom2p) + + rot1n*mom1n + (rot2n-rot1n)*(mom2n+mom1n) + (rot3n-rot2n)*(mom3n+mom2n)); + + // Set envelope slopes + this->setEnvelope(); + + // Initialize history variables + this->revertToStart(); + this->revertToLastCommit(); + +} + + + +Trilinwp::Trilinwp(): +UniaxialMaterial(0, MAT_TAG_Trilinwp), +pinchX(0.0), pinchY(0.0), damfc1(0.0), damfc2(0.0), beta(0.0), +mom1p(0.0), rot1p(0.0), mom2p(0.0), rot2p(0.0), mom3p(0.0), rot3p(0.0), +mom1n(0.0), rot1n(0.0), mom2n(0.0), rot2n(0.0), mom3n(0.0), rot3n(0.0), pt(0.0), pb(0.0),itype(0) +{ + +} + +Trilinwp::~Trilinwp() +{ + // Nothing to do +} + +int +Trilinwp::setTrialStrain(double strain, double strainRate) +{ + +if (TloadIndicator == 0 && strain == 0.0) + return 0; + +double N=strainRate; //Fuerza axial >0= traccion +//opserr << "N= "<< N< 0) { + double duct = duct0; + } + else if (N < 0 && N > pb) { + double duct = (1.0 - duct0) * N / pb + duct0; + } + else if (N < pb) { + double duct = 1.1; + } + else { + double duct = duct0; + } + if (N > 0 && N < pt) { + mom3p = mom3pi * (1 - (N * N / (pb * pb)) - N / (1.2 * pt)); + mom3p = (mom3p < 0) ? 0 : mom3p; + mom3p = (mom3p > mom3pi) ? mom3pi : mom3p; + mom2p = mom2pi * (1 - (N * N / (pb * pb)) - N / (1.2 * pt)); + mom2p = (mom2p < 0) ? 0 : mom2p; + mom2p = (mom2p > mom2pi) ? mom2pi : mom2p; + mom1p = mom2p / 10; + rot1p = mom1p / stiff1; + rot2p = rot2pi; + rot1p = (rot1p > rot2p) ? 0.9 * rot2p : rot1p; + rot3p = duct * rot2p; + } + else if (N > pt) { + mom1p = mom1pi / 100.0; + mom1n = mom1ni / 100.0; + mom2p = mom2pi / 100.0; + mom2n = mom2ni / 100.0; + mom3p = mom3pi / 100.0; + mom3n = mom3ni / 100.0; + } + else if (N<0 && N>pb / 3) { + mom3p = mom3pi * (1 - (N * N / (pb * pb)) - N / (1.2 * pt)); + mom3p = (mom3p < 0) ? 0 : mom3p; + mom2p = mom2pi * (1 - (N * N / (pb * pb)) - N / (1.2 * pt)); + mom2p = (mom2p < 0) ? 0 : mom2p; + mom1p = mom1pi * (1 - (N * N / (pb * pb)) - N / (1.2 * pt)); + mom1p = (mom1p < 0) ? 0 : mom1p; + rot1p = mom1p / stiff1; + if (rot1p > rot2pi) { + rot1p = 0.9 * rot2pi; + } + rot2p = rot2pi; + rot3p = rot2p * duct; + } + else if (N <= pb / 3 && N > pb / 2) { + mom3p = mom3pi * (1 - (N * N / (pb * pb)) - N / (1.2 * pt)); + mom3p = (mom3p < 0) ? 0 : mom3p; + mom2p = mom2pi * mom3p / mom3pi; + mom1p = 0.9 * mom2p; + rot1p = mom1p / stiff1; + rot2p = rot2pi; + if (rot1p > rot2pi) { + rot1p = 0.9 * rot2pi; + } + rot3p = rot2p * duct; + } + else if (N <= pb / 2 && N > pb) { + mom3p = mom3pi * (1 - (N * N / (pb * pb)) - N / (1.2 * pt)); + mom3p = (mom3p < 0) ? 0 : mom3p; + mom3p = (mom3p < 0) ? -1.0 * mom3p : mom3p; + mom2p = 0.95 * mom3p; + mom1p = 0.95 * mom2p; + rot1p = mom1p / stiff1; + if (rot1p > rot2pi) { + rot1p = 0.9 * rot2pi; + } + rot2p = rot2pi; + rot3p = duct * rot2p; + } + else if (N <= pb) { + mom3p = mom3pi * (1 - (N * N / (pb * pb)) - N / (1.2 * pt)); + mom3p = (mom3p < 0) ? 0 : mom3p; + mom2p = 0.95 * mom3p; + mom1p = 0.95 * mom2p; + rot1p = 0.95 * rot2pi; + rot2p = rot2pi; + rot3p = duct * rot2p; + } + else { + mom1p = mom1pi; + mom1n = mom1ni; + mom2p = mom2pi; + mom2n = mom2ni; + mom3p = mom3pi; + mom3n = mom3ni; + } + mom1n = -1.0 * mom1p; + mom2n = -1.0 * mom2p; + mom3n = -1.0 * mom3p; + rot1n = -1.0 * rot1p; + rot2n = -1.0 * rot2p; + rot3n = -1.0 * rot3p; + +} +else if (itype == 2) { + double ksp = mom2pi / (rot2pi - rot1pi); + if (N > 0 && N < pt) { + double expo = 2.5; + mom1p = mom1pi * (1.0 - pow(N / pt, expo)); + mom1n = mom1ni * (1.0 - pow(N / pt, expo)); + mom2p = mom2pi * (1.0 - pow(N / pt, expo)); + mom2n = mom2ni * (1.0 - pow(N / pt, expo)); + mom3p = mom3pi * (1.0 - pow(N / pt, expo)); + mom3n = mom3ni * (1.0 - pow(N / pt, expo)); + } + else if (N > pt) { + mom1p = mom1pi / 100.0; + mom1n = mom1ni / 100.0; + mom2p = mom2pi / 100.0; + mom2n = mom2ni / 100.0; + mom3p = mom3pi / 100.0; + mom3n = mom3ni / 100.0; + + } + else if (N<0 && N>pb) { + mom1p = mom1pi * (1.0 + pow(N / pb, 2)); + mom1n = mom1ni * (1.0 + pow(N / pb, 2)); + mom2p = mom2pi * (1.0 + pow(N / pb, 2)); + mom2n = mom2ni * (1.0 + pow(N / pb, 2)); + mom3p = mom3pi * (1.0 + pow(N / pb, 2)); + mom3n = mom3ni * (1.0 + pow(N / pb, 2)); + } + else if (N < 0 && N < pb) { + mom1p = mom1pi * (1.0 + pow(N / pb, 2)); + mom1n = mom1ni * (1.0 + pow(N / pb, 2)); + mom2p = mom2pi * (1.0 + pow(N / pb, 2)); + mom2n = mom2ni * (1.0 + pow(N / pb, 2)); + mom3p = mom3pi * (1.0 + pow(N / pb, 2)); + mom3n = mom3ni * (1.0 + pow(N / pb, 2)); + } + else { + mom1p = mom1pi; + mom1n = mom1ni; + mom2p = mom2pi; + mom2n = mom2ni; + mom3p = mom3pi; + mom3n = mom3ni; + } + rot2p = (mom2p / ksp) * (1 - 1.4 * N / pb) + rot1p; + rot2n = (mom2n / ksp) * (1 - 1.4 * N / pb) + rot1n; + rot3p = 2 * rot2p; + rot3n = 2 * rot2n; +} +else { + mom1p = mom1pi; + mom1n = mom1ni; + mom2p = mom2pi; + mom2n = mom2ni; + mom3p = mom3pi; + mom3n = mom3ni; +} +this->setEnvelope(); +TrotMax = CrotMax; +TrotMin = CrotMin; +TenergyD = CenergyD; +TrotPu = CrotPu; +TrotNu = CrotNu; + +Tstrain = strain; +double dStrain = Tstrain - Cstrain; + +if (fabs(dStrain) < DBL_EPSILON) + return 0; + +TloadIndicator = CloadIndicator; + +if (TloadIndicator == 0) +TloadIndicator = (dStrain < 0.0) ? 2 : 1; + +if (Tstrain >= CrotMax) { + TrotMax = Tstrain; + Ttangent = posEnvlpTangent(Tstrain); + Tstress = posEnvlpStress(Tstrain); + TloadIndicator = 1; +} +else if (Tstrain <= CrotMin) { + TrotMin = Tstrain; + Ttangent = negEnvlpTangent(Tstrain); + Tstress = negEnvlpStress(Tstrain); + TloadIndicator = 2; +} +else { + if (dStrain < 0.0) + negativeIncrement(dStrain); + else if (dStrain > 0.0) + positiveIncrement(dStrain); +} + +TenergyD = CenergyD + 0.5*(Cstress + Tstress)*dStrain; + + +// if (this->getTag() == 40) +// opserr << "setTrial: " << Tstrain << " " << Ttangent << " " << Tstress << endln; + +return 0; +} + + + +double +Trilinwp::getStrain(void) +{ + return Tstrain; +} + +double +Trilinwp::getStress(void) +{ + return Tstress; +} + + +double +Trilinwp::getTangent(void) +{ + return Ttangent; +} + +void +Trilinwp::positiveIncrement(double dStrain) +{ + double kn = pow(CrotMin / rot1n, beta); + kn = (kn < 1.0) ? 1.0 : 1.0 / kn; + double kp = pow(CrotMax / rot1p, beta); + kp = (kp < 1.0) ? 1.0 : 1.0 / kp; + + if (TloadIndicator == 2) { + TloadIndicator = 1; + if (Cstress <= 0.0) { + TrotNu = Cstrain - Cstress / (Eun*kn); + double energy = CenergyD - 0.5*Cstress / (Eun*kn)*Cstress; + double damfc = 0.0; + if (CrotMin < rot1n) { + damfc = damfc2*energy / energyA; + damfc += damfc1*(CrotMin - rot1n) / rot1n; + } + + TrotMax = CrotMax*(1.0 + damfc); + } + } + + TloadIndicator = 1; + + if (TrotMax > POS_INF_STRAIN) + TrotMax = POS_INF_STRAIN; + + TrotMax = (TrotMax > rot1p) ? TrotMax : rot1p; + + double maxmom = posEnvlpStress(TrotMax); + double rotlim = negEnvlpRotlim(CrotMin); + double rotrel = (rotlim > TrotNu) ? rotlim : TrotNu; + + // rotrel = TrotNu; + // if (negEnvlpStress(CrotMin) >= 0.0) + // rotrel = rotlim; + + // double rotmp1 = rotrel + pinchY*(TrotMax-rotrel); + + double rotmp2 = TrotMax - (1.0 - pinchY)*maxmom / (Eup*kp); + //double rotmp2 = TrotMax-(1-pinchY)*maxmom/Eup; + // double rotch = rotmp1 + (rotmp2-rotmp1)*pinchX; + double rotch = rotrel + (rotmp2 - rotrel)*pinchX; // changed on 7/11/2006 + + double tmpmo1; + double tmpmo2; + + if (Tstrain < TrotNu) { + Ttangent = Eun*kn; + Tstress = Cstress + Ttangent*dStrain; + if (Tstress >= 0.0) { + Tstress = 0.0; + Ttangent = Eun*1.0e-9; + } + } + + else if (Tstrain >= TrotNu && Tstrain < rotch) { + if (Tstrain <= rotrel) { + Tstress = 0.0; + Ttangent = Eup*1.0e-9; + } + else { + Ttangent = maxmom*pinchY / (rotch - rotrel); + tmpmo1 = Cstress + Eup*kp*dStrain; + tmpmo2 = (Tstrain - rotrel)*Ttangent; + if (tmpmo1 < tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eup*kp; + } + else + Tstress = tmpmo2; + } + } + + else { + Ttangent = (1.0 - pinchY)*maxmom / (TrotMax - rotch); + tmpmo1 = Cstress + Eup*kp*dStrain; + tmpmo2 = pinchY*maxmom + (Tstrain - rotch)*Ttangent; + if (tmpmo1 < tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eup*kp; + } + else + Tstress = tmpmo2; + } +} + +void +Trilinwp::negativeIncrement(double dStrain) +{ + double kn = pow(CrotMin / rot1n, beta); + kn = (kn < 1.0) ? 1.0 : 1.0 / kn; + double kp = pow(CrotMax / rot1p, beta); + kp = (kp < 1.0) ? 1.0 : 1.0 / kp; + + if (TloadIndicator == 1) { + TloadIndicator = 2; + if (Cstress >= 0.0) { + TrotPu = Cstrain - Cstress / (Eup*kp); + double energy = CenergyD - 0.5*Cstress / (Eup*kp)*Cstress; + double damfc = 0.0; + if (CrotMax > rot1p) { + damfc = damfc2*energy / energyA; + damfc += damfc1*(CrotMax - rot1p) / rot1p; + } + + TrotMin = CrotMin*(1.0 + damfc); + } + } + + TloadIndicator = 2; + + if (TrotMin < NEG_INF_STRAIN) + TrotMin = NEG_INF_STRAIN; + + TrotMin = (TrotMin < rot1n) ? TrotMin : rot1n; + + double minmom = negEnvlpStress(TrotMin); + double rotlim = posEnvlpRotlim(CrotMax); + double rotrel = (rotlim < TrotPu) ? rotlim : TrotPu; + + //rotrel = TrotPu; + //if (posEnvlpStress(CrotMax) <= 0.0) + // rotrel = rotlim; + + //double rotmp1 = rotrel + pinchY*(TrotMin-rotrel); + double rotmp2 = TrotMin - (1.0 - pinchY)*minmom / (Eun*kn); + //double rotmp2 = TrotMin-(1-pinchY)*minmom/Eun; + //double rotch = rotmp1 + (rotmp2-rotmp1)*pinchX; + double rotch = rotrel + (rotmp2 - rotrel)*pinchX; // changed on 7/11/2006 + + double tmpmo1; + double tmpmo2; + + if (Tstrain > TrotPu) { + Ttangent = Eup*kp; + Tstress = Cstress + Ttangent*dStrain; + if (Tstress <= 0.0) { + Tstress = 0.0; + Ttangent = Eup*1.0e-9; + } + } + + else if (Tstrain <= TrotPu && Tstrain > rotch) { + if (Tstrain >= rotrel) { + Tstress = 0.0; + Ttangent = Eun*1.0e-9; + } + else { + Ttangent = minmom*pinchY / (rotch - rotrel); + tmpmo1 = Cstress + Eun*kn*dStrain; + tmpmo2 = (Tstrain - rotrel)*Ttangent; + if (tmpmo1 > tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eun*kn; + } + else + Tstress = tmpmo2; + } + } + + else { + Ttangent = (1.0 - pinchY)*minmom / (TrotMin - rotch); + tmpmo1 = Cstress + Eun*kn*dStrain; + tmpmo2 = pinchY*minmom + (Tstrain - rotch)*Ttangent; + if (tmpmo1 > tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eun*kn; + } + else + Tstress = tmpmo2; + } +} + +int +Trilinwp::commitState(void) +{ + CrotMax = TrotMax; + CrotMin = TrotMin; + CrotPu = TrotPu; + CrotNu = TrotNu; + CenergyD = TenergyD; + CloadIndicator = TloadIndicator; + + Cstress = Tstress; + Cstrain = Tstrain; + return 0; +} + + +int +Trilinwp::revertToLastCommit(void) +{ + TrotMax = CrotMax; + TrotMin = CrotMin; + TrotPu = CrotPu; + TrotNu = CrotNu; + TenergyD = CenergyD; + TloadIndicator = CloadIndicator; + + Tstress = Cstress; + Tstrain = Cstrain; + + return 0; +} + + +int +Trilinwp::revertToStart(void) +{ + CrotMax = 0.0; + CrotMin = 0.0; + CrotPu = 0.0; + CrotNu = 0.0; + CenergyD = 0.0; + CloadIndicator = 0; + + Cstress = 0.0; + Cstrain = 0.0; + + Tstrain = 0; + Tstress = 0; + Ttangent = E1p; + + mom1pi=mom1p; + mom2pi=mom2p; + mom3pi=mom3p; + mom1ni=mom1n; + mom2ni=mom2n; + mom3ni=mom3n; + return 0; +} + + +UniaxialMaterial* +Trilinwp::getCopy(void) +{ + Trilinwp *theCopy = new Trilinwp (this->getTag(), + mom1p, rot1p, mom2p, rot2p, mom3p, rot3p, + mom1n, rot1n, mom2n, rot2n, mom3n, rot3n, + pinchX, pinchY, damfc1, damfc2, beta,pt,pb, itype); + + theCopy->CrotMax = CrotMax; + theCopy->CrotMin = CrotMin; + theCopy->CrotPu = CrotPu; + theCopy->CrotNu = CrotNu; + theCopy->CenergyD = CenergyD; + theCopy->CloadIndicator = CloadIndicator; + theCopy->Cstress = Cstress; + theCopy->Cstrain = Cstrain; + theCopy->Ttangent = Ttangent; + + return theCopy; +} +int +Trilinwp::sendSelf(int commitTag, Channel &theChannel) +{ + int res = 0; + + static Vector data(30); + + data(0) = this->getTag(); + data(1) = mom1p; + data(2) = rot1p; + data(3) = mom2p; + data(4) = rot2p; + data(5) = mom3p; + data(6) = rot3p; + data(7) = mom1n; + data(8) = rot1n; + data(9) = mom2n; + data(10) = rot2n; + data(11) = mom3n; + data(12) = rot3n; + data(13) = pinchX; + data(14) = pinchY; + data(15) = damfc1; + data(16) = damfc2; + data(17) = beta; + data(18) = CrotMax; + data(19) = CrotMin; + data(20) = CrotPu; + data(21) = CrotNu; + data(22) = CenergyD; + data(23) = CloadIndicator; + data(24) = Cstress; + data(25) = Cstrain; + data(26) = Ttangent; + data(27) = pt; + data(28) = pb; + data(29)=itype; + + res = theChannel.sendVector(this->getDbTag(), commitTag, data); + if (res < 0) + opserr << "Trilinwp::sendSelf() - failed to send data\n"; + + + return res; +} + +int +Trilinwp::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + + static Vector data(30); + res = theChannel.recvVector(this->getDbTag(), commitTag, data); + + if (res < 0) { + opserr << "Trilinwp::recvSelf() - failed to receive data\n"; + return res; + } + else { + this->setTag((int)data(0)); + mom1p = data(1); + rot1p = data(2); + mom2p = data(3); + rot2p = data(4); + mom3p = data(5); + rot3p = data(6); + mom1n = data(7); + rot1n = data(8); + mom2n = data(9); + rot2n = data(10); + mom3n = data(11); + rot3n = data(12); + pinchX = data(13); + pinchY = data(14); + damfc1 = data(15); + damfc2 = data(16); + beta = data(17); + + CrotMax = data(18); + CrotMin = data(19); + CrotPu = data(20); + CrotNu = data(21); + CenergyD = data(22); + CloadIndicator = int(data(23)); + Cstress = data(24); + Cstrain = data(25); + Ttangent = data(26); + pt = data(27); + pb = data(28); + itype=data(29); + // set the trial values + TrotMax = CrotMax; + TrotMin = CrotMin; + TrotPu = CrotPu; + TrotNu = CrotNu; + TenergyD = CenergyD; + TloadIndicator = CloadIndicator; + Tstress = Cstress; + Tstrain = Cstrain; + } + + // Set envelope slopes + this->setEnvelope(); + + return 0; +} + +void +Trilinwp::Print(OPS_Stream &s, int flag) +{ + s << "Trilineal with pinching material - GST(2017), tag: " << this->getTag() << endln; + s << "mom1p: " << mom1p << endln; + s << "rot1p: " << rot1p << endln; + s << "E1p: " << E1p << endln; + s << "mom2p: " << mom2p << endln; + s << "rot2p: " << rot2p << endln; + s << "E2p: " << E2p << endln; + s << "mom3p: " << mom3p << endln; + s << "rot3p: " << rot3p << endln; + s << "E3p: " << E3p << endln; + + s << "mom1n: " << mom1n << endln; + s << "rot1n: " << rot1n << endln; + s << "E1n: " << E1n << endln; + s << "mom2n: " << mom2n << endln; + s << "rot2n: " << rot2n << endln; + s << "E2n: " << E2n << endln; + s << "mom3n: " << mom3n << endln; + s << "rot3n: " << rot3n << endln; + s << "E3n: " << E3n << endln; + + s << "pinchX: " << pinchX << endln; + s << "pinchY: " << pinchY << endln; + s << "damfc1: " << damfc1 << endln; + s << "damfc2: " << damfc2 << endln; + s << "energyA: " << energyA << endln; + s << "beta: " << beta << endln; + s << "Pt: " << pt << endln; + s << "Pb: " << pb << endln; + s << "itype "<< itype<< endln; + if(itype==1){ + s << "Type: Flexure" << endln; + } + else if(itype==2){ + s << "Type: Shear" << endln; + } + else { + s << "Shear and flexure with no Axial Interaction" << endln; + } +} + +void +Trilinwp::setEnvelope(void) +{ + E1p = mom1p/rot1p; + E2p = (mom2p-mom1p)/(rot2p-rot1p); + E3p = (mom3p-mom2p)/(rot3p-rot2p); + + E1n = mom1n/rot1n; + E2n = (mom2n-mom1n)/(rot2n-rot1n); + E3n = (mom3n-mom2n)/(rot3n-rot2n); + + Eup = E1p; + if (E2p > Eup) Eup = E2p; + if (E3p > Eup) Eup = E3p; + + Eun = E1n; + if (E2n > Eun) Eun = E2n; + if (E3n > Eun) Eun = E3n; + + +} + +double +Trilinwp::posEnvlpStress(double strain) +{ + if (strain <= 0.0) + return 0.0; + else if (strain <= rot1p) + return E1p*strain; + else if (strain <= rot2p) + return mom1p + E2p*(strain-rot1p); + else if (strain <= rot3p || E3p > 0.0) + return mom2p + E3p*(strain-rot2p); + else + return mom3p; +} + +double +Trilinwp::negEnvlpStress(double strain) +{ + if (strain >= 0.0) + return 0.0; + else if (strain >= rot1n) + return E1n*strain; + else if (strain >= rot2n) + return mom1n + E2n*(strain-rot1n); + else if (strain >= rot3n || E3n > 0.0) + return mom2n + E3n*(strain-rot2n); + else + return mom3n; +} + +double +Trilinwp::posEnvlpTangent(double strain) +{ + if (strain < 0.0) + return E1p*1.0e-9; + else if (strain <= rot1p) + return E1p; + else if (strain <= rot2p) + return E2p; + else if (strain <= rot3p || E3p > 0.0) + return E3p; + else + return E1p*1.0e-9; +} + +double +Trilinwp::negEnvlpTangent(double strain) +{ + if (strain > 0.0) + return E1n*1.0e-9; + else if (strain >= rot1n) + return E1n; + else if (strain >= rot2n) + return E2n; + else if (strain >= rot3n || E3n > 0.0) + return E3n; + else + return E1n*1.0e-9; +} + +double +Trilinwp::posEnvlpRotlim(double strain) +{ + double strainLimit = POS_INF_STRAIN; + + if (strain <= rot1p) + return POS_INF_STRAIN; + if (strain > rot1p && strain <= rot2p && E2p < 0.0) + strainLimit = rot1p - mom1p/E2p; + if (strain > rot2p && E3p < 0.0) + strainLimit = rot2p - mom2p/E3p; + + if (strainLimit == POS_INF_STRAIN) + return POS_INF_STRAIN; + else if (posEnvlpStress(strainLimit) > 0) + return POS_INF_STRAIN; + else + return strainLimit; +} + +double +Trilinwp::negEnvlpRotlim(double strain) +{ + double strainLimit = NEG_INF_STRAIN; + + if (strain >= rot1n) + return NEG_INF_STRAIN; + if (strain < rot1n && strain >= rot2n && E2n < 0.0) + strainLimit = rot1n - mom1n/E2n; + if (strain < rot2n && E3n < 0.0) + strainLimit = rot2n - mom2n/E3n; + + if (strainLimit == NEG_INF_STRAIN) + return NEG_INF_STRAIN; + else if (negEnvlpStress(strainLimit) < 0) + return NEG_INF_STRAIN; + else + return strainLimit; +} diff --git a/SRC/material/uniaxial/Trilinwp.h b/SRC/material/uniaxial/Trilinwp.h new file mode 100644 index 000000000..4d56a2093 --- /dev/null +++ b/SRC/material/uniaxial/Trilinwp.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) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.8 $ +// $Date: 2008-12-18 23:40:51 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/Trilinwp.h,v $ + +#ifndef Trilinwp_h +#define Trilinwp_h + +#include + +class Trilinwp : public UniaxialMaterial +{ + public: + Trilinwp(int tag, + double mom1p, double rot1p, double mom2p, double rot2p, + double mom3p, double rot3p, + double mom1n, double rot1n, double mom2n, double rot2n, + double mom3n, double rot3n, + double pinchX, double pinchY, + double damfc1 = 0.0, double damfc2 = 0.0, + double beta = 0.0, + double pt= 0.0, double pb= 0.0, int itype=0); + Trilinwp(); + ~Trilinwp(); + + const char *getClassType(void) const {return "Trilinwp";}; + + int setTrialStrain(double strain, double strainRate =0.0 ); + double getStrain(void); + double getStress(void); + double getTangent(void); + double getInitialTangent(void) {return E1p;}; + + 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: + // Pinching parameters + double pinchX; // Deformation pinching + double pinchY; // Force pinching + + // Damage parameters + double damfc1; // Deformation + double damfc2; // Energy + + // Unloading parameter + double beta; + + // Trial history variables + double TrotMax; + double TrotMin; + double TrotPu; + double TrotNu; + double TenergyD; + int TloadIndicator; + + // Trial state variables + double Ttangent; + double Tstress; + double Tstrain; + + // Converged history variables + double CrotMax; + double CrotMin; + double CrotPu; + double CrotNu; + double CenergyD; + int CloadIndicator; + + // Converged state variables + double Cstress; + double Cstrain; + + // Backbone parameters + double mom1p, rot1p; + double mom2p, rot2p; + double mom3p, rot3p; + double mom1n, rot1n; + double mom2n, rot2n; + double mom3n, rot3n; + + double E1p, E1n; + double E2p, E2n; + double E3p, E3n; + double Eup, Eun; + + double energyA; + double pt; + double pb; + double mom1pi,mom2pi,mom3pi; + double mom1ni, mom2ni, mom3ni; + double rot1pi, rot2pi, rot3pi; + int itype; + double duct; + + void setEnvelope(void); + + double posEnvlpStress(double strain); + double negEnvlpStress(double strain); + + double posEnvlpTangent(double strain); + double negEnvlpTangent(double strain); + + double posEnvlpRotlim(double strain); + double negEnvlpRotlim(double strain); + + void positiveIncrement(double dStrain); + void negativeIncrement(double dStrain); +}; + +#endif diff --git a/SRC/material/uniaxial/Trilinwp2.cpp b/SRC/material/uniaxial/Trilinwp2.cpp new file mode 100644 index 000000000..615120f96 --- /dev/null +++ b/SRC/material/uniaxial/Trilinwp2.cpp @@ -0,0 +1,967 @@ +/* ****************************************************************** ** +** 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.7 $ +// $Date: 2009/03/23 23:17:04 $ +// $Source: /usr/local/cvs/OpenSees/PACKAGES/NewMaterial/cpp/Trilinwp.cpp,v $ + +#include +#include + +#include +#include +#include +#include + + +void* OPS_Trilinwp2() +{ + // print out some KUDO's + // if (numTrilinwp == 0) { + // opserr << "Trilineal with pinching unaxial material - Written by GST UNcuyo Copyright 2017 - Use at your Own Peril\n"; + // numTrilinwp =1; + //} + + // Pointer to a uniaxial material that will be returned + // UniaxialMaterial *theMaterial = 0; + + // + // parse the input line for the material parameters + // + + int iData[2]; + double dData[15]; + int numData; + int numDatatot; + + numData = 1; + if (OPS_GetIntInput(&numData, &iData[0]) != 0) { + opserr << "WARNING invalid uniaxialMaterial Trilinwp2 tag" << endln; + return 0; + } + numDatatot=numData; + + numData = 15; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING invalid parameters\n"; + return 0; + } + numDatatot=numDatatot+numData; + numData = 1; + if (OPS_GetIntInput(&numData, &iData[1]) != 0) { + opserr << "WARNING invalid uniaxialMaterial Trilinwp2 type" << endln; + return 0; + } + numDatatot=numDatatot+numData; + if (numDatatot != 17 ) { + opserr << "Invalid Args want: uniaxialMaterial Trilinwp2 tag? Fcrp? dcrp? Fyp? dyp? Fup? dup? px? py? d1? d2? beta? Pt? Pb? Pc? Mb? itype? "; + return 0; + } + + + int itype=iData[1]; + + // + // create a new material + // + + UniaxialMaterial* mat = new Trilinwp2(iData[0], dData[0], 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], iData[1]); + + + if (mat == 0) { + opserr << "WARNING could not create uniaxialMaterial of type Trilinwp2\n"; + return 0; + } + + // return the material + return mat; +} + + + + +Trilinwp2::Trilinwp2(int tag, + double m1p, double r1p, double m2p, double r2p, double m3p, double r3p, + double px, double py, double d1, double d2, double b, double ptn, double pbn,double pcn, double mbn, int it): +UniaxialMaterial(tag, MAT_TAG_Trilinwp2), +pinchX(px), pinchY(py), damfc1(d1), damfc2(d2), beta(b), +mom1p(m1p), rot1p(r1p), mom2p(m2p), rot2p(r2p), mom3p(m3p), rot3p(r3p),pt(ptn), pb(pbn),pc(pcn),mb(mbn),itype(it) +{ + bool error = false; + // Positive backbone parameters + if (rot1p <= 0.0) + error = true; + + if (rot2p <= rot1p) + error = true; + + if (rot3p <= rot2p) + error = true; + + rot1n=-1.0*rot1p; + rot2n=-1.0*rot2p; + rot3n=-1.0*rot3p; + mom1n=-1.0*mom1p; + mom2n=-1.0*mom2p; + mom3n=-1.0*mom3p; + + // Negative backbone parameters + if (rot1n >= 0.0) + error = true; + + if (rot2n >= rot1n) + error = true; + + if (rot3n >= rot2n) + error = true; + + if (error) { + opserr << "Trilinwp2::Trilinwp2 -- input backbone is not unique (one-to-one)\n"; + exit(-1); + } + + mom1pi=mom1p; + mom2pi=mom2p; + mom3pi=mom3p; + mom1ni=mom1n; + mom2ni=mom2n; + mom3ni=mom3n; + rot1pi=rot1p; + rot2pi=rot2p; + rot3pi=rot3p; + + energyA = 0.5 * (rot1p*mom1p + (rot2p-rot1p)*(mom2p+mom1p) + (rot3p-rot2p)*(mom3p+mom2p) + + rot1n*mom1n + (rot2n-rot1n)*(mom2n+mom1n) + (rot3n-rot2n)*(mom3n+mom2n)); + + // Set envelope slopes + this->setEnvelope(); + + // Initialize history variables + this->revertToStart(); + this->revertToLastCommit(); + +} + + + +Trilinwp2::Trilinwp2(): +UniaxialMaterial(0, MAT_TAG_Trilinwp2), +pinchX(0.0), pinchY(0.0), damfc1(0.0), damfc2(0.0), beta(0.0), +mom1p(0.0), rot1p(0.0), mom2p(0.0), rot2p(0.0), mom3p(0.0), rot3p(0.0), +pt(0.0), pb(0.0),pc(0.0),mb(0.0),itype(0) +{ + +} + +Trilinwp2::~Trilinwp2() +{ + // Nothing to do +} + +int +Trilinwp2::setTrialStrain(double strain, double strainRate) +{ + +// opserr<<"m1p= "< rot1p) ? TrotMax : rot1p; + + double maxmom = posEnvlpStress(TrotMax); + double rotlim = negEnvlpRotlim(CrotMin); + double rotrel = (rotlim > TrotNu) ? rotlim : TrotNu; + + // rotrel = TrotNu; + // if (negEnvlpStress(CrotMin) >= 0.0) + // rotrel = rotlim; + + // double rotmp1 = rotrel + pinchY*(TrotMax-rotrel); + + double rotmp2 = TrotMax - (1.0-pinchY)*maxmom/(Eup*kp); + //double rotmp2 = TrotMax-(1-pinchY)*maxmom/Eup; + // double rotch = rotmp1 + (rotmp2-rotmp1)*pinchX; + double rotch = rotrel + (rotmp2-rotrel)*pinchX; // changed on 7/11/2006 + + double tmpmo1; + double tmpmo2; + + if (Tstrain < TrotNu) { + Ttangent = Eun*kn; + Tstress = Cstress + Ttangent*dStrain; + if (Tstress >= 0.0) { + Tstress = 0.0; + Ttangent = Eun*1.0e-9; + } + } + + else if (Tstrain >= TrotNu && Tstrain < rotch) { + if (Tstrain <= rotrel) { + Tstress = 0.0; + Ttangent = Eup*1.0e-9; + } + else { + Ttangent = maxmom*pinchY/(rotch-rotrel); + tmpmo1 = Cstress + Eup*kp*dStrain; + tmpmo2 = (Tstrain-rotrel)*Ttangent; + if (tmpmo1 < tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eup*kp; + } + else + Tstress = tmpmo2; + } + } + + else { + Ttangent = (1.0-pinchY)*maxmom/(TrotMax-rotch); + tmpmo1 = Cstress + Eup*kp*dStrain; + tmpmo2 = pinchY*maxmom + (Tstrain-rotch)*Ttangent; + if (tmpmo1 < tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eup*kp; + } + else + Tstress = tmpmo2; + } +} + +void +Trilinwp2::negativeIncrement(double dStrain) +{ + double kn = pow(CrotMin/rot1n,beta); + kn = (kn < 1.0) ? 1.0 : 1.0/kn; + double kp = pow(CrotMax/rot1p,beta); + kp = (kp < 1.0) ? 1.0 : 1.0/kp; + + if (TloadIndicator == 1) { + TloadIndicator = 2; + if (Cstress >= 0.0) { + TrotPu = Cstrain - Cstress/(Eup*kp); + double energy = CenergyD - 0.5*Cstress/(Eup*kp)*Cstress; + double damfc = 0.0; + if (CrotMax > rot1p) { + damfc = damfc2*energy/energyA; + damfc += damfc1*(CrotMax-rot1p)/rot1p; + } + + TrotMin = CrotMin*(1.0+damfc); + } + } + + TloadIndicator = 2; + + TrotMin = (TrotMin < rot1n) ? TrotMin : rot1n; + + double minmom = negEnvlpStress(TrotMin); + double rotlim = posEnvlpRotlim(CrotMax); + double rotrel = (rotlim < TrotPu) ? rotlim : TrotPu; + + //rotrel = TrotPu; + //if (posEnvlpStress(CrotMax) <= 0.0) + // rotrel = rotlim; + + //double rotmp1 = rotrel + pinchY*(TrotMin-rotrel); + double rotmp2 = TrotMin - (1.0-pinchY)*minmom/(Eun*kn); + //double rotmp2 = TrotMin-(1-pinchY)*minmom/Eun; + //double rotch = rotmp1 + (rotmp2-rotmp1)*pinchX; + double rotch = rotrel + (rotmp2-rotrel)*pinchX; // changed on 7/11/2006 + + double tmpmo1; + double tmpmo2; + + if (Tstrain > TrotPu) { + Ttangent = Eup*kp; + Tstress = Cstress + Ttangent*dStrain; + if (Tstress <= 0.0) { + Tstress = 0.0; + Ttangent = Eup*1.0e-9; + } + } + + else if (Tstrain <= TrotPu && Tstrain > rotch) { + if (Tstrain >= rotrel) { + Tstress = 0.0; + Ttangent = Eun*1.0e-9; + } + else { + Ttangent = minmom*pinchY/(rotch-rotrel); + tmpmo1 = Cstress + Eun*kn*dStrain; + tmpmo2 = (Tstrain-rotrel)*Ttangent; + if (tmpmo1 > tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eun*kn; + } + else + Tstress = tmpmo2; + } + } + + else { + Ttangent = (1.0-pinchY)*minmom/(TrotMin-rotch); + tmpmo1 = Cstress + Eun*kn*dStrain; + tmpmo2 = pinchY*minmom + (Tstrain-rotch)*Ttangent; + if (tmpmo1 > tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eun*kn; + } + else + Tstress = tmpmo2; + } +} + +int +Trilinwp2::commitState(void) +{ + CrotMax = TrotMax; + CrotMin = TrotMin; + CrotPu = TrotPu; + CrotNu = TrotNu; + CenergyD = TenergyD; + CloadIndicator = TloadIndicator; + + Cstress = Tstress; + Cstrain = Tstrain; + return 0; +} + + +int +Trilinwp2::revertToLastCommit(void) +{ + TrotMax = CrotMax; + TrotMin = CrotMin; + TrotPu = CrotPu; + TrotNu = CrotNu; + TenergyD = CenergyD; + TloadIndicator = CloadIndicator; + + Tstress = Cstress; + Tstrain = Cstrain; + + return 0; +} + + +int +Trilinwp2::revertToStart(void) +{ + CrotMax = 0.0; + CrotMin = 0.0; + CrotPu = 0.0; + CrotNu = 0.0; + CenergyD = 0.0; + CloadIndicator = 0; + + Cstress = 0.0; + Cstrain = 0.0; + + Tstrain = 0; + Tstress = 0; + Ttangent = E1p; + + mom1pi=mom1p; + mom2pi=mom2p; + mom3pi=mom3p; + mom1ni=mom1n; + mom2ni=mom2n; + mom3ni=mom3n; + return 0; +} + + +UniaxialMaterial* +Trilinwp2::getCopy(void) +{ + Trilinwp2 *theCopy = new Trilinwp2 (this->getTag(), + mom1pi, rot1pi, mom2pi, rot2pi, mom3pi, rot3pi, + pinchX, pinchY, damfc1, damfc2, beta,pt,pb,pc,mb, itype); + + theCopy->CrotMax = CrotMax; + theCopy->CrotMin = CrotMin; + theCopy->CrotPu = CrotPu; + theCopy->CrotNu = CrotNu; + theCopy->CenergyD = CenergyD; + theCopy->CloadIndicator = CloadIndicator; + theCopy->Cstress = Cstress; + theCopy->Cstrain = Cstrain; + theCopy->Ttangent = Ttangent; + //theCopy->N = N; + //theCopy->mom1p = mom1p; + //theCopy->mom2p = mom2p; + //theCopy->mom3p = mom3p; + //theCopy->mom1n = mom1n; + //theCopy->mom2n = mom2n; + //theCopy->mom3n = mom3n; + //theCopy->rot1p = rot1p; + //theCopy->rot2p = rot2p; + //theCopy->rot3p = rot3p; + //theCopy->rot1n = rot1n; + //theCopy->rot2n = rot2n; + //theCopy->rot3n = rot3n; + + + + return theCopy; +} +int +Trilinwp2::sendSelf(int commitTag, Channel &theChannel) +{ + int res = 0; + + static Vector data(32); + + data(0) = this->getTag(); + data(1) = mom1p; + data(2) = rot1p; + data(3) = mom2p; + data(4) = rot2p; + data(5) = mom3p; + data(6) = rot3p; + data(7) = mom1n; + data(8) = rot1n; + data(9) = mom2n; + data(10) = rot2n; + data(11) = mom3n; + data(12) = rot3n; + data(13) = pinchX; + data(14) = pinchY; + data(15) = damfc1; + data(16) = damfc2; + data(17) = beta; + data(18) = CrotMax; + data(19) = CrotMin; + data(20) = CrotPu; + data(21) = CrotNu; + data(22) = CenergyD; + data(23) = CloadIndicator; + data(24) = Cstress; + data(25) = Cstrain; + data(26) = Ttangent; + data(27) = pt; + data(28) = pb; + data(29) = pc; + data(30) = mb; + data(31)=itype; + + res = theChannel.sendVector(this->getDbTag(), commitTag, data); + if (res < 0) + opserr << "Trilinwp2::sendSelf() - failed to send data\n"; + + + return res; +} + +int +Trilinwp2::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + + static Vector data(32); + res = theChannel.recvVector(this->getDbTag(), commitTag, data); + + if (res < 0) { + opserr << "Trilinwp2::recvSelf() - failed to receive data\n"; + return res; + } + else { + this->setTag((int)data(0)); + mom1p = data(1); + rot1p = data(2); + mom2p = data(3); + rot2p = data(4); + mom3p = data(5); + rot3p = data(6); + mom1n = data(7); + rot1n = data(8); + mom2n = data(9); + rot2n = data(10); + mom3n = data(11); + rot3n = data(12); + pinchX = data(13); + pinchY = data(14); + damfc1 = data(15); + damfc2 = data(16); + beta = data(17); + + CrotMax = data(18); + CrotMin = data(19); + CrotPu = data(20); + CrotNu = data(21); + CenergyD = data(22); + CloadIndicator = int(data(23)); + Cstress = data(24); + Cstrain = data(25); + Ttangent = data(26); + pt = data(27); + pb = data(28); + pc = data(29); + mb = data(30); + itype=data(31); + // set the trial values + TrotMax = CrotMax; + TrotMin = CrotMin; + TrotPu = CrotPu; + TrotNu = CrotNu; + TenergyD = CenergyD; + TloadIndicator = CloadIndicator; + Tstress = Cstress; + Tstrain = Cstrain; + } + + // Set envelope slopes + this->setEnvelope(); + + return 0; +} + +void +Trilinwp2::Print(OPS_Stream &s, int flag) +{ + s << "Trilineal with pinching material - GST(2017), tag: " << this->getTag() << endln; + s << "mom1p: " << mom1p << endln; + s << "rot1p: " << rot1p << endln; + s << "E1p: " << E1p << endln; + s << "mom2p: " << mom2p << endln; + s << "rot2p: " << rot2p << endln; + s << "E2p: " << E2p << endln; + s << "mom3p: " << mom3p << endln; + s << "rot3p: " << rot3p << endln; + s << "E3p: " << E3p << endln; + + s << "mom1n: " << mom1n << endln; + s << "rot1n: " << rot1n << endln; + s << "E1n: " << E1n << endln; + s << "mom2n: " << mom2n << endln; + s << "rot2n: " << rot2n << endln; + s << "E2n: " << E2n << endln; + s << "mom3n: " << mom3n << endln; + s << "rot3n: " << rot3n << endln; + s << "E3n: " << E3n << endln; + + s << "pinchX: " << pinchX << endln; + s << "pinchY: " << pinchY << endln; + s << "damfc1: " << damfc1 << endln; + s << "damfc2: " << damfc2 << endln; + s << "energyA: " << energyA << endln; + s << "beta: " << beta << endln; + s << "Pt: " << pt << endln; + s << "Pb: " << pb << endln; + s << "Pc: " << pc << endln; + s << "Mb: " << mb << endln; + s << "itype "<< itype<< endln; + if(itype==1){ + s << "Type: Flexure" << endln; + } + else if(itype==2){ + s << "Type: Shear" << endln; + } + else { + s << "Shear and flexure with no Axial Interaction" << endln; + } +} + +void +Trilinwp2::setEnvelope(void) +{ + E1p = mom1p/rot1p; + E2p = (mom2p-mom1p)/(rot2p-rot1p); + E3p = (mom3p-mom2p)/(rot3p-rot2p); + + E1n = mom1n/rot1n; + E2n = (mom2n-mom1n)/(rot2n-rot1n); + E3n = (mom3n-mom2n)/(rot3n-rot2n); + + Eup = E1p; + if (E2p > Eup) Eup = E2p; + if (E3p > Eup) Eup = E3p; + + Eun = E1n; + if (E2n > Eun) Eun = E2n; + if (E3n > Eun) Eun = E3n; + + +} + +double +Trilinwp2::posEnvlpStress(double strain) +{ + if (strain <= 0.0) + return 0.0; + else if (strain <= rot1p) + return E1p*strain; + else if (strain <= rot2p) + return mom1p + E2p*(strain-rot1p); + else if (strain <= rot3p || E3p > 0.0) + return mom2p + E3p*(strain-rot2p); + else + return mom3p; +} + +double +Trilinwp2::negEnvlpStress(double strain) +{ + if (strain >= 0.0) + return 0.0; + else if (strain >= rot1n) + return E1n*strain; + else if (strain >= rot2n) + return mom1n + E2n*(strain-rot1n); + else if (strain >= rot3n || E3n > 0.0) + return mom2n + E3n*(strain-rot2n); + else + return mom3n; +} + +double +Trilinwp2::posEnvlpTangent(double strain) +{ + if (strain < 0.0) + return E1p*1.0e-9; + else if (strain <= rot1p) + return E1p; + else if (strain <= rot2p) + return E2p; + else if (strain <= rot3p || E3p > 0.0) + return E3p; + else + return E1p*1.0e-9; +} + +double +Trilinwp2::negEnvlpTangent(double strain) +{ + if (strain > 0.0) + return E1n*1.0e-9; + else if (strain >= rot1n) + return E1n; + else if (strain >= rot2n) + return E2n; + else if (strain >= rot3n || E3n > 0.0) + return E3n; + else + return E1n*1.0e-9; +} + +double +Trilinwp2::posEnvlpRotlim(double strain) +{ + double strainLimit = POS_INF_STRAIN; + + if (strain <= rot1p) + return POS_INF_STRAIN; + if (strain > rot1p && strain <= rot2p && E2p < 0.0) + strainLimit = rot1p - mom1p/E2p; + if (strain > rot2p && E3p < 0.0) + strainLimit = rot2p - mom2p/E3p; + + if (strainLimit == POS_INF_STRAIN) + return POS_INF_STRAIN; + else if (posEnvlpStress(strainLimit) > 0) + return POS_INF_STRAIN; + else + return strainLimit; +} + +double +Trilinwp2::negEnvlpRotlim(double strain) +{ + double strainLimit = NEG_INF_STRAIN; + + if (strain >= rot1n) + return NEG_INF_STRAIN; + if (strain < rot1n && strain >= rot2n && E2n < 0.0) + strainLimit = rot1n - mom1n/E2n; + if (strain < rot2n && E3n < 0.0) + strainLimit = rot2n - mom2n/E3n; + + if (strainLimit == NEG_INF_STRAIN) + return NEG_INF_STRAIN; + else if (negEnvlpStress(strainLimit) < 0) + return NEG_INF_STRAIN; + else + return strainLimit; +} diff --git a/SRC/material/uniaxial/Trilinwp2.h b/SRC/material/uniaxial/Trilinwp2.h new file mode 100644 index 000000000..7bbf80089 --- /dev/null +++ b/SRC/material/uniaxial/Trilinwp2.h @@ -0,0 +1,144 @@ +/* ****************************************************************** ** +** 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.8 $ +// $Date: 2008-12-18 23:40:51 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/Trilinwp.h,v $ + +#ifndef Trilinwp2_h +#define Trilinwp2_h + +#include + +class Trilinwp2 : public UniaxialMaterial +{ + public: + Trilinwp2(int tag, + double mom1p, double rot1p, double mom2p, double rot2p, + double mom3p, double rot3p, + double pinchX, double pinchY, + double damfc1 = 0.0, double damfc2 = 0.0, + double beta = 0.0, + double pt = 0.0, double pb = 0.0, double pc = 0.0, double mb = 0.0, int itype = 0); + Trilinwp2(); + ~Trilinwp2(); + + const char *getClassType(void) const {return "Trilinwp2";}; + + int setTrialStrain(double strain, double strainRate = 0.0 ); + double getStrain(void); + double getStress(void); + double getTangent(void); + double getInitialTangent(void) {return E1p;}; + + 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: + // Pinching parameters + double pinchX; // Deformation pinching + double pinchY; // Force pinching + + // Damage parameters + double damfc1; // Deformation + double damfc2; // Energy + + // Unloading parameter + double beta; + // Envelope parameters + + double pt; + double pb; + double pc; + double mb; + + // Trial history variables + double TrotMax; + double TrotMin; + double TrotPu; + double TrotNu; + double TenergyD; + int TloadIndicator; + + // Trial state variables + double Ttangent; + double Tstress; + double Tstrain; + + // Converged history variables + double CrotMax; + double CrotMin; + double CrotPu; + double CrotNu; + double CenergyD; + int CloadIndicator; + + // Converged state variables + double Cstress; + double Cstrain; + + // Backbone parameters + double mom1p, rot1p; + double mom2p, rot2p; + double mom3p, rot3p; + double mom1n, rot1n; + double mom2n, rot2n; + double mom3n, rot3n; + + double E1p, E1n; + double E2p, E2n; + double E3p, E3n; + double Eup, Eun; + + double energyA; + + double mom1pi,mom2pi,mom3pi; + double mom1ni, mom2ni, mom3ni; + double rot1pi, rot2pi, rot3pi; + double duct; + int itype; + + void setEnvelope(void); + + double posEnvlpStress(double strain); + double negEnvlpStress(double strain); + + double posEnvlpTangent(double strain); + double negEnvlpTangent(double strain); + + double posEnvlpRotlim(double strain); + double negEnvlpRotlim(double strain); + + void positiveIncrement(double dStrain); + void negativeIncrement(double dStrain); +}; + +#endif diff --git a/SRC/material/uniaxial/Trilinwpd.cpp b/SRC/material/uniaxial/Trilinwpd.cpp new file mode 100644 index 000000000..aeec3a4c0 --- /dev/null +++ b/SRC/material/uniaxial/Trilinwpd.cpp @@ -0,0 +1,839 @@ +/* ****************************************************************** ** +** 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.7 $ +// $Date: 2009/03/23 23:17:04 $ +// $Source: /usr/local/cvs/OpenSees/PACKAGES/NewMaterial/cpp/trilinwpd.cpp,v $ + +#include +#include + +#include +#include +#include +#include + + +static int numTrilinwpd = 0; + +void * +OPS_Trilinwpd() +{ + // print out some KUDO's + if (numTrilinwpd == 0) { + opserr << "Trilineal with pinching unaxial material - Written by GST UNcuyo Copyright 2017 - Use at your Own Peril\n"; + numTrilinwpd =1; + } + + // Pointer to a uniaxial material that will be returned + UniaxialMaterial *theMaterial = 0; + + // + // parse the input line for the material parameters + // + + int iData[2]; + double dData[19]; + int numData; + + numData = 1; + if (OPS_GetIntInput(&numData, &iData[0]) != 0) { + opserr << "WARNING invalid uniaxialMaterial trilinwpd tag" << endln; + return 0; + } + + numData = 19; + if (OPS_GetDoubleInput(&numData, dData) != 0) { + opserr << "WARNING invalid parameters\n"; + return 0; + } + numData = 1; + if (OPS_GetIntInput(&numData, &iData[1]) != 0) { + opserr << "WARNING invalid uniaxialMaterial trilinwpd type" << endln; + return 0; + } + + int itype=iData[1]; + + // + // create a new material + // + + theMaterial = new trilinwpd(iData[0], dData[0], 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], iData[1]); + + + if (theMaterial == 0) { + opserr << "WARNING could not create uniaxialMaterial of type trilinwpd\n"; + return 0; + } + + // return the material + return theMaterial; +} + + + + +trilinwpd::trilinwpd(int tag, + double m1p, double r1p, double m2p, double r2p, double m3p, double r3p, + double m1n, double r1n, double m2n, double r2n, double m3n, double r3n, + double px, double py, double d1, double d2, double b, double ptn, double pbn, int it): +UniaxialMaterial(tag, MAT_TAG_Trilinwpd), +pinchX(px), pinchY(py), damfc1(d1), damfc2(d2), beta(b), +mom1p(m1p), rot1p(r1p), mom2p(m2p), rot2p(r2p), mom3p(m3p), rot3p(r3p), +mom1n(m1n), rot1n(r1n), mom2n(m2n), rot2n(r2n), mom3n(m3n), rot3n(r3n),pt(ptn), pb(pbn),itype(it) +{ + bool error = false; + // Positive backbone parameters + if (rot1p <= 0.0) + error = true; + + if (rot2p <= rot1p) + error = true; + + if (rot3p <= rot2p) + error = true; + + // Negative backbone parameters + if (rot1n >= 0.0) + error = true; + + if (rot2n >= rot1n) + error = true; + + if (rot3n >= rot2n) + error = true; + + if (error) { + opserr << "trilinwpd::trilinwpd -- input backbone is not unique (one-to-one)\n"; + exit(-1); + } + mom1pi=mom1p; + mom2pi=mom2p; + mom3pi=mom3p; + mom1ni=mom1n; + mom2ni=mom2n; + mom3ni=mom3n; + energyA = 0.5 * (rot1p*mom1p + (rot2p-rot1p)*(mom2p+mom1p) + (rot3p-rot2p)*(mom3p+mom2p) + + rot1n*mom1n + (rot2n-rot1n)*(mom2n+mom1n) + (rot3n-rot2n)*(mom3n+mom2n)); + + // Set envelope slopes + this->setEnvelope(); + + // Initialize history variables + this->revertToStart(); + this->revertToLastCommit(); + +} + + + +trilinwpd::trilinwpd(): +UniaxialMaterial(0, MAT_TAG_Trilinwpd), +pinchX(0.0), pinchY(0.0), damfc1(0.0), damfc2(0.0), beta(0.0), +mom1p(0.0), rot1p(0.0), mom2p(0.0), rot2p(0.0), mom3p(0.0), rot3p(0.0), +mom1n(0.0), rot1n(0.0), mom2n(0.0), rot2n(0.0), mom3n(0.0), rot3n(0.0), pt(0.0), pb(0.0),itype(0) +{ + +} + +trilinwpd::~trilinwpd() +{ + // Nothing to do +} + +int +trilinwpd::setTrialStrain(double strain, double strainRate) +{ + + + +if (TloadIndicator == 0 && strain == 0.0) + return 0; +double N=strainRate; //Fuerza axial >0= traccion + +N=-1.0*(strainRate); + +if (itype==1){ + +if (N>0 && Npt){ + mom1p=mom1pi/100.0; + mom1n=mom1ni/100.0; + mom2p=mom2pi/100.0; + mom2n=mom2ni/100.0; + mom3p=mom3pi/100.0; + mom3n=mom3ni/100.0; + +} +else if(N<0 && N>pb){ + mom1p=mom1pi+(mom2pi-mom1pi)*N/pb; + mom1n=mom1ni+(mom2ni-mom1ni)*N/pb; + mom2p=mom2pi+(mom3pi-mom2pi)*N/pb; + mom2n=mom2ni+(mom3ni-mom2ni)*N/pb; + mom3p=mom3pi*N/pb; + mom3n=mom3ni*N/pb; +} +else if(N<0 && N0 && Npt){ + mom1p=mom1pi/100.0; + mom1n=mom1ni/100.0; + mom2p=mom2pi/100.0; + mom2n=mom2ni/100.0; + mom3p=mom3pi/100.0; + mom3n=mom3ni/100.0; + +} + +else if(N<0 && N>pb){ + mom1p=mom1pi*(1.0+pow(N/pb,2)); + mom1n=mom1ni*(1.0+pow(N/pb,2)); + mom2p=mom2pi*(1.0+pow(N/pb,2)); + mom2n=mom2ni*(1.0+pow(N/pb,2)); + mom3p=mom3pi*(1.0+pow(N/pb,2)); + mom3n=mom3ni*(1.0+pow(N/pb,2)); +} +else if(N<0 && NsetEnvelope(); + + TrotMax = CrotMax; + TrotMin = CrotMin; + TenergyD = CenergyD; + TrotPu = CrotPu; + TrotNu = CrotNu; + + Tstrain = strain; + double dStrain = Tstrain - Cstrain; + + if (fabs(dStrain) < DBL_EPSILON) + return 0; + + TloadIndicator = CloadIndicator; + + if (TloadIndicator == 0) + TloadIndicator = (dStrain < 0.0) ? 2 : 1; + + if (Tstrain >= CrotMax) { + TrotMax = Tstrain; + Ttangent = posEnvlpTangent(Tstrain); + Tstress = posEnvlpStress(Tstrain); + TloadIndicator=1; + } + else if (Tstrain <= CrotMin) { + TrotMin = Tstrain; + Ttangent = negEnvlpTangent(Tstrain); + Tstress = negEnvlpStress(Tstrain); + TloadIndicator=2; + } + else { + if (dStrain < 0.0) + negativeIncrement(dStrain); + else if (dStrain > 0.0) + positiveIncrement(dStrain); + } + + TenergyD = CenergyD + 0.5*(Cstress+Tstress)*dStrain; + + return 0; +} + + +double +trilinwpd::getStrain(void) +{ + return Tstrain; +} + +double +trilinwpd::getStress(void) +{ + return Tstress; +} + + +double +trilinwpd::getTangent(void) +{ + return Ttangent; +} + +void +trilinwpd::positiveIncrement(double dStrain) +{ + double kn = pow(CrotMin/rot1n,beta); + kn = (kn < 1.0) ? 1.0 : 1.0/kn; + double kp = pow(CrotMax/rot1p,beta); + kp = (kp < 1.0) ? 1.0 : 1.0/kp; + + if (TloadIndicator == 2) { + TloadIndicator = 1; + if (Cstress <= 0.0) { + TrotNu = Cstrain - Cstress/(Eun*kn); + double energy = CenergyD - 0.5*Cstress/(Eun*kn)*Cstress; + double damfc = 0.0; + if (CrotMin < rot1n) { + damfc = damfc2*energy/energyA; + damfc += damfc1*(CrotMin-rot1n)/rot1n; + } + + TrotMax = CrotMax*(1.0+damfc); + } + } + + TloadIndicator = 1; + + TrotMax = (TrotMax > rot1p) ? TrotMax : rot1p; + + double maxmom = posEnvlpStress(TrotMax); + double rotlim = negEnvlpRotlim(CrotMin); + double rotrel = (rotlim > TrotNu) ? rotlim : TrotNu; + + + double rotmp2 = TrotMax - (1.0-pinchY)*maxmom/(Eup*kp); + double rotch = rotrel + (rotmp2-rotrel)*pinchX; // changed on 7/11/2006 + + double tmpmo1; + double tmpmo2; + + if (Tstrain < TrotNu) { + Ttangent = Eun*kn; + Tstress = Cstress + Ttangent*dStrain; + if (Tstress >= 0.0) { + Tstress = 0.0; + Ttangent = Eun*1.0e-9; + } + } + + else if (Tstrain >= TrotNu && Tstrain < rotch) { + if (Tstrain <= rotrel) { + Tstress = 0.0; + Ttangent = Eup*1.0e-9; + } + else { + Ttangent = maxmom*pinchY/(rotch-rotrel); + tmpmo1 = Cstress + Eup*kp*dStrain; + tmpmo2 = (Tstrain-rotrel)*Ttangent; + if (tmpmo1 < tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eup*kp; + } + else + Tstress = tmpmo2; + } + } + + else { + Ttangent = (1.0-pinchY)*maxmom/(TrotMax-rotch); + tmpmo1 = Cstress + Eup*kp*dStrain; + tmpmo2 = pinchY*maxmom + (Tstrain-rotch)*Ttangent; + if (tmpmo1 < tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eup*kp; + } + else + Tstress = tmpmo2; + } +} + +void +trilinwpd::negativeIncrement(double dStrain) +{ + double kn = pow(CrotMin/rot1n,beta); + kn = (kn < 1.0) ? 1.0 : 1.0/kn; + double kp = pow(CrotMax/rot1p,beta); + kp = (kp < 1.0) ? 1.0 : 1.0/kp; + + if (TloadIndicator == 1) { + TloadIndicator = 2; + if (Cstress >= 0.0) { + TrotPu = Cstrain - Cstress/(Eup*kp); + double energy = CenergyD - 0.5*Cstress/(Eup*kp)*Cstress; + double damfc = 0.0; + if (CrotMax > rot1p) { + damfc = damfc2*energy/energyA; + damfc += damfc1*(CrotMax-rot1p)/rot1p; + } + + TrotMin = CrotMin*(1.0+damfc); + } + } + + TloadIndicator = 2; + + TrotMin = (TrotMin < rot1n) ? TrotMin : rot1n; + + double minmom = negEnvlpStress(TrotMin); + double rotlim = posEnvlpRotlim(CrotMax); + double rotrel = (rotlim < TrotPu) ? rotlim : TrotPu; + + + double rotmp2 = TrotMin - (1.0-pinchY)*minmom/(Eun*kn); + + double rotch = rotrel + (rotmp2-rotrel)*pinchX; // changed on 7/11/2006 + + double tmpmo1; + double tmpmo2; + + if (Tstrain > TrotPu) { + Ttangent = Eup*kp; + Tstress = Cstress + Ttangent*dStrain; + if (Tstress <= 0.0) { + Tstress = 0.0; + Ttangent = Eup*1.0e-9; + } + } + + else if (Tstrain <= TrotPu && Tstrain > rotch) { + if (Tstrain >= rotrel) { + Tstress = 0.0; + Ttangent = Eun*1.0e-9; + } + else { + Ttangent = minmom*pinchY/(rotch-rotrel); + tmpmo1 = Cstress + Eun*kn*dStrain; + tmpmo2 = (Tstrain-rotrel)*Ttangent; + if (tmpmo1 > tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eun*kn; + } + else + Tstress = tmpmo2; + } + } + + else { + Ttangent = (1.0-pinchY)*minmom/(TrotMin-rotch); + tmpmo1 = Cstress + Eun*kn*dStrain; + tmpmo2 = pinchY*minmom + (Tstrain-rotch)*Ttangent; + if (tmpmo1 > tmpmo2) { + Tstress = tmpmo1; + Ttangent = Eun*kn; + } + else + Tstress = tmpmo2; + } +} + +int +trilinwpd::commitState(void) +{ + CrotMax = TrotMax; + CrotMin = TrotMin; + CrotPu = TrotPu; + CrotNu = TrotNu; + CenergyD = TenergyD; + CloadIndicator = TloadIndicator; + + Cstress = Tstress; + Cstrain = Tstrain; + return 0; +} + + +int +trilinwpd::revertToLastCommit(void) +{ + TrotMax = CrotMax; + TrotMin = CrotMin; + TrotPu = CrotPu; + TrotNu = CrotNu; + TenergyD = CenergyD; + TloadIndicator = CloadIndicator; + + Tstress = Cstress; + Tstrain = Cstrain; + + return 0; +} + + +int +trilinwpd::revertToStart(void) +{ + CrotMax = 0.0; + CrotMin = 0.0; + CrotPu = 0.0; + CrotNu = 0.0; + CenergyD = 0.0; + CloadIndicator = 0; + + Cstress = 0.0; + Cstrain = 0.0; + + Tstrain = 0; + Tstress = 0; + Ttangent = E1p; + + mom1pi=mom1p; + mom2pi=mom2p; + mom3pi=mom3p; + mom1ni=mom1n; + mom2ni=mom2n; + mom3ni=mom3n; + return 0; +} + + +UniaxialMaterial* +trilinwpd::getCopy(void) +{ + trilinwpd *theCopy = new trilinwpd (this->getTag(), + mom1p, rot1p, mom2p, rot2p, mom3p, rot3p, + mom1n, rot1n, mom2n, rot2n, mom3n, rot3n, + pinchX, pinchY, damfc1, damfc2, beta,pt,pb, itype); + + theCopy->CrotMax = CrotMax; + theCopy->CrotMin = CrotMin; + theCopy->CrotPu = CrotPu; + theCopy->CrotNu = CrotNu; + theCopy->CenergyD = CenergyD; + theCopy->CloadIndicator = CloadIndicator; + theCopy->Cstress = Cstress; + theCopy->Cstrain = Cstrain; + theCopy->Ttangent = Ttangent; + + return theCopy; +} +int +trilinwpd::sendSelf(int commitTag, Channel &theChannel) +{ + int res = 0; + + static Vector data(30); + + data(0) = this->getTag(); + data(1) = mom1p; + data(2) = rot1p; + data(3) = mom2p; + data(4) = rot2p; + data(5) = mom3p; + data(6) = rot3p; + data(7) = mom1n; + data(8) = rot1n; + data(9) = mom2n; + data(10) = rot2n; + data(11) = mom3n; + data(12) = rot3n; + data(13) = pinchX; + data(14) = pinchY; + data(15) = damfc1; + data(16) = damfc2; + data(17) = beta; + data(18) = CrotMax; + data(19) = CrotMin; + data(20) = CrotPu; + data(21) = CrotNu; + data(22) = CenergyD; + data(23) = CloadIndicator; + data(24) = Cstress; + data(25) = Cstrain; + data(26) = Ttangent; + data(27) = pt; + data(28) = pb; + data(29)=itype; + + res = theChannel.sendVector(this->getDbTag(), commitTag, data); + if (res < 0) + opserr << "trilinwpd::sendSelf() - failed to send data\n"; + + + return res; +} + +int +trilinwpd::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + + static Vector data(30); + res = theChannel.recvVector(this->getDbTag(), commitTag, data); + + if (res < 0) { + opserr << "trilinwpd::recvSelf() - failed to receive data\n"; + return res; + } + else { + this->setTag((int)data(0)); + mom1p = data(1); + rot1p = data(2); + mom2p = data(3); + rot2p = data(4); + mom3p = data(5); + rot3p = data(6); + mom1n = data(7); + rot1n = data(8); + mom2n = data(9); + rot2n = data(10); + mom3n = data(11); + rot3n = data(12); + pinchX = data(13); + pinchY = data(14); + damfc1 = data(15); + damfc2 = data(16); + beta = data(17); + + CrotMax = data(18); + CrotMin = data(19); + CrotPu = data(20); + CrotNu = data(21); + CenergyD = data(22); + CloadIndicator = int(data(23)); + Cstress = data(24); + Cstrain = data(25); + Ttangent = data(26); + pt = data(27); + pb = data(29); + itype=data(30); + // set the trial values + TrotMax = CrotMax; + TrotMin = CrotMin; + TrotPu = CrotPu; + TrotNu = CrotNu; + TenergyD = CenergyD; + TloadIndicator = CloadIndicator; + Tstress = Cstress; + Tstrain = Cstrain; + } + + // Set envelope slopes + this->setEnvelope(); + + return 0; +} + +void +trilinwpd::Print(OPS_Stream &s, int flag) +{ + s << "Trilineal with pinching material - GST(2017), tag: " << this->getTag() << endln; + s << "mom1p: " << mom1p << endln; + s << "rot1p: " << rot1p << endln; + s << "E1p: " << E1p << endln; + s << "mom2p: " << mom2p << endln; + s << "rot2p: " << rot2p << endln; + s << "E2p: " << E2p << endln; + s << "mom3p: " << mom3p << endln; + s << "rot3p: " << rot3p << endln; + s << "E3p: " << E3p << endln; + + s << "mom1n: " << mom1n << endln; + s << "rot1n: " << rot1n << endln; + s << "E1n: " << E1n << endln; + s << "mom2n: " << mom2n << endln; + s << "rot2n: " << rot2n << endln; + s << "E2n: " << E2n << endln; + s << "mom3n: " << mom3n << endln; + s << "rot3n: " << rot3n << endln; + s << "E3n: " << E3n << endln; + + s << "pinchX: " << pinchX << endln; + s << "pinchY: " << pinchY << endln; + s << "damfc1: " << damfc1 << endln; + s << "damfc2: " << damfc2 << endln; + s << "energyA: " << energyA << endln; + s << "beta: " << beta << endln; + s << "Pt: " << pt << endln; + s << "Pb: " << pb << endln; + s << "itype "<< itype<< endln; + if(itype==1){ + s << "Type: Flexure" << endln; + } + else if(itype==2){ + s << "Type: Shear" << endln; + } +} + +void +trilinwpd::setEnvelope(void) +{ + E1p = mom1p/rot1p; + E2p = (mom2p-mom1p)/(rot2p-rot1p); + E3p = (mom3p-mom2p)/(rot3p-rot2p); + + E1n = mom1n/rot1n; + E2n = (mom2n-mom1n)/(rot2n-rot1n); + E3n = (mom3n-mom2n)/(rot3n-rot2n); + + Eup = E1p; + if (E2p > Eup) Eup = E2p; + if (E3p > Eup) Eup = E3p; + + Eun = E1n; + if (E2n > Eun) Eun = E2n; + if (E3n > Eun) Eun = E3n; + + +} + +double +trilinwpd::posEnvlpStress(double strain) +{ + if (strain <= 0.0) + return 0.0; + else if (strain <= rot1p) + return E1p*strain; + else if (strain <= rot2p) + return mom1p + E2p*(strain-rot1p); + else if (strain <= rot3p ) + return mom2p + E3p*(strain-rot2p); + else + + return mom1p*0.1-E1p*.001*(strain-rot3p); +} + +double +trilinwpd::negEnvlpStress(double strain) +{ + if (strain >= 0.0) + return 0.0; + else if (strain >= rot1n) + return E1n*strain; + else if (strain >= rot2n) + return mom1n + E2n*(strain-rot1n); + else if (strain >= rot3n ) + return mom2n + E3n*(strain-rot2n); + else + + return mom1n*0.1-E1n*.001*(strain-rot3n); +} + +double +trilinwpd::posEnvlpTangent(double strain) +{ + if (strain < 0.0) + return E1p*1.0e-9; + else if (strain <= rot1p) + return E1p; + else if (strain <= rot2p) + return E2p; + else if (strain <= rot3p ) + return E3p; + else + + return -1.0*E1p*.001; +} + +double +trilinwpd::negEnvlpTangent(double strain) +{ + if (strain > 0.0) + return E1n*1.0e-9; + else if (strain >= rot1n) + return E1n; + else if (strain >= rot2n) + return E2n; + else if (strain >= rot3n ) + return E3n; + else + + return -1*E1n*.001; +} + +double +trilinwpd::posEnvlpRotlim(double strain) +{ + double strainLimit = POS_INF_STRAIN; + + if (strain <= rot1p) + return POS_INF_STRAIN; + if (strain > rot1p && strain <= rot2p && E2p < 0.0) + strainLimit = rot1p - mom1p/E2p; + if (strain > rot2p && E3p < 0.0) + strainLimit = rot2p - mom2p/E3p; + + if (strainLimit == POS_INF_STRAIN) + return POS_INF_STRAIN; + else if (posEnvlpStress(strainLimit) > 0) + return POS_INF_STRAIN; + else + return strainLimit; +} + +double +trilinwpd::negEnvlpRotlim(double strain) +{ + double strainLimit = NEG_INF_STRAIN; + + if (strain >= rot1n) + return NEG_INF_STRAIN; + if (strain < rot1n && strain >= rot2n && E2n < 0.0) + strainLimit = rot1n - mom1n/E2n; + if (strain < rot2n && E3n < 0.0) + strainLimit = rot2n - mom2n/E3n; + + if (strainLimit == NEG_INF_STRAIN) + return NEG_INF_STRAIN; + else if (negEnvlpStress(strainLimit) < 0) + return NEG_INF_STRAIN; + else + return strainLimit; +} diff --git a/SRC/material/uniaxial/Trilinwpd.h b/SRC/material/uniaxial/Trilinwpd.h new file mode 100644 index 000000000..abf1ab677 --- /dev/null +++ b/SRC/material/uniaxial/Trilinwpd.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) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.8 $ +// $Date: 2008-12-18 23:40:51 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/trilinwpd.h,v $ + +#ifndef trilinwpd_h +#define trilinwpd_h + +#include + +class trilinwpd : public UniaxialMaterial +{ + public: + trilinwpd(int tag, + double mom1p, double rot1p, double mom2p, double rot2p, + double mom3p, double rot3p, + double mom1n, double rot1n, double mom2n, double rot2n, + double mom3n, double rot3n, + double pinchX, double pinchY, + double damfc1 = 0.0, double damfc2 = 0.0, + double beta = 0.0, + double pt= 0.0, double pb= 0.0,int itype=0); + trilinwpd(); + ~trilinwpd(); + + const char *getClassType(void) const {return "trilinwpd";}; + + int setTrialStrain(double strain, double strainRate =0.0 ); + double getStrain(void); + double getStress(void); + double getTangent(void); + double getInitialTangent(void) {return E1p;}; + + 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: + // Pinching parameters + double pinchX; // Deformation pinching + double pinchY; // Force pinching + + // Damage parameters + double damfc1; // Deformation + double damfc2; // Energy + + // Unloading parameter + double beta; + + // Trial history variables + double TrotMax; + double TrotMin; + double TrotPu; + double TrotNu; + double TenergyD; + int TloadIndicator; + + // Trial state variables + double Ttangent; + double Tstress; + double Tstrain; + + // Converged history variables + double CrotMax; + double CrotMin; + double CrotPu; + double CrotNu; + double CenergyD; + int CloadIndicator; + + // Converged state variables + double Cstress; + double Cstrain; + + // Backbone parameters + double mom1p, rot1p; + double mom2p, rot2p; + double mom3p, rot3p; + double mom1n, rot1n; + double mom2n, rot2n; + double mom3n, rot3n; + + double E1p, E1n; + double E2p, E2n; + double E3p, E3n; + double Eup, Eun; + + double energyA; + double pt; + double pb; + double mom1pi,mom2pi,mom3pi; + double mom1ni, mom2ni, mom3ni; + int itype; + + void setEnvelope(void); + + double posEnvlpStress(double strain); + double negEnvlpStress(double strain); + + double posEnvlpTangent(double strain); + double negEnvlpTangent(double strain); + + double posEnvlpRotlim(double strain); + double negEnvlpRotlim(double strain); + + void positiveIncrement(double dStrain); + void negativeIncrement(double dStrain); +}; + +#endif diff --git a/SRC/material/uniaxial/limitState/PinchingLimitStateMaterial.cpp b/SRC/material/uniaxial/limitState/PinchingLimitStateMaterial.cpp index 2aca4bf30..5b128a9bd 100644 --- a/SRC/material/uniaxial/limitState/PinchingLimitStateMaterial.cpp +++ b/SRC/material/uniaxial/limitState/PinchingLimitStateMaterial.cpp @@ -61,7 +61,7 @@ OPS_PinchingLimitState(void) { if (numPinchingLimitStateMaterial == 0) { numPinchingLimitStateMaterial++; - opserr << "PinchingLimitStateMaterial unaxial material - Written by MRL UT Austin Copyright 2012 - Use at Your Peril\n"; + //opserr << "PinchingLimitStateMaterial unaxial material - Written by MRL UT Austin Copyright 2012 - Use at Your Peril\n"; } UniaxialMaterial *theMaterial = 0; diff --git a/SRC/material/uniaxial/limitState/limitCurve/RotationShearCurve.cpp b/SRC/material/uniaxial/limitState/limitCurve/RotationShearCurve.cpp index 31f508810..62343fd0d 100644 --- a/SRC/material/uniaxial/limitState/limitCurve/RotationShearCurve.cpp +++ b/SRC/material/uniaxial/limitState/limitCurve/RotationShearCurve.cpp @@ -58,7 +58,7 @@ void * OPS_RotationShearCurve(void) { if (shearCurveCount == 0) { - opserr << "RotationShearCurve limit curve - Written by MRL UT Austin Copyright 2012 - Use at your Own Peril \n"; + //opserr << "RotationShearCurve limit curve - Written by MRL UT Austin Copyright 2012 - Use at your Own Peril \n"; shearCurveCount++; } diff --git a/SRC/material/yieldSurface/evolution/NullEvolution.cpp b/SRC/material/yieldSurface/evolution/NullEvolution.cpp index 9516d7567..705480c29 100644 --- a/SRC/material/yieldSurface/evolution/NullEvolution.cpp +++ b/SRC/material/yieldSurface/evolution/NullEvolution.cpp @@ -110,7 +110,7 @@ int NullEvolution::getResponse(int responseID, Information & info) } /** No descriptions */ -Response * NullEvolution::setResponse(char * * argv, int argc, Information & info) +Response * NullEvolution::setResponse(char * * argv, int argc, OPS_Stream &output) { return 0; } diff --git a/SRC/material/yieldSurface/evolution/NullEvolution.h b/SRC/material/yieldSurface/evolution/NullEvolution.h index ccdf4e4cc..2e8811f68 100644 --- a/SRC/material/yieldSurface/evolution/NullEvolution.h +++ b/SRC/material/yieldSurface/evolution/NullEvolution.h @@ -36,7 +36,7 @@ class NullEvolution : public YS_Evolution { YS_Evolution* getCopy(); int getResponse(int responseID, Information & info); - Response* setResponse(char **argv, int argc, Information & info); + Response* setResponse(char **argv, int argc, OPS_Stream &output); int displaySelf(Renderer &theViewer, int displayMode, float fact) { return 0;} diff --git a/SRC/material/yieldSurface/evolution/YS_Evolution.h b/SRC/material/yieldSurface/evolution/YS_Evolution.h index 95eb95cd5..e6cd3cb95 100644 --- a/SRC/material/yieldSurface/evolution/YS_Evolution.h +++ b/SRC/material/yieldSurface/evolution/YS_Evolution.h @@ -37,7 +37,7 @@ class YS_Evolution : public TaggedObject, public MovableObject virtual int revertToLastCommit(void); virtual YS_Evolution *getCopy(void) = 0; - virtual Response *setResponse(char **argv, int argc, Information &info)=0; + virtual Response *setResponse(char **argv, int argc, OPS_Stream &output)=0; virtual int getResponse(int responseID, Information &info)=0; virtual int displaySelf(Renderer &theViewer, int displayMode, float fact)=0; diff --git a/SRC/material/yieldSurface/evolution/YS_Evolution2D.cpp b/SRC/material/yieldSurface/evolution/YS_Evolution2D.cpp index bc61b7438..f92f95d87 100644 --- a/SRC/material/yieldSurface/evolution/YS_Evolution2D.cpp +++ b/SRC/material/yieldSurface/evolution/YS_Evolution2D.cpp @@ -353,7 +353,7 @@ int YS_Evolution2D::displaySelf(Renderer &theViewer, int displayMode, float fact return -1; } -Response* YS_Evolution2D::setResponse(char **argv, int argc, Information &matInfo) +Response* YS_Evolution2D::setResponse(char **argv, int argc, OPS_Stream &output) { return 0; /* diff --git a/SRC/material/yieldSurface/evolution/YS_Evolution2D.h b/SRC/material/yieldSurface/evolution/YS_Evolution2D.h index b512f8706..85a98360c 100644 --- a/SRC/material/yieldSurface/evolution/YS_Evolution2D.h +++ b/SRC/material/yieldSurface/evolution/YS_Evolution2D.h @@ -21,7 +21,7 @@ class YS_Evolution2D : public YS_Evolution // Methods inherited virtual void Print(OPS_Stream &s, int flag =0) =0; virtual YS_Evolution *getCopy(void) = 0; - virtual Response *setResponse(char **argv, int argc, Information &info); + virtual Response *setResponse(char **argv, int argc, OPS_Stream &output); virtual int getResponse(int responseID, Information &info); virtual int displaySelf(Renderer &theViewer, int displayMode, float fact); diff --git a/SRC/material/yieldSurface/plasticHardeningMaterial/PlasticHardeningMaterial.cpp b/SRC/material/yieldSurface/plasticHardeningMaterial/PlasticHardeningMaterial.cpp index f961a28a9..03cc4e1ae 100644 --- a/SRC/material/yieldSurface/plasticHardeningMaterial/PlasticHardeningMaterial.cpp +++ b/SRC/material/yieldSurface/plasticHardeningMaterial/PlasticHardeningMaterial.cpp @@ -70,7 +70,7 @@ int PlasticHardeningMaterial::revertToStart (void) } -Response *PlasticHardeningMaterial::setResponse (char **argv, int argc, Information &matInformation) +Response *PlasticHardeningMaterial::setResponse (char **argv, int argc, OPS_Stream &output) { return 0; } diff --git a/SRC/material/yieldSurface/plasticHardeningMaterial/PlasticHardeningMaterial.h b/SRC/material/yieldSurface/plasticHardeningMaterial/PlasticHardeningMaterial.h index 989dc1dfc..5461d3069 100644 --- a/SRC/material/yieldSurface/plasticHardeningMaterial/PlasticHardeningMaterial.h +++ b/SRC/material/yieldSurface/plasticHardeningMaterial/PlasticHardeningMaterial.h @@ -26,7 +26,7 @@ class PlasticHardeningMaterial : public Material double getTrialValue(void); virtual PlasticHardeningMaterial *getCopy (void) = 0; - virtual Response *setResponse (char **argv, int argc, Information &matInformation); + virtual Response *setResponse (char **argv, int argc, OPS_Stream &output); virtual int getResponse (int responseID, Information &matInformation); virtual void Print(OPS_Stream &s, int flag =0); diff --git a/SRC/recorder/ElementRecorder.cpp b/SRC/recorder/ElementRecorder.cpp index 14ffcba32..1aa7d3b07 100644 --- a/SRC/recorder/ElementRecorder.cpp +++ b/SRC/recorder/ElementRecorder.cpp @@ -249,13 +249,14 @@ OPS_ElementRecorder() nargrem = 1 + OPS_GetNumRemainingInputArgs(); data = new const char *[nargrem]; data[0] = option; - argv = new char*[nargrem]; + //argv = new char*[nargrem]; char buffer[128]; for (int i = 1; i < nargrem; i++) { - argv[i] = new char[128]; + data[i] = new char[128]; // Turn everything in to a string for setResponse - data[i] = OPS_GetStringFromAll(buffer, 128); + //data[i] = OPS_GetStringFromAll(buffer, 128); + OPS_GetStringFromAll((char*)data[i], 128); } } } @@ -287,11 +288,11 @@ OPS_ElementRecorder() data, nargrem, echoTimeFlag, *domain, *theOutputStream, dT, &dofs); - if (argv != 0) { + if (data != 0) { for (int i=1; igetClassTag(); - - if (elem_type == ELE_TAG_Subdomain) + /* + skip element classes tht we don't want to record + */ + if (elem_type == ELE_TAG_Subdomain || + elem_type == ELE_TAG_ASDEmbeddedNodeElement) { - //Skip subdomains continue; } - ElementGeometryType::Enum geom_type; ElementIntegrationRuleType::Enum int_rule_type; getGeometryAndIntRuleByClassTag(elem_type, geom_type, int_rule_type); diff --git a/SRC/recorder/PVDRecorder.cpp b/SRC/recorder/PVDRecorder.cpp index 9a845fd0f..533c076d5 100644 --- a/SRC/recorder/PVDRecorder.cpp +++ b/SRC/recorder/PVDRecorder.cpp @@ -552,27 +552,27 @@ PVDRecorder::savePart0(int nodendf) // node displacement if(nodedata.disp) { // all displacement - this->indent(); - theFile<<"\n"; - this->incrLevel(); - for(int i=0; i<(int)nodes.size(); i++) { - const Vector& vel = nodes[i]->getTrialDisp(); - this->indent(); - for(int j=0; jdecrLevel(); - this->indent(); - theFile<<"\n"; + // this->indent(); + // theFile<<"\n"; + // this->incrLevel(); + // for(int i=0; i<(int)nodes.size(); i++) { + // const Vector& vel = nodes[i]->getTrialDisp(); + // this->indent(); + // for(int j=0; jdecrLevel(); + // this->indent(); + // theFile<<"\n"; // displacement this->indent(); @@ -972,7 +972,7 @@ PVDRecorder::savePartParticle(int pno, int bgtag, int nodendf) this->incrLevel(); for(int i=0; i<(int)particles.size(); i++) { this->indent(); - theFile<getTag()<decrLevel(); this->indent(); @@ -1449,27 +1449,27 @@ PVDRecorder::savePart(int partno, int ctag, int nodendf) // node displacement if(nodedata.disp) { // all displacement - this->indent(); - theFile<<"\n"; - this->incrLevel(); - for(int i=0; igetTrialDisp(); - this->indent(); - for(int j=0; jdecrLevel(); - this->indent(); - theFile<<"\n"; + // this->indent(); + // theFile<<"\n"; + // this->incrLevel(); + // for(int i=0; igetTrialDisp(); + // this->indent(); + // for(int j=0; jdecrLevel(); + // this->indent(); + // theFile<<"\n"; // displacement this->indent(); diff --git a/SRC/renderer/OpenGLRenderer.h b/SRC/renderer/OpenGLRenderer.h index 7e9d7ecc0..eee82b772 100644 --- a/SRC/renderer/OpenGLRenderer.h +++ b/SRC/renderer/OpenGLRenderer.h @@ -65,10 +65,9 @@ class OpenGLRenderer : public Renderer virtual int drawPoint(const Vector &, const Vector &rgb1, int tag = 0, int mode=0, int width = 1); virtual int drawLine(const Vector &, const Vector &, - float V1, float V2, int tag = 0, int mode = 0, int width = 1, int style = 1); + float V1, float V2, int tag = 0, int mode = 0); virtual int drawLine(const Vector &end1, const Vector &end2, - const Vector &rgb1, const Vector &rgb2, - int tag = 0, int mode = 0, int width = 1, int style = 1); + const Vector &rgb1, const Vector &rgb2, int tag = 0, int mode = 0); virtual int drawPolygon(const Matrix &points, const Vector &values, int tag = 0, int mode = 0); virtual int drawPolygon(const Matrix &points, const Matrix &rgbValues, int tag = 0, int mode = 0); @@ -90,6 +89,7 @@ class OpenGLRenderer : public Renderer virtual int setProjectionMode(const char *mode); // parallel or perspective virtual int setFillMode(const char *mode); // wire or fill + virtual int setLineWidth(int width); // width in pixels virtual int setPRP(float u, float v, float n); // eye location if // perspective, dirn to +ViewPlane if parallel @@ -130,6 +130,7 @@ class OpenGLRenderer : public Renderer Vector portWindow; // mapping to window - port window coords [-1,-1] to [1,1] int fillMode; // flag indicating fill mode + int lineWidth; // line width for drawing lines float viewData[16]; float projData[16]; diff --git a/SRC/renderer/OpenGlRenderer.cpp b/SRC/renderer/OpenGlRenderer.cpp index c59575c01..5cbf874dc 100644 --- a/SRC/renderer/OpenGlRenderer.cpp +++ b/SRC/renderer/OpenGlRenderer.cpp @@ -77,7 +77,7 @@ OpenGLRenderer::OpenGLRenderer(const char *_title, int _xLoc, int _yLoc, count(-1), theOutputFileName(0), theDevice(0), vrp(3), vuv(3), vpn(3), cop(3), ViewMat(4,4), - projectionMode(0), vpWindow(4), ProjMat(4,4), + projectionMode(0), lineWidth(2), vpWindow(4), ProjMat(4,4), portWindow(4) { @@ -121,7 +121,7 @@ OpenGLRenderer::OpenGLRenderer(const char *_title, int _xLoc, int _yLoc, count(-1), theOutputFileName(0), theDevice(0), vrp(3), vuv(3), vpn(3), cop(3), ViewMat(4,4), - projectionMode(0), vpWindow(4), ProjMat(4,4), + projectionMode(0), lineWidth(2), vpWindow(4), ProjMat(4,4), portWindow(4) { // set the WindowDevices title, height, wdth, xLoc and yLoc @@ -480,14 +480,13 @@ OpenGLRenderer::drawPoint(const Vector &pos1, const Vector &rgb, int tag, int mo int OpenGLRenderer::drawLine(const Vector &pos1, const Vector &pos2, - float V1, float V2, int tag, int mode, int width, int style) + float V1, float V2, int tag, int mode) { // open gl does a divide by zero error if points are the same - so check if (pos1(0) == pos2(0) && pos1(1) == pos2(1) && pos1(2) == pos2(2)) return 0; - width = 2; // S. Mazzoni - glLineWidth(width); + glLineWidth(lineWidth); glBegin(GL_LINES); float r, g, b; @@ -520,15 +519,13 @@ OpenGLRenderer::drawLine(const Vector &pos1, const Vector &pos2, int OpenGLRenderer::drawLine(const Vector &end1, const Vector &end2, - const Vector &rgb1, const Vector &rgb2, - int tag, int mode, int width, int style) + const Vector &rgb1, const Vector &rgb2, int tag, int mode) { // open gl does a divide by zero error if points are the same if (end1(0) == end2(0) && end1(1) == end2(1) && end1(2) == end2(2)) return 0; - width = 2; // S. Mazzoni - glLineWidth(width); + glLineWidth(lineWidth); glBegin(GL_LINES); float r, g, b; @@ -753,6 +750,13 @@ OpenGLRenderer::setFillMode(const char *newMode) return 0; } +int +OpenGLRenderer::setLineWidth(int width) +{ + lineWidth = width; + return 0; +} + // eye location int OpenGLRenderer::setPRP(float u, float v, float n){ diff --git a/SRC/renderer/Renderer.h b/SRC/renderer/Renderer.h index 08397273b..d8f2c3801 100644 --- a/SRC/renderer/Renderer.h +++ b/SRC/renderer/Renderer.h @@ -67,14 +67,10 @@ class Renderer virtual int drawPoint(const Vector &, float V1, int tag = 0, int mode = 0, int width = 1) =0; virtual int drawPoint(const Vector &, const Vector &rgb1, int tag = 0, int mode = 0, int width = 1) =0; - virtual int drawLine(const Vector &, const Vector &, float V1, float V2, int tag = 0, int mode = 0, - int width = 1, int style = 1) =0; - - + virtual int drawLine(const Vector &, const Vector &, + float V1, float V2, int tag = 0, int mode = 0) =0; virtual int drawLine(const Vector &end1, const Vector &end2, - const Vector &rgb1, const Vector &rgb2, - int tag = 0, int mode = 0, - int width = 1, int style = 1) =0; + const Vector &rgb1, const Vector &rgb2,int tag = 0, int mode = 0) =0; virtual int drawCube(const Matrix &points, const Vector &values, int tag = 0, int mode = 0); @@ -106,6 +102,7 @@ class Renderer virtual int setProjectionMode(const char *mode) =0; //parallel or perspective virtual int setFillMode(const char *mode) =0; // wire or fill + virtual int setLineWidth(int width) = 0; // line width virtual int setPRP(float u, float v, float n) =0; // eye location if // perspective, dirn to +ViewPlane if parallel diff --git a/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMLinSOE.cpp b/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMLinSOE.cpp index a09f4b3ca..11878f7bb 100644 --- a/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMLinSOE.cpp +++ b/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMLinSOE.cpp @@ -55,7 +55,6 @@ using std::nothrow; #include #include #include -#include #include #ifdef _PARALLEL_INTERPRETERS #include @@ -65,7 +64,7 @@ PFEMLinSOE::PFEMLinSOE(PFEMSolver &the_Solver) :LinearSOE(the_Solver, LinSOE_TAGS_PFEMLinSOE), M(0), Gft(0), Git(0), L(0), Qt(0), X(), B(), Mhat(), Mf(), - dofType(), dofID(), assemblyFlag(0), stage(0) + dofType(), dofID() { the_Solver.setLinearSOE(*this); } @@ -75,7 +74,7 @@ PFEMLinSOE::PFEMLinSOE() :LinearSOE(LinSOE_TAGS_PFEMLinSOE), M(0), Gft(0), Git(0), L(0), Qt(0), X(), B(), Mhat(), Mf(), - dofType(), dofID(), assemblyFlag(0), stage(0) + dofType(), dofID() { } @@ -84,7 +83,7 @@ PFEMLinSOE::PFEMLinSOE(int classTag) :LinearSOE(classTag), M(0), Gft(0), Git(0), L(0), Qt(0), X(), B(), Mhat(), Mf(), - dofType(), dofID(), assemblyFlag(0), stage(0) + dofType(), dofID() { } @@ -94,9 +93,8 @@ PFEMLinSOE::PFEMLinSOE(PFEMSolver &the_Solver, int classTag) :LinearSOE(the_Solver, classTag), M(0), Gft(0), Git(0), L(0), Qt(0), X(), B(), Mhat(), Mf(), - dofType(), dofID(), assemblyFlag(0), stage(0) + dofType(), dofID() { - } @@ -119,7 +117,6 @@ PFEMLinSOE::solve(void) return res; } - assemblyFlag = 1; return 0; } @@ -153,16 +150,6 @@ PFEMLinSOE::setSize(Graph &theGraph) // set matrix IDs result = this->setMatIDs(theGraph, Ssize, Fsize, Isize, Psize, Pisize); - - // reset flags - assemblyFlag = 0; - - BackgroundMesh& bgmesh = OPS_getBgMesh(); - bool pressureonce = bgmesh.isPressureOnce(); - stage = 0; - if (pressureonce) { - stage = 1; - } // invoke setSize() on the Solver LinearSOESolver *the_Solver = this->getSolver(); @@ -192,8 +179,6 @@ PFEMLinSOE::addA(const Matrix &m, const ID &id, double fact) return -1; } - bool hasFluid = !skipFluid(); - int Ssize = M->n - Git->n; if (fact == 1.0) { // do not need to multiply @@ -204,9 +189,9 @@ PFEMLinSOE::addA(const Matrix &m, const ID &id, double fact) int colid = dofID(col); // column id if(coltype == 4) { // diganol of Mhat - if (hasFluid) Mhat(colid) += m(i,i); + Mhat(colid) += m(i,i); } else if(coltype == 1) { // diganol of Mf - if (hasFluid) Mf(colid) += m(i,i); + Mf(colid) += m(i,i); } if(coltype==4 || coltype<0) continue; @@ -234,13 +219,13 @@ PFEMLinSOE::addA(const Matrix &m, const ID &id, double fact) mat = M; rowid += Ssize; } else if(rowtype==3 && coltype==1) { // Gft - if (hasFluid) mat = Gft; + mat = Gft; } else if(rowtype==3 && coltype==2) { // Git mat = Git; } else if(rowtype==3 && coltype==3) { // L - if (hasFluid) mat = L; + mat = L; } else if(rowtype==4 && coltype==3) { // Qt - if (hasFluid) mat = Qt; + mat = Qt; } if(mat == 0) continue; @@ -262,9 +247,9 @@ PFEMLinSOE::addA(const Matrix &m, const ID &id, double fact) int colid = dofID(col); // column id if(coltype == 4) { // diganol of Mhat - if (hasFluid) Mhat(colid) += fact*m(i,i); + Mhat(colid) += fact*m(i,i); } else if(coltype == 1) { // diganol of Mf - if (hasFluid) Mf(colid) += fact*m(i,i); + Mf(colid) += fact*m(i,i); } if(coltype==4 || coltype<0) continue; @@ -292,13 +277,13 @@ PFEMLinSOE::addA(const Matrix &m, const ID &id, double fact) mat = M; rowid += Ssize; } else if(rowtype==3 && coltype==1) { // Gft - if (hasFluid) mat = Gft; + mat = Gft; } else if(rowtype==3 && coltype==2) { // Git mat = Git; } else if(rowtype==3 && coltype==3) { // L - if (hasFluid) mat = L; + mat = L; } else if(rowtype==4 && coltype==3) { // Qt - if (hasFluid) mat = Qt; + mat = Qt; } if(mat == 0) continue; @@ -393,18 +378,15 @@ PFEMLinSOE::zeroA(void) Git->x[i] = 0.0; // zero fluid part - bool hasFluid = !skipFluid(); - if (hasFluid) { - for (int i = 0; i < Gft->nzmax; i++) - Gft->x[i] = 0.0; - for (int i = 0; i < L->nzmax; i++) - L->x[i] = 0.0; - for (int i = 0; i < Qt->nzmax; i++) - Qt->x[i] = 0.0; - - Mhat.Zero(); - Mf.Zero(); - } + for (int i = 0; i < Gft->nzmax; i++) + Gft->x[i] = 0.0; + for (int i = 0; i < L->nzmax; i++) + L->x[i] = 0.0; + for (int i = 0; i < Qt->nzmax; i++) + Qt->x[i] = 0.0; + + Mhat.Zero(); + Mf.Zero(); } void @@ -750,13 +732,6 @@ PFEMLinSOE::isFluidID(const ID &id) const return fluid; } -bool -PFEMLinSOE::skipFluid() const -{ - BackgroundMesh& bgmesh = OPS_getBgMesh(); - return assemblyFlag==1 && bgmesh.isDispOn()==false && bgmesh.isFastAssembly(); -} - void PFEMLinSOE::saveK(OPS_Stream& output) { if (M == 0) return; output << "sparse matrix <" << M->m << ", " << M->n << "> with " diff --git a/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMLinSOE.h b/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMLinSOE.h index 9db5ef6e1..1cb93ea99 100644 --- a/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMLinSOE.h +++ b/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMLinSOE.h @@ -87,9 +87,6 @@ class PFEMLinSOE : public LinearSOE friend class PFEMSolver_LumpM; virtual bool isFluidID(const ID& id) const; - virtual bool skipFluid() const; - virtual int getStage() const {return stage;} - virtual void setStage(int s) {stage = s;} void saveK(OPS_Stream& output); private: @@ -102,8 +99,6 @@ class PFEMLinSOE : public LinearSOE cs* M, *Gft, *Git, *L, *Qt; Vector X, B, Mhat, Mf; ID dofType, dofID; - int assemblyFlag; - int stage; }; #endif diff --git a/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMSolver_Mumps.cpp b/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMSolver_Mumps.cpp index e54af79e5..1a171c774 100644 --- a/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMSolver_Mumps.cpp +++ b/SRC/system_of_eqn/linearSOE/sparseGEN/PFEMSolver_Mumps.cpp @@ -181,7 +181,6 @@ PFEMSolver_Mumps::solve() Vector& B = theSOE->B; ID& dofType = theSOE->dofType; ID& dofID = theSOE->dofID; - int stage = theSOE->stage; int Msize = M->n; int Isize = Git->n; @@ -191,7 +190,7 @@ PFEMSolver_Mumps::solve() int size = X.Size(); // numeric LU factorization of M - if(Msize > 0 && stage!=2) { + if(Msize > 0) { sid.job = JOB_FACTORIZATION; dmumps_c(&sid); @@ -205,8 +204,6 @@ PFEMSolver_Mumps::solve() std::vector deltaV1; if(Msize > 0) { deltaV1.assign(Msize, 0.0); - } - if (Msize>0 && stage!=2) { // rsi for (int i = 0; i < size; i++) { // row int rowtype = dofType(i); // row type @@ -231,8 +228,6 @@ PFEMSolver_Mumps::solve() std::vector deltaVf1; if (Fsize > 0) { deltaVf1.assign(Fsize,0.0); - } - if(Fsize>0 && stage!=2) { // rf for(int i=0; i0 && (stage==0||stage==2)) { + if(Fsize>0) { Gf = cs_transpose(Gft, 1); } - if(Isize>0 && (stage==0||stage==2)) { + if(Isize>0) { Gi = cs_transpose(Git, 1); } @@ -265,18 +260,18 @@ PFEMSolver_Mumps::solve() deltaP.assign(Psize, 0.0); rhsP.assign(Psize, 0.0); } - if(Psize>0 && (stage==2||stage==0)) { + if(Psize>0) { // S = L + Git*Mi{-1}*Gi + Gft*Mf{-1}*Gf cs* S = 0; // Gft*deltaVf1 - if(Fsize > 0 && stage==0) { + if(Fsize > 0) { cs_gaxpy(Gft, &deltaVf1[0], &rhsP[0]); } // Git*deltaVi1 - if(Isize > 0 && stage==0) { + if(Isize > 0) { cs_gaxpy(Git, &deltaV1[0]+Ssize, &rhsP[0]); } @@ -290,7 +285,7 @@ PFEMSolver_Mumps::solve() } // Git*Mi{-1}*Gi - if (Isize > 0 && stage==0) { + if (Isize > 0) { std::vector irhs_ptr(Msize+1,1); std::vector irhs_row(Isize*Isize); std::vector rhs_val(Isize*Isize); @@ -346,40 +341,6 @@ PFEMSolver_Mumps::solve() S = cs_multiply(S1, Gi); cs_spfree(S1); cs_spfree(Bi); - - } else if (Isize > 0 && stage==2) { - - // get Mi - Vector Mi; - Mi.resize(Isize); - Mi.Zero(); - - for (int i = 0; i < size; ++i) { - int coltype = dofType(i); - int colid = dofID(i); - if (coltype == 2) { - int cid = colid + Ssize; - for (int k = M->p[cid]; k < M->p[cid+1]; ++k) { - Mi(colid) += M->x[k]; - } - } - } - - // Gi*Mi{-1}*Gi - for(int j=0; jp[j]; kp[j+1]; k++) { - Gi->x[k] /= Mi(Gi->i[k]); - } - } - cs* S1 = cs_multiply(Git, Gi); - if(S == 0) { - S = S1; - } else { - cs* S2 = cs_add(S, S1, 1.0, 1.0); - cs_spfree(S); - cs_spfree(S1); - S = S2; - } } // Gft*Mf{-1}*Gf @@ -473,7 +434,7 @@ PFEMSolver_Mumps::solve() if (Msize > 0) { deltaV.assign(Msize, 0.0); } - if(Isize > 0 && stage==0) { + if(Isize > 0) { // Gi*deltaP if(Psize > 0) { cs_gaxpy(Gi, &deltaP[0], &deltaV[0]+Ssize); @@ -497,7 +458,7 @@ PFEMSolver_Mumps::solve() if(Fsize > 0) { deltaVf.assign(Fsize, 0.0); } - if(Fsize > 0 && stage==0) { + if(Fsize > 0) { if(Psize > 0) { cs_gaxpy(Gf, &deltaP[0], &deltaVf[0]); } @@ -507,10 +468,10 @@ PFEMSolver_Mumps::solve() } // delete Gi, Gf - if(Fsize>0 && (stage==0||stage==2)) { + if(Fsize>0) { cs_spfree(Gf); } - if(Isize>0 && (stage==0||stage==2)) { + if(Isize>0) { cs_spfree(Gi); } diff --git a/SRC/tcl/TclFeViewer.cpp b/SRC/tcl/TclFeViewer.cpp index fd5b331bc..7276793d7 100644 --- a/SRC/tcl/TclFeViewer.cpp +++ b/SRC/tcl/TclFeViewer.cpp @@ -91,7 +91,7 @@ TclFeViewer_setProjectionMode(ClientData clientData, Tcl_Interp *interp, int arg TCL_Char **argv); int TclFeViewer_setFillMode(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv); + TCL_Char **argv); int TclFeViewer_setPRP(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); @@ -502,7 +502,7 @@ TclFeViewer::setPortWindow(float left, float right, float bottom, float top) } int -TclFeViewer::displayModel(int eleFlag, int nodeFlag, float displayFact) +TclFeViewer::displayModel(int eleFlag, int nodeFlag, float displayFact, int lineWidth) { #ifdef _NOGRAPHICS // if no graphics .. just return 0 @@ -512,6 +512,7 @@ TclFeViewer::displayModel(int eleFlag, int nodeFlag, float displayFact) theEleMode = eleFlag; theNodeMode = nodeFlag; theDisplayFact = displayFact; + theRenderer->setLineWidth(lineWidth); return this->record(0, 0.0); #endif } @@ -885,8 +886,8 @@ TclFeViewer_displayModel(ClientData clientData, Tcl_Interp *interp, int argc, return TCL_OK; // check number of args - if (argc != 3 && argc != 4) { - opserr << "WARNING args incorrect - display eleMode fact\n"; + if (argc < 3 || argc > 5) { + opserr << "WARNING args incorrect - display eleMode displayFact \n"; return TCL_ERROR; } @@ -905,24 +906,32 @@ TclFeViewer_displayModel(ClientData clientData, Tcl_Interp *interp, int argc, theTclFeViewer->displayModel(displayMode, -1, float(displayFact)); return TCL_OK; } else { - - int eleFlag, nodeFlag; + int eleMode, nodeMode; double displayFact; - if (Tcl_GetInt(interp, argv[1], &eleFlag) != TCL_OK) { - opserr << "WARNING invalid displayMode - display eleFlag nodeFlag displayFact\n"; + if (Tcl_GetInt(interp, argv[1], &eleMode) != TCL_OK) { + opserr << "WARNING invalid eleMode - display eleMode nodeMode displayFact\n"; return TCL_ERROR; } - if (Tcl_GetInt(interp, argv[2], &nodeFlag) != TCL_OK) { - opserr << "WARNING invalid displayMode - display eleFlag nodeFlahg displayFact\n"; + if (Tcl_GetInt(interp, argv[2], &nodeMode) != TCL_OK) { + opserr << "WARNING invalid nodeMode - display eleMode nodeMode displayFact\n"; return TCL_ERROR; } if (Tcl_GetDouble(interp, argv[3], &displayFact) != TCL_OK) { - opserr << "WARNING invalid displayMode - display eleFlag nodeFlahg displayFact\n"; + opserr << "WARNING invalid displayFact - display eleMode nodeMode displayFact\n"; return TCL_ERROR; } - - theTclFeViewer->displayModel(eleFlag, nodeFlag, float(displayFact)); - return TCL_OK; + // line width + if (argc == 5) { + int lineWidth; + if (Tcl_GetInt(interp, argv[4], &lineWidth) != TCL_OK) { + opserr << "WARNING invalid lineWidth - display eleMode nodeMode displayFact lineWidth\n"; + return TCL_ERROR; + } + theTclFeViewer->displayModel(eleMode, nodeMode, float(displayFact), lineWidth); + return TCL_OK; + } + theTclFeViewer->displayModel(eleMode, nodeMode, float(displayFact)); + return TCL_OK; } #endif } diff --git a/SRC/tcl/TclFeViewer.h b/SRC/tcl/TclFeViewer.h index f54abea31..a76e2cabc 100644 --- a/SRC/tcl/TclFeViewer.h +++ b/SRC/tcl/TclFeViewer.h @@ -75,8 +75,8 @@ class TclFeViewer : public Recorder int setPlaneDist(float, float); // location of // near, view & far clipping planes - int setProjectionMode(const char *); // - int setFillMode(const char *); // 1 = wire, otherwise fill + int setProjectionMode(const char *); // "parallel" for parallel projection (default), "perspective" for perspective. + int setFillMode(const char *); // "wire" for wire-frame (default), "fill" to fill polygons int setPRP(float, float, float); // eye location, global coords @@ -85,7 +85,7 @@ class TclFeViewer : public Recorder // methods invoked on the FE_Viewer - int displayModel(int eleFlag, int nodeFlag, float displayFact); + int displayModel(int eleFlag, int nodeFlag, float displayFact, int lineWidth = 2); // default line width set here. int clearImage(void); int saveImage(const char *fileName); int saveImage(const char *imageName, const char *fileName); diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index 49234cbed..7d2561e80 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -75,6 +75,7 @@ using std::ofstream; #include bool OPS_suppressOpenSeesOutput = false; +bool OPS_showHeader = true; StandardStream sserr; OPS_Stream *opserrPtr = &sserr; @@ -194,6 +195,7 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp #include //SAJalali extern void *OPS_NewtonRaphsonAlgorithm(void); +extern void *OPS_ExpressNewton(void); extern void *OPS_ModifiedNewton(void); extern void *OPS_NewtonHallM(void); @@ -204,6 +206,7 @@ extern void *OPS_AlphaOS(void); extern void *OPS_AlphaOS_TP(void); extern void *OPS_AlphaOSGeneralized(void); extern void *OPS_AlphaOSGeneralized_TP(void); +extern void *OPS_ExplicitDifference(void); extern void *OPS_CentralDifference(void); extern void *OPS_CentralDifferenceAlternative(void); extern void *OPS_CentralDifferenceNoDamping(void); @@ -1017,6 +1020,17 @@ int OpenSeesAppInit(Tcl_Interp *interp) { Tcl_CreateCommand(interp, "retainedDOFs", &retainedDOFs, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + Tcl_CreateCommand(interp, "getNumElements", &getNumElements, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "getEleClassTags", &getEleClassTags, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "getEleLoadClassTags", &getEleLoadClassTags, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "getEleLoadTags", &getEleLoadTags, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "getEleLoadData", &getEleLoadData, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "sdfResponse", &sdfResponse, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); @@ -2252,19 +2266,24 @@ printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) FileStream outputFile; OPS_Stream *output = &opserr; + bool ret = false; int currentArg = 1; + while (currentArg < argc) { + if ((strcmp(argv[currentArg], "file") == 0) || + (strcmp(argv[currentArg], "-file") == 0)) { + currentArg++; - if (argc > 2) { - if ((strcmp(argv[currentArg],"file") == 0) || - (strcmp(argv[currentArg],"-file") == 0)) { - currentArg++; - - if (outputFile.setFile(argv[currentArg]) != 0) { - opserr << "print .. - failed to open file: " << argv[currentArg] << endln; - return TCL_ERROR; + if (outputFile.setFile(argv[currentArg]) != 0) { + opserr << "print .. - failed to open file: " << argv[currentArg] << endln; + return TCL_ERROR; + } + output = &outputFile; } - output = &outputFile; - } + else if ((strcmp(argv[currentArg], "ret") == 0) || + (strcmp(argv[currentArg], "-ret") == 0)) { + ret = true; + } + currentArg++; } if (theSOE != 0) { if (theStaticIntegrator != 0) @@ -2274,13 +2293,27 @@ printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) const Matrix *A = theSOE->getA(); if (A != 0) { - *output << *A; + if (ret) { + int n = A->noRows(); + int m = A->noCols(); + if (n * m > 0) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + char buffer[40]; + sprintf(buffer, "%.10e ", (*A)(i, j)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + } + } + else { + *output << *A; + // close the output file + outputFile.close(); + } } } - // close the output file - outputFile.close(); - return res; } @@ -2293,19 +2326,24 @@ printB(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) OPS_Stream *output = &opserr; // bool done = false; + bool ret = false; int currentArg = 1; + while (currentArg < argc) { + if ((strcmp(argv[currentArg], "file") == 0) || + (strcmp(argv[currentArg], "-file") == 0)) { + currentArg++; - if (argc > 2) { - if ((strcmp(argv[currentArg],"file") == 0) || - (strcmp(argv[currentArg],"-file") == 0)) { - currentArg++; - - if (outputFile.setFile(argv[currentArg]) != 0) { - opserr << "print .. - failed to open file: " << argv[currentArg] << endln; - return TCL_ERROR; + if (outputFile.setFile(argv[currentArg]) != 0) { + opserr << "print .. - failed to open file: " << argv[currentArg] << endln; + return TCL_ERROR; + } + output = &outputFile; } - output = &outputFile; - } + else if ((strcmp(argv[currentArg], "ret") == 0) || + (strcmp(argv[currentArg], "-ret") == 0)) { + ret = true; + } + currentArg++; } if (theSOE != 0) { if (theStaticIntegrator != 0) @@ -2314,12 +2352,23 @@ printB(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) theTransientIntegrator->formUnbalance(); const Vector &b = theSOE->getB(); - *output << b; + if (ret) { + int n = b.Size(); + if (n > 0) { + for (int i = 0; i < n; i++) { + char buffer[40]; + sprintf(buffer, "%.10e ", b(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + } + else { + *output << b; + // close the output file + outputFile.close(); + } } - // close the output file - outputFile.close(); - return res; } @@ -3536,9 +3585,10 @@ specifySOE(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) #endif return TCL_OK; + } else { + opserr << "WARNING system " << argv[1] << " is unknown or not installed\n"; + return TCL_ERROR; } - - return TCL_ERROR; } @@ -4060,24 +4110,13 @@ specifyAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, } 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) + void *theNewtonAlgo = OPS_ExpressNewton(); + if (theNewtonAlgo == 0) 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); + + theNewAlgo = (EquiSolnAlgo *)theNewtonAlgo; + if (theTest != 0) + theNewAlgo->setConvergenceTest(theTest); } else { @@ -5201,12 +5240,19 @@ specifyIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, theTransientAnalysis->setIntegrator(*theTransientIntegrator); } + else if (strcmp(argv[1],"ExplicitDifference") == 0) { + theTransientIntegrator = (TransientIntegrator *)OPS_ExplicitDifference(); + + if (theTransientAnalysis != 0) + theTransientAnalysis->setIntegrator(*theTransientIntegrator); + } + else if (strcmp(argv[1],"CentralDifference") == 0) { theTransientIntegrator = (TransientIntegrator *)OPS_CentralDifference(); if (theTransientAnalysis != 0) theTransientAnalysis->setIntegrator(*theTransientIntegrator); - } + } else if (strcmp(argv[1],"CentralDifferenceAlternative") == 0) { theTransientIntegrator = (TransientIntegrator *)OPS_CentralDifferenceAlternative(); @@ -7084,7 +7130,7 @@ eleType(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) return TCL_ERROR; } - char buffer[20]; + char buffer[80]; Element* theElement = theDomain.getElement(tag); if (theElement == 0) { opserr << "WARNING eleType ele " << tag << " not found" << endln; @@ -8877,6 +8923,224 @@ getNP(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) return TCL_OK; } +int +getNumElements(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + char buffer[20]; + + sprintf(buffer, "%d ", theDomain.getNumElements()); + Tcl_AppendResult(interp, buffer, NULL); + + return TCL_OK; +} + +int +getEleClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + + if (argc == 1) { + Element *theEle; + ElementIter &eleIter = theDomain.getElements(); + + char buffer[20]; + + while ((theEle = eleIter()) != 0) { + sprintf(buffer, "%d ", theEle->getClassTag()); + Tcl_AppendResult(interp, buffer, NULL); + } + } else if (argc == 2) { + int eleTag; + + if (Tcl_GetInt(interp, argv[1], &eleTag) != TCL_OK) { + opserr << "WARNING getParamValue -- could not read paramTag \n"; + return TCL_ERROR; + } + + Element *theEle = theDomain.getElement(eleTag); + + char buffer[20]; + + sprintf(buffer, "%d ", theEle->getClassTag()); + Tcl_AppendResult(interp, buffer, NULL); + + } else { + opserr << "WARNING want - getEleClassTags \n" << endln; + return TCL_ERROR; + } + + return TCL_OK; +} + +int +getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + + if (argc == 1) { + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain.getLoadPatterns(); + + char buffer[20]; + + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad *theLoad; + + while ((theLoad = theEleLoads()) != 0) { + sprintf(buffer, "%d ", theLoad->getClassTag()); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + } else if (argc == 2) { + int patternTag; + + if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { + opserr << "WARNING getEleLoadClassTags -- could not read patternTag\n"; + return TCL_ERROR; + } + + LoadPattern *thePattern = theDomain.getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadClassTags\n"; + return TCL_ERROR; + } + + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + char buffer[20]; + + while ((theLoad = theEleLoads()) != 0) { + sprintf(buffer, "%d ", theLoad->getClassTag()); + Tcl_AppendResult(interp, buffer, NULL); + } + + } else { + opserr << "WARNING want - getEleLoadClassTags \n" << endln; + return TCL_ERROR; + } + + return TCL_OK; +} + +int +getEleLoadTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + + if (argc == 1) { + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain.getLoadPatterns(); + + char buffer[20]; + + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad *theLoad; + + while ((theLoad = theEleLoads()) != 0) { + sprintf(buffer, "%d ", theLoad->getElementTag()); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + } else if (argc == 2) { + int patternTag; + + if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { + opserr << "WARNING getEleLoadTags -- could not read patternTag \n"; + return TCL_ERROR; + } + + LoadPattern *thePattern = theDomain.getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadTags\n"; + return TCL_ERROR; + } + + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + char buffer[20]; + + while ((theLoad = theEleLoads()) != 0) { + sprintf(buffer, "%d ", theLoad->getElementTag()); + Tcl_AppendResult(interp, buffer, NULL); + } + + } else { + opserr << "WARNING want - getEleLoadTags \n" << endln; + return TCL_ERROR; + } + + return TCL_OK; +} + +int +getEleLoadData(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + + if (argc == 1) { + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain.getLoadPatterns(); + + char buffer[40]; + int typeEL; + + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter &theEleLoads = thePattern->getElementalLoads(); + ElementalLoad *theLoad; + + while ((theLoad = theEleLoads()) != 0) { + const Vector &eleLoadData = theLoad->getData(typeEL, 1.0); + + int eleLoadDataSize = eleLoadData.Size(); + opserr << "eleLoadDataSize: "<< eleLoadDataSize << "\n"; + for (int i = 0; i < eleLoadDataSize; i++) { + sprintf(buffer, "%35.20f ", eleLoadData(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + } + + } else if (argc == 2) { + int patternTag; + + if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { + opserr << "WARNING getEleLoadData -- could not read patternTag \n"; + return TCL_ERROR; + } + + LoadPattern *thePattern = theDomain.getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadData\n"; + return TCL_ERROR; + } + + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + int typeEL; + char buffer[40]; + + while ((theLoad = theEleLoads()) != 0) { + const Vector &eleLoadData = theLoad->getData(typeEL, 1.0); + + int eleLoadDataSize = eleLoadData.Size(); + for (int i = 0; i < eleLoadDataSize; i++) { + sprintf(buffer, "%35.20f ", eleLoadData(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + + } + + } else { + opserr << "WARNING want - getEleLoadTags \n" << endln; + return TCL_ERROR; + } + + return TCL_OK; +} + int getEleTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { diff --git a/SRC/tcl/commands.h b/SRC/tcl/commands.h index 02e949fa7..e53269397 100644 --- a/SRC/tcl/commands.h +++ b/SRC/tcl/commands.h @@ -281,6 +281,20 @@ int sensitivityIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); // AddingSensitivity:END /////////////////////////////////////////////////// +int +getNumElements(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); + +int +getEleClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); + +int +getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); + +int +getEleLoadTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); + +int +getEleLoadData(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); int startTimer(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); diff --git a/SRC/tcl/tclMain.cpp b/SRC/tcl/tclMain.cpp index daf4bbd35..0a1432ea3 100644 --- a/SRC/tcl/tclMain.cpp +++ b/SRC/tcl/tclMain.cpp @@ -205,6 +205,7 @@ char *TclGetStartupScriptFileName() */ extern bool OPS_suppressOpenSeesOutput; +extern bool OPS_showHeader; void g3TclMain(int argc, char **argv, Tcl_AppInitProc * appInitProc, int rank, int np) @@ -224,9 +225,13 @@ g3TclMain(int argc, char **argv, Tcl_AppInitProc * appInitProc, int rank, int np DummyStream dummy; for (int i=0; i Disabled - ..\..\..\src\element\RockingBC;..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files (x86)\tcl;c:\Program Files (x86)\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\element\RockingBC;..\..\..\src\element\CEqElement;..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files (x86)\tcl;c:\Program Files (x86)\tcl\include;%(AdditionalIncludeDirectories) _DEBUG;WIN32;_LIB;_WGL;_TCL85;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -76,7 +76,7 @@ OnlyExplicitInline - ..\..\..\src\element\RockingBC;..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files (x86)\tcl;c:\Program Files (x86)\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\element\RockingBC;..\..\..\src\element\CEqElement;..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files (x86)\tcl;c:\Program Files (x86)\tcl\include;%(AdditionalIncludeDirectories) NDEBUG;WIN32;_LIB;_WGL;_TCL85;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreaded @@ -108,6 +108,7 @@ + @@ -379,6 +380,7 @@ + diff --git a/Win32/proj/element/element.vcxproj.filters b/Win32/proj/element/element.vcxproj.filters index a085fee5e..6aedc5235 100644 --- a/Win32/proj/element/element.vcxproj.filters +++ b/Win32/proj/element/element.vcxproj.filters @@ -129,6 +129,9 @@ {91ebcb15-2aac-4ce7-ad6a-0b8c7b83b286} + + {0e9b8d94-5562-43c8-a721-4ab2cc9c0edf} + {b9971b16-c2ff-443f-ab28-9022482c25ed} @@ -920,6 +923,9 @@ RockingBC + + CEqElement + elasticBeamColumn @@ -1651,6 +1657,9 @@ RockingBC + + CEqElement + elasticBeamColumn diff --git a/Win64/proj/analysis/analysis.vcxproj b/Win64/proj/analysis/analysis.vcxproj index 195b95a20..34f872941 100644 --- a/Win64/proj/analysis/analysis.vcxproj +++ b/Win64/proj/analysis/analysis.vcxproj @@ -104,7 +104,7 @@ Disabled - ..\..\..\src\optimization\domain;..\..\..\src\optimization\domain\component;..\..\..\src\domain\pattern;..\..\..\src\coordTransformation;..\..\..\src\api;..\..\..\SRC\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\tagged\storage;..\..\..\src\tagged;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm\domainDecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\analysis\dof_grp;..\..\..\src\matrix;..\..\..\src\analysis\model\simple;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\analysis\fe_ele;..\..\..\src\nDarray;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\fesensitivity;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\optimization\domain;..\..\..\src\optimization\domain\component;..\..\..\src\domain\pattern;..\..\..\src\coordTransformation;..\..\..\src\api;..\..\..\SRC\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\tagged\storage;..\..\..\src\tagged;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm\domainDecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\analysis\dof_grp;..\..\..\src\matrix;..\..\..\src\analysis\model\simple;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\analysis\fe_ele;..\..\..\src\nDarray;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\fesensitivity;..\..\..\other\CSPARSE;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) _DEBUG;WIN32;_LIB;_RELIABILITY;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -169,7 +169,7 @@ Speed true true - ..\..\..\src\optimization\domain;..\..\..\src\optimization\domain\component;..\..\..\src\domain\pattern;..\..\..\src\coordTransformation;..\..\..\src\api;..\..\..\SRC\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\tagged\storage;..\..\..\src\tagged;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm\domainDecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\analysis\dof_grp;..\..\..\src\matrix;..\..\..\src\analysis\model\simple;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\analysis\fe_ele;..\..\..\src\nDarray;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\fesensitivity;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\optimization\domain;..\..\..\src\optimization\domain\component;..\..\..\src\domain\pattern;..\..\..\src\coordTransformation;..\..\..\src\api;..\..\..\SRC\analysis\algorithm\equiSolnAlgo\accelerator;..\..\..\src\tagged\storage;..\..\..\src\tagged;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm\domainDecompAlgo;..\..\..\src\analysis\algorithm\eigenAlgo;..\..\..\src\system_of_eqn\eigenSOE;..\..\..\src\handler;..\..\..\src\domain\domain\single;..\..\..\src\convergenceTest;..\..\..\src\analysis\analysis;..\..\..\src\recorder;..\..\..\src\analysis\algorithm\equiSolnAlgo;..\..\..\src\analysis\algorithm;..\..\..\src\system_of_eqn;..\..\..\src\system_of_eqn\linearSOE;..\..\..\src\system_of_eqn\linearSOE\fullGEN;..\..\..\src\graph\graph;..\..\..\src\graph\numberer;..\..\..\src\analysis\numberer;..\..\..\src\analysis\fe_ele\transformation;..\..\..\src\analysis\fe_ele\lagrange;..\..\..\src\analysis\fe_ele\penalty;..\..\..\src\actor\objectBroker;..\..\..\src\actor\channel;..\..\..\src\utility;..\..\..\src\domain\subdomain;..\..\..\src\domain\constraints;..\..\..\src\domain\component;..\..\..\src\domain\node;..\..\..\src\element;..\..\..\src\analysis\dof_grp;..\..\..\src\matrix;..\..\..\src\analysis\model\simple;..\..\..\src\domain\domain;..\..\..\src\analysis\model;..\..\..\src;..\..\..\src\actor\actor;..\..\..\src\analysis\handler;..\..\..\src\analysis\fe_ele;..\..\..\src\nDarray;..\..\..\src\reliability\domain\components;..\..\..\src\reliability\domain\filter;..\..\..\src\reliability\domain\modulatingFunction;..\..\..\src\reliability\domain\performanceFunction;..\..\..\src\reliability\domain\spectrum;..\..\..\src\reliability\fesensitivity;..\..\..\other\CSPARSE;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) NDEBUG;WIN32;_LIB;_RELIABILITY;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreadedDLL diff --git a/Win64/proj/element/element.vcxproj b/Win64/proj/element/element.vcxproj index 0e7ef7c25..0d464e9f3 100644 --- a/Win64/proj/element/element.vcxproj +++ b/Win64/proj/element/element.vcxproj @@ -75,7 +75,7 @@ Disabled - ..\..\..\src\element\RockingBC;..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\RockingBC;..\..\..\src\element\CEqElement;..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) _DEBUG;WIN32;_LIB;_WGL;_TCL85;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);_HAVE_PML_;_HAVE_PML EnableFastChecks MultiThreadedDebug @@ -104,7 +104,7 @@ Disabled - ..\..\..\src\element\RockingBC;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\RockingBC;..\..\..\src\element\CEqElement;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) _DEBUG;WIN32;_LIB;_WGL;_TCL85;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);_HAVE_PML_;_HAVE_PML EnableFastChecks MultiThreadedDebugDLL @@ -133,7 +133,7 @@ OnlyExplicitInline - ..\..\..\src\element\RockingBC;..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\RockingBC;..\..\..\src\element\CEqElement;..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) NDEBUG;WIN32;_LIB;_WGL;_TCL85;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);_HAVE_PML_;_HAVE_PML true MultiThreaded @@ -161,7 +161,7 @@ OnlyExplicitInline - ..\..\..\src\element\RockingBC;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\element\mixedBeamColumn;..\..\..\src\element\RockingBC;..\..\..\src\element\CEqElement;..\..\..\src\element\tetrahedron;..\..\..\src\domain\pattern;..\..\..\src\element\catenaryCable;..\..\..\src\recorder;..\..\..\src\analysis\integrator;..\..\..\src\analysis\algorithm;..\..\..\src\domain\region;..\..\..\src\element\triangle;..\..\..\src\element\PFEMElement;..\..\..\other\tetgen1.4.3;..\..\..\src\analysis\analysis;..\..\..\other\triangle;..\..\..\src\element\HUelements;..\..\..\src\material\nD\UWmaterials;..\..\..\src\element\UWelements;..\..\..\src\tagged\storage;..\..\..\src\element\frictionBearing\frictionModel;..\..\..\src\element\frictionBearing;..\..\..\src\element\adapter;..\..\..\src\element\elastomericBearing;..\..\..\src\element\twoNodeLink;..\..\..\src\api;..\..\..\src\actor\message;..\..\..\src\element\generic;..\..\..\src\material\section\fiber;..\..\..\src\element\dispBeamColumnInt;..\..\..\src\element\UP_ucdavis;..\..\..\src\element\UP-ucsd;..\..\..\src\package;..\..\..\src\damage;..\..\..\src\element\TotalLagrangianFD20NodeBrick;..\..\..\src\element\27nbrick;..\..\..\src\element\upU;..\..\..\src\element\dispBeamColumn;..\..\..\src\element\brick;..\..\..\src\element\shell;..\..\..\src\element\8nbrick;..\..\..\src\recorder\response;..\..\..\src\element\nonlinearBeamColumn\quadRule;..\..\..\src\material\nD;..\..\..\src\element\fourNodeQuad;..\..\..\src\element\damper;..\..\..\src\coordTransformation;..\..\..\src\element\beamWithHinges;..\..\..\src\element\nonlinearBeamColumn\matrixutil;..\..\..\src\element\zeroLength;..\..\..\src\modelbuilder;..\..\..\src\modelbuilder\tcl;..\..\..\src\element\feap;..\..\..\src\handler;..\..\..\src\element;..\..\..\src\element\truss;..\..\..\src\material\section;..\..\..\src\element\beam3d;..\..\..\src\element\beam2d;..\..\..\src\material;..\..\..\src\material\uniaxial;..\..\..\src\actor\objectBroker;..\..\..\src\matrix;..\..\..\src\domain\load;..\..\..\src\renderer;..\..\..\src\actor\channel;..\..\..\src\domain\node;..\..\..\src\actor\actor;..\..\..\src\tagged;..\..\..\src\domain\component;..\..\..\src;..\..\..\src\domain\domain;..\..\..\src\material\nd\template3dep;..\..\..\src\nDarray;..\..\..\src\element\20nbrick;..\..\..\src\element\elasticBeamColumn;..\..\..\src\element\joint;..\..\..\src\domain\constraints;..\..\..\src\element\updatedLagrangianBeamColumn;..\..\..\src\material\yieldSurface\yieldSurfaceBC;..\..\..\src\material\yieldSurface\evolution;..\..\..\src\element\forceBeamColumn;..\..\..\src\element\nonlinearBeamColumn\element;..\..\..\src\element\nonlinearBeamColumn\matrixUtil;c:\Program Files\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) NDEBUG;WIN32;_LIB;_WGL;_TCL85;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);_HAVE_PML_;_HAVE_PML true MultiThreadedDLL @@ -194,10 +194,13 @@ + + + @@ -206,6 +209,7 @@ + @@ -220,14 +224,20 @@ + + + + + + @@ -468,11 +478,13 @@ + + @@ -497,6 +509,7 @@ + diff --git a/Win64/proj/element/element.vcxproj.filters b/Win64/proj/element/element.vcxproj.filters index 5eccb06df..ce1eb5a32 100644 --- a/Win64/proj/element/element.vcxproj.filters +++ b/Win64/proj/element/element.vcxproj.filters @@ -132,6 +132,12 @@ {962a9734-043f-43c1-8e90-1a79eeef085f} + + {61bce605-5c0a-4311-b059-28f47dbe6364} + + + {44a1f5d6-7e75-44f5-a5a5-b79b65801b24} + @@ -929,6 +935,9 @@ RockingBC + + CEqElement + crdTransf @@ -938,6 +947,33 @@ dispBeamColumn + + dispBeamColumn + + + pfem + + + pfem + + + dispBeamColumn + + + mixedBeamColumn + + + masonry + + + masonry + + + masonry + + + forceBeamColumn\beamIntegration + @@ -1663,6 +1699,9 @@ RockingBC + + CEqElement + crdTransf @@ -1672,5 +1711,11 @@ dispBeamColumn + + dispBeamColumn + + + mixedBeamColumn + \ No newline at end of file diff --git a/Win64/proj/material/material.vcxproj b/Win64/proj/material/material.vcxproj index e7b3fbf85..dcaf0a307 100644 --- a/Win64/proj/material/material.vcxproj +++ b/Win64/proj/material/material.vcxproj @@ -221,9 +221,6 @@ - - - @@ -239,6 +236,7 @@ + @@ -322,6 +320,8 @@ + + @@ -341,6 +341,7 @@ + @@ -352,6 +353,7 @@ + @@ -365,6 +367,7 @@ + @@ -387,6 +390,8 @@ + + @@ -641,9 +646,6 @@ - - - @@ -659,6 +661,7 @@ + @@ -781,6 +784,7 @@ + diff --git a/Win64/proj/material/material.vcxproj.filters b/Win64/proj/material/material.vcxproj.filters index 1a2bfd471..17327347c 100644 --- a/Win64/proj/material/material.vcxproj.filters +++ b/Win64/proj/material/material.vcxproj.filters @@ -1256,15 +1256,6 @@ nD - - nD\stressDensityModel - - - nD\stressDensityModel - - - nD\stressDensityModel - nD\UWmaterials @@ -1367,6 +1358,30 @@ section + + section + + + uniaxial + + + uniaxial + + + uniaxial + + + uniaxial + + + uniaxial + + + uniaxial + + + uniaxial\py_tz_qz + @@ -2447,15 +2462,6 @@ nD - - nD\stressDensityModel - - - nD\stressDensityModel - - - nD\stressDensityModel - nD\UWmaterials @@ -2555,5 +2561,11 @@ section + + section + + + uniaxial + \ No newline at end of file diff --git a/Win64/proj/openSeesPy/OpenSeesPy.vcxproj b/Win64/proj/openSeesPy/OpenSeesPy.vcxproj index ad4c2a303..1f8d9b3a9 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 @@ -172,7 +172,7 @@ Disabled - ..\..\..\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:\users\mhscott\Anaconda3\include;%(AdditionalIncludeDirectories) _DEBUG;_WGL;_RELIABILITY;_WIN32;_WIN64;_FORTRAN;WIN32;WIN64;_CONSOLE;BUILD_tcl;_TCL85;_NO_NEW_RESTREPO;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -192,10 +192,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;PML.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) + 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;PML.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\debug;%(AdditionalLibraryDirectories) + c:\Program Files\tcl\lib;c:\users\mhscott\Anaconda3\libs;..\..\lib;..\..\lib\debug;%(AdditionalLibraryDirectories) libcmt.lib;%(IgnoreSpecificDefaultLibraries) true .\..\..\bin\OpenSeesPy.pdb diff --git a/Win64/proj/openSeesPy38/OpenSeesPy38.vcxproj b/Win64/proj/openSeesPy38/OpenSeesPy38.vcxproj index f2fc7a695..d60cb093a 100755 --- a/Win64/proj/openSeesPy38/OpenSeesPy38.vcxproj +++ b/Win64/proj/openSeesPy38/OpenSeesPy38.vcxproj @@ -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\Python38\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:\users\mhscott\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 @@ -81,7 +81,7 @@ 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;PML.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\Python38\libs;..\..\lib;..\..\lib\release;%(AdditionalLibraryDirectories) + c:\Program Files\tcl\lib;c:\users\mhscott\Anaconda3\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\Python38\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:\users\mhscott\Anaconda3\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;PML.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) + 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;PML.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\Python38\libs;..\..\lib;..\..\lib\debug;%(AdditionalLibraryDirectories) + c:\Program Files\tcl\lib;c:\users\mhscott\Anaconda3\libs;..\..\lib;..\..\lib\debug;%(AdditionalLibraryDirectories) libcmt.lib;%(IgnoreSpecificDefaultLibraries) true .\..\..\bin\OpenSeesPy.pdb diff --git a/Win64/proj/system/system.vcxproj b/Win64/proj/system/system.vcxproj index 737aa2ce1..0eb98a1a6 100644 --- a/Win64/proj/system/system.vcxproj +++ b/Win64/proj/system/system.vcxproj @@ -75,7 +75,7 @@ Disabled - ..\..\..\src\api;..\..\..\src\element;..\..\..\src\element\PFEMElement;..\..\..\src\domain\node;..\..\..\src\domain\component;..\..\..\src\domain\constraints;..\..\..\other\AMGCL;..\..\..\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\recorder;..\..\..\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\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\recorder;..\..\..\src\element\PFEMElement;..\..\..\src\api;..\..\..\src\element;..\..\..\src\element\PFEMElement;..\..\..\src\domain\node;..\..\..\src\domain\component;..\..\..\src\domain\constraints;..\..\..\other\AMGCL;..\..\..\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\recorder;..\..\..\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\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_LIB;_WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -104,7 +104,7 @@ Disabled - ..\..\..\src\api;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\component;..\..\..\src\domain\constraints;..\..\..\other\CSPARSE;..\..\..\src\utility;..\..\..\other\MUMPS_4.7.3\libseq;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\system_of_eqn\linearSOE\mumps;..\..\..\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\tcl;c:\Program Files\tcl\include;..\..\..\src\system_of_eqn\linearSOE\pardiso;%(AdditionalIncludeDirectories) + ..\..\..\src\recorder;..\..\..\src\element\PFEMElement;..\..\..\src\api;..\..\..\src\element;..\..\..\src\domain\node;..\..\..\src\domain\component;..\..\..\src\domain\constraints;..\..\..\other\CSPARSE;..\..\..\src\utility;..\..\..\other\MUMPS_4.7.3\libseq;..\..\..\other\SuperLU_5.1.1\SRC;..\..\..\src\system_of_eqn\linearSOE\mumps;..\..\..\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\tcl;c:\Program Files\tcl\include;..\..\..\src\system_of_eqn\linearSOE\pardiso;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_LIB;_WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -133,7 +133,7 @@ OnlyExplicitInline - ..\..\..\src\api;..\..\..\src\element;..\..\..\src\element\PFEMElement;..\..\..\src\domain\node;..\..\..\src\domain\component;..\..\..\src\domain\constraints;..\..\..\other\AMGCL;..\..\..\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\recorder;..\..\..\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\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\recorder;..\..\..\src\element\PFEMElement;..\..\..\src\api;..\..\..\src\element;..\..\..\src\element\PFEMElement;..\..\..\src\domain\node;..\..\..\src\domain\component;..\..\..\src\domain\constraints;..\..\..\other\AMGCL;..\..\..\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\recorder;..\..\..\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\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;AMGCL_NO_BOOST;_AMGCL;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreaded @@ -161,7 +161,7 @@ OnlyExplicitInline - ..\..\..\src\api;..\..\..\src\element;..\..\..\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\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) + ..\..\..\src\recorder;..\..\..\src\element\PFEMElement;..\..\..\src\api;..\..\..\src\element;..\..\..\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\tcl;c:\Program Files\tcl\include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreadedDLL