diff --git a/CMakeLists.txt b/CMakeLists.txt index 7931d0018..72273f36b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,11 +59,17 @@ endif() if(WIN32) # NOTE: this will execute for both 32-bit and 64-bit builds. include(OpenSeesDependenciesWin) + + # target_sources(OPS_OS_Specific_libs INTERFACE ${OPS_SRC_DIR}/api/win32Functions.cpp) + #target_link_libraries(OPS_OS_Specific_libs INTERFACE ${CBLAS_LIBRARIES} wsock32 ws2_32) + target_link_libraries(OPS_OS_Specific_libs INTERFACE wsock32 ws2_32) +# ======= add_compile_definitions(_WIN32) # file(GLOB_RECURSE ops_precompiled CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/Win64/lib/debug/*.lib") # message("OPS >>> Including the following precompiled libs: '${ops_precompiled}'") # target_sources(OPS_OS_Specific_libs INTERFACE ${OPS_SRC_DIR}/api/win32Functions.cpp) - target_link_libraries(OPS_OS_Specific_libs INTERFACE ${CBLAS_LIBRARIES} ${ops_precompiled} wsock32 ws2_32) + # target_link_libraries(OPS_OS_Specific_libs INTERFACE ${CBLAS_LIBRARIES} ${ops_precompiled} wsock32 ws2_32) + message(STATUS ">>> WIN32") endif() @@ -97,7 +103,7 @@ enable_language(Fortran) # C++ #-------------------------------------- #set(CMAKE_CXX_STANDARD 11) -add_link_options(-rdynamic) +#add_link_options(-rdynamic) set(CMAKE_CXX_ARCHIVE_CREATE " cqls ") # Warnings @@ -195,23 +201,23 @@ include_directories(${OPS_INCLUDE_DIRS}) # Define Targets # #============================================================================== -add_library(OPS_Matrix OBJECT) -add_library(OPS_Actor OBJECT) -add_library(OPS_Handler OBJECT) -add_library(OPS_Recorder OBJECT) -add_library(OPS_Tagged OBJECT) -add_library(OPS_Utilities OBJECT) -add_library(OPS_ModelBuilder OBJECT) - add_library(OPS_Numerics INTERFACE) target_link_libraries(OPS_Numerics INTERFACE ${ARPACK_LIBRARIES} ${SUPERLU_LIBRARIES} ${UMFPACK_LIBRARIES} ${AMD_LIBRARIES} - ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES} + ${LAPACK_LIBRARIES} + ${BLAS_LIBRARIES} ) # Core OpenSees +add_library(OPS_Matrix OBJECT) +add_library(OPS_Actor OBJECT) +add_library(OPS_Handler OBJECT) +add_library(OPS_Recorder OBJECT) +add_library(OPS_Tagged OBJECT) +add_library(OPS_Utilities OBJECT) +add_library(OPS_ModelBuilder OBJECT) add_library(OPS_Domain OBJECT) add_library(OPS_SysOfEqn OBJECT) add_library(OPS_Analysis OBJECT) @@ -235,20 +241,20 @@ add_library(OPS_Renderer OBJECT EXCLUDE_FROM_ALL) # Packaged libraries add_library(G3) add_library(OpenSees EXCLUDE_FROM_ALL) -target_sources(OpenSees - PRIVATE - "${OPS_SRC_DIR}/interpreter/OpenSeesBeamIntegrationCommands.cpp" - "${OPS_SRC_DIR}/interpreter/OpenSeesCrdTransfCommands.cpp" - "${OPS_SRC_DIR}/interpreter/OpenSeesFrictionModelCommands.cpp" - "${OPS_SRC_DIR}/interpreter/OpenSeesMiscCommands.cpp" - "${OPS_SRC_DIR}/interpreter/OpenSeesNDMaterialCommands.cpp" - "${OPS_SRC_DIR}/interpreter/OpenSeesOutputCommands.cpp" - #"${OPS_SRC_DIR}/interpreter/OpenSeesCommands.cpp" - "${OPS_SRC_DIR}/interpreter/OpenSeesElementCommands.cpp" - "${OPS_SRC_DIR}/interpreter/OpenSeesSectionCommands.cpp" - "${OPS_SRC_DIR}/interpreter/OpenSeesUniaxialMaterialCommands.cpp" - "${OPS_SRC_DIR}/renderer/PlainMap.cpp" -) +#target_sources(OpenSees +# PRIVATE +# "${OPS_SRC_DIR}/interpreter/OpenSeesBeamIntegrationCommands.cpp" +# "${OPS_SRC_DIR}/interpreter/OpenSeesCrdTransfCommands.cpp" +# "${OPS_SRC_DIR}/interpreter/OpenSeesFrictionModelCommands.cpp" +# "${OPS_SRC_DIR}/interpreter/OpenSeesMiscCommands.cpp" +# "${OPS_SRC_DIR}/interpreter/OpenSeesNDMaterialCommands.cpp" +# "${OPS_SRC_DIR}/interpreter/OpenSeesOutputCommands.cpp" +# #"${OPS_SRC_DIR}/interpreter/OpenSeesCommands.cpp" +# "${OPS_SRC_DIR}/interpreter/OpenSeesElementCommands.cpp" +# "${OPS_SRC_DIR}/interpreter/OpenSeesSectionCommands.cpp" +# "${OPS_SRC_DIR}/interpreter/OpenSeesUniaxialMaterialCommands.cpp" +# "${OPS_SRC_DIR}/renderer/PlainMap.cpp" +#) # Executables #------------------------------------------------------------------------------ @@ -512,12 +518,11 @@ endif() message("OPS >>> Configuring OpenSees extensions") foreach(extension IN LISTS OPS_Element_List OPS_Extension_List) string(TOUPPER "${extension}" ext_flag) - set(ext_flag "_${ext_flag}") + string(REGEX REPLACE "^OPS_" "OPSDEF_" ext_flag "${ext_flag}") message(" Adding macro definition '${ext_flag}'") add_compile_definitions(${ext_flag}) endforeach() -#---------------------------- # Renderer #---------------------------- if (OPS_Use_Graphics) @@ -527,28 +532,14 @@ else() add_compile_definitions(_NOGRAPHICS) endif() -#---------------------------- # Reliability #---------------------------- -if (OPS_Use_Reliability) +if ("OPS_Reliability" IN_LIST OPS_Extension_List) add_compile_definitions(_RELIABILITY) target_link_libraries(${OPS_FINAL_TARGET} OPS_Reliability) endif() -#---------------------------- -# ASDEA -#---------------------------- -if (OPS_Use_ASDEA) - target_link_libraries(${OPS_FINAL_TARGET} OPS_ASDEA) -endif() -#---------------------------- -# PFEM -#---------------------------- -if (OPS_Use_PFEM) - message("OPS >>> Including OPS_PFEM option") - #target_link_libraries(${OPS_FINAL_TARGET} OPS_PFEM) -endif() #---------------------------- # HDF5 diff --git a/Conf.cmake b/Conf.cmake index 37427ebe1..9de657bd0 100644 --- a/Conf.cmake +++ b/Conf.cmake @@ -23,18 +23,9 @@ option(FMK # Optional Extensions #-------------------------------------- -option(OPS_Use_Reliability - "Include reliability" OFF) - - option(OPS_Use_Graphics "Include graphics" OFF) -option(OPS_Use_PFEM - "Include PFEM library" OFF) - -option(OPS_Use_ASDEA - "Include ASDEA library" ON) option(OPS_Use_DRM "DRM lib" ON) @@ -61,8 +52,8 @@ option(OPS_Use_Thermal # (e.g. using OPS_Element_truss defines the macro _OPS_ELEMENT_TRUSS) #============================================================================== set(OPS_Extension_List - - OPS_Reliability # TODO: replace existing tests on '_RELIABILITY' + OPS_ASDEA + #OPS_Reliability # TODO: replace existing tests on '_RELIABILITY' OPS_NumLib_PETSC OPS_NumLib_METIS @@ -77,6 +68,7 @@ set(OPS_Extension_List ) set(OPS_Element_List + #OPS_Material_StressDensity OPS_Element_truss #OPS_Element_beam2d @@ -84,7 +76,6 @@ set(OPS_Element_List OPS_Element_dispBeamColumnInt OPS_Element_forceBeamColumn OPS_Element_mixedBeamColumn - #OPS_Element_beamWithHinges OPS_Element_LHMYS #OPS_Element_Dmglib @@ -107,6 +98,7 @@ set(OPS_Element_List OPS_Element_shell OPS_Element_surfaceLoad OPS_Element_updatedLagrangianBeamColumn + OPS_Element_masonry #OPS_Element_feap #OPS_Element_PFEMElement ) diff --git a/ETC/cmake/OpenSeesDependenciesConda.cmake b/ETC/cmake/OpenSeesDependenciesConda.cmake index 6996f390b..622d7433b 100644 --- a/ETC/cmake/OpenSeesDependenciesConda.cmake +++ b/ETC/cmake/OpenSeesDependenciesConda.cmake @@ -81,41 +81,3 @@ opensees_load(MySQL #FIND set(MYSQL_INCLUDE_DIR "${CONDA_ENV}/Library/include/mysql/") - - -#============================================================================== -# Select Element Libraries -# -# Each element in this list ows and associated macro definition -#============================================================================== -set(OPS_Element_List - #OPS_Element_PFEMElement - #OPS_Element_beamWithHinges - #OPS_Element_feap - OPS_Element_LHMYS - OPS_Element_PML - OPS_Element_RockingBC - OPS_Element_UP_ucsd - OPS_Element_absorbentBoundaries - OPS_Element_adapter - OPS_Element_beam3d - #OPS_Element_beam2d - OPS_Element_catenaryCable - OPS_Element_componentElement - OPS_Element_dispBeamColumnInt - OPS_Element_forceBeamColumn - OPS_Element_elastomericBearing - OPS_Element_frictionBearing - OPS_Element_generic - OPS_Element_gradientInelasticBeamColumn - OPS_Element_joint - OPS_Element_mixedBeamColumn - OPS_Element_mvlem - OPS_Element_pyMacro - OPS_Element_shell - OPS_Element_surfaceLoad - OPS_Element_truss - OPS_Element_updatedLagrangianBeamColumn -) - - diff --git a/ETC/cmake/OpenSeesDependenciesWin.cmake b/ETC/cmake/OpenSeesDependenciesWin.cmake index ed262f94d..4bd7376a2 100644 --- a/ETC/cmake/OpenSeesDependenciesWin.cmake +++ b/ETC/cmake/OpenSeesDependenciesWin.cmake @@ -8,20 +8,6 @@ # (Copyright and Disclaimer @ http://www.berkeley.edu/OpenSees/copyright.html) # #============================================================================== -# External Libraries -# -# - BLAS_LIBRARIES -# - BLAS_INCLUDE_DIRS -# -# - LAPACK_LIBRARIES -# - LAPACK_INCLUDE_DIRS -# -# - ARPACK_LIBRARIES -# -# - SUPERLU_LIBRARIES -# - SUPERLU_INCLUDE_DIRS -# -#============================================================================== # Synopsis # - opensees_load( [BUILD|FIND|SEARCH|PATHS] []) # @@ -30,15 +16,17 @@ # - FIND: Use CMake to find library, fail if not found # - SEARCH: Try finding library with CMake, build OpenSees # Version if not found. -# - PATHS: Provide specific paths for library. +# - BUNDLED: Provide specific paths for library. # #============================================================================== set(CONDA_DIR "C:/Users/claud/miniconda3") set(CONDA_ENV "C:/Users/claud/miniconda3/envs/sim") +set(BUNDLE_LIBS "${PROJECT_SOURCE_DIR}/Win64/lib/debug/") -opensees_load(TCL #FIND - LIBRARY ${CONDA_DIR}/Library/lib/tcl86t.lib - INCLUDE ${CONDA_DIR}/Library/include +opensees_load(TCL + LIBRARY ${CONDA_DIR}/Library/lib/tcl86t.lib + #LIBRARY "${BUNDLE_LIBS}/tcl.lib" + INCLUDE ${CONDA_DIR}/Library/include ) set(TCL_INCLUDE_PATH ${TCL_INCLUDE_DIRS}) @@ -46,22 +34,20 @@ set(TCL_LIBRARY ${TCL_LIBRARIES}) message("TCL: ${TCL_INCLUDE_PATH}") -opensees_load(BLAS #FIND - LIBRARY ${CONDA_ENV}/Library/lib/blas.lib +opensees_load(BLAS + LIBRARY "${BUNDLE_LIBS}/blas.lib" ) -opensees_load(CBLAS #FIND - LIBRARY ${CONDA_ENV}/Library/lib/cblas.lib - INCLUDE ${CONDA_ENV}/Library/include/ +opensees_load(CBLAS + LIBRARY "${BUNDLE_LIBS}/cblas.lib" ) -opensees_load(LAPACK #FIND - LIBRARY ${CONDA_ENV}/Library/lib/lapack.lib - INCLUDE ${CONDA_ENV}/Library/include/ +opensees_load(LAPACK + LIBRARY "${BUNDLE_LIBS}/lapack.lib" ) -set(ENV{SUPERLU_DIR}) -opensees_load(SUPERLU #SEARCH +#set(ENV{SUPERLU_DIR}) +opensees_load(SUPERLU BUNDLED ${OPS_BUNDLED_DIR}/SuperLU_5.1.1/ ) @@ -69,52 +55,19 @@ opensees_load(ARPACK SEARCH BUNDLED ${OPS_BUNDLED_DIR}/ARPACK/ ) +opensees_load(AMD + BUNDLED ${OPS_BUNDLED_DIR}/AMD/ +) + opensees_load(METIS SEARCH) opensees_load(HDF5 FIND) opensees_load(MySQL #FIND - LIBRARY ${CONDA_ENV}/Library/lib/libmysql.lib - INCLUDE ${CONDA_ENV}/Library/include/mysql + LIBRARY ${CONDA_ENV}/Library/lib/libmysql.lib + INCLUDE ${CONDA_ENV}/Library/include/mysql ) set(MYSQL_INCLUDE_DIR "${CONDA_ENV}/Library/include/mysql/") - -#============================================================================== -# Select Element Libraries -# -# Each element in this list ows and associated macro definition -#============================================================================== -set(OPS_Element_List - #OPS_Element_PFEMElement - #OPS_Element_beamWithHinges - #OPS_Element_feap - OPS_Element_LHMYS - OPS_Element_PML - OPS_Element_RockingBC - OPS_Element_UP_ucsd - OPS_Element_absorbentBoundaries - OPS_Element_adapter - OPS_Element_beam3d - #OPS_Element_beam2d - OPS_Element_catenaryCable - OPS_Element_componentElement - OPS_Element_dispBeamColumnInt - OPS_Element_forceBeamColumn - OPS_Element_elastomericBearing - OPS_Element_frictionBearing - OPS_Element_generic - OPS_Element_gradientInelasticBeamColumn - OPS_Element_joint - OPS_Element_mixedBeamColumn - OPS_Element_mvlem - OPS_Element_pyMacro - OPS_Element_shell - OPS_Element_surfaceLoad - OPS_Element_truss - OPS_Element_updatedLagrangianBeamColumn -) - - diff --git a/OTHER/AMD/CMakeLists.txt b/OTHER/AMD/CMakeLists.txt index 60a478ef1..8931359dc 100644 --- a/OTHER/AMD/CMakeLists.txt +++ b/OTHER/AMD/CMakeLists.txt @@ -14,34 +14,41 @@ project(AMD) add_library(AMD) -add_compiler_flags(-fexceptions -fPIC -I.) +target_compile_options(AMD PRIVATE -fexceptions -fPIC -I.) #------------------------------------------------------------------------------- # source files #------------------------------------------------------------------------------- -target_sources(AMD - amd_aat.c amd_1.c amd_2.c amd_dump.c amd_postorder.c amd_post_tree.c amd_defaults.c \ - amd_order.c amd_control.c amd_info.c amd_valid.c amd_preprocess +target_sources(AMD PRIVATE + amd_aat.c + amd_1.c + amd_2.c + amd_dump.c + amd_postorder.c + amd_post_tree.c + amd_defaults.c + amd_order.c + amd_control.c + amd_info.c + amd_valid.c + amd_preprocess.c + SuiteSparse_config.c ) - -#AMDI = $(addsuffix .o, $(subst amd_,amd_i_,$(AMD))) -#AMDL = $(addsuffix .o, $(subst amd_,amd_l_,$(AMD))) - #------------------------------------------------------------------------------- # compile each int and long routine (with no real/complex version) #------------------------------------------------------------------------------- -amd_i_%.o: amd_%.c $(INC) - $(C) -DDINT -c $< -o $@ - -# amd_l_%.o: amd_%.c $(INC) -# $(C) -DDLONG -c $< -o $@ - -$(AMD_LIBRARY): $(AMDI) SuiteSparse_config.o - @$(RM) $(RMFLAGS) $(AMD_LIBRARY) - @$(AR) $(ARFLAGS) $(AMD_LIBRARY) $(AMDI) SuiteSparse_config.o - @$(RANLIB) $(AMD_LIBRARY) +#amd_i_%.o: amd_%.c $(INC) +# $(C) -DDINT -c $< -o $@ +# +## amd_l_%.o: amd_%.c $(INC) +## $(C) -DDLONG -c $< -o $@ +# +#$(AMD_LIBRARY): $(AMDI) SuiteSparse_config.o +# @$(RM) $(RMFLAGS) $(AMD_LIBRARY) +# @$(AR) $(ARFLAGS) $(AMD_LIBRARY) $(AMDI) SuiteSparse_config.o +# @$(RANLIB) $(AMD_LIBRARY) diff --git a/OTHER/ARPACK/CMakeLists.txt b/OTHER/ARPACK/CMakeLists.txt index ad99cba0c..c3c8a9a37 100644 --- a/OTHER/ARPACK/CMakeLists.txt +++ b/OTHER/ARPACK/CMakeLists.txt @@ -60,13 +60,13 @@ target_sources(ARPACK PUBLIC ivout.f second.f ) -target_link_libraries(ARPACK PUBLIC ${LAPACK_LIBRARIES}) + +target_link_libraries(ARPACK PRIVATE ${LAPACK_LIBRARIES}) # Required on Unix OS family to be able to be linked into shared libraries. set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) - # Expose public includes to other subprojects through cache variable. set(${PROJECT_NAME}_INCLUDE_DIRS ${PROJECT_SOURCE_DIR} CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE) diff --git a/OTHER/SuperLU_5.1.1/CMakeLists.txt b/OTHER/SuperLU_5.1.1/CMakeLists.txt index dffd6b162..98dcce993 100644 --- a/OTHER/SuperLU_5.1.1/CMakeLists.txt +++ b/OTHER/SuperLU_5.1.1/CMakeLists.txt @@ -39,12 +39,18 @@ project(SUPERLU C) set(SUPERLU_SRC_DIR "${CMAKE_CURRENT_LIST_DIR}/SRC") +if (WIN32) + #target_compile_definitions(SUPERLU PUBLIC UpCase) + add_definitions(-DUpCase) +endif() + add_library(SUPERLU) add_library(DZLAUX OBJECT ${SUPERLU_SRC_DIR}/dmach.c ) + add_library(ALLAUX OBJECT ${SUPERLU_SRC_DIR}/superlu_timer.c ${SUPERLU_SRC_DIR}/util.c @@ -237,8 +243,9 @@ add_library(DLUSRC OBJECT # ${SUPERLU_SRC_DIR}/dzsum1.c # ${SUPERLU_SRC_DIR}/izmax1.c #) -include_directories(${SUPERLUS_SRC_DIR}) -target_link_libraries(SUPERLU DLUSRC ALLAUX DZLAUX) + +include_directories(${SUPERLU_SRC_DIR}) +target_link_libraries(SUPERLU DLUSRC ALLAUX DZLAUX ${LAPACK_LIBRARIES}) set(${PROJECT_NAME}_INCLUDE_DIRS ${PROJECT_SOURCE_DIR} CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE) diff --git a/SRC/Makefile b/SRC/Makefile index 6de8aa5d5..27dcbd3a4 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 \ @@ -653,7 +654,10 @@ 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)/material/nD/Damage2p.o \ # $(FE)/material/nD/Damage2p3D.o \ @@ -813,6 +817,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 \ @@ -850,6 +855,11 @@ 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/nD/NDMaterial.o \ $(FE)/material/nD/PlaneStressLayeredMaterial.o \ $(FE)/material/nD/PlaneStressRebarMaterial.o \ @@ -1022,7 +1032,6 @@ 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 \ diff --git a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp index e6ff0e05a..606af0322 100644 --- a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp +++ b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp @@ -166,7 +166,7 @@ #include "PlaneStressUserMaterial.h" //end Yuli Huang & Xinzheng Lu -#ifdef _OPS_Element_FEAP +#if defined(OPSDEF_Element_FEAP) #include "feap/FeapMaterial03.h" #endif // _OPS_Element_FEAP @@ -305,7 +305,7 @@ #include "frictionBearing/SingleFPSimple3d.h" #include "frictionBearing/TripleFrictionPendulum.h" -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) #include "PFEMElement/PFEMElement2D.h" #endif // _OPS_Element_PFEM @@ -473,7 +473,7 @@ #include "NewmarkHSIncrLimit.h" #include "NewmarkHSIncrReduct.h" -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) #include "PFEMIntegrator.h" #endif // _OPS_Element_PFEM @@ -767,7 +767,7 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_SSPbrickUP: return new SSPbrickUP(); -#if defined(_OPS_ELEMENT_PML) +#if defined(OPSDEF_ELEMENT_PML) case ELE_TAG_PML2D: return new PML2D(); @@ -900,7 +900,7 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_TripleFrictionPendulum: return new TripleFrictionPendulum(); -#if defined(_OPS_ELEMENT_PFEM) +#if defined(OPSDEF_ELEMENT_PFEM) case ELE_TAG_PFEMElement2D: return new PFEMElement2D(); #endif // _OPS_Element_PFEM @@ -1488,7 +1488,7 @@ FEM_ObjectBrokerAllClasses::getNewNDMaterial(int classTag) case ND_TAG_PressureIndependMultiYield: return new PressureIndependMultiYield(); -#ifdef _OPS_Element_FEAP +#if defined(OPSDEF_Element_FEAP) case ND_TAG_FeapMaterial03: return new FeapMaterial03(); #endif // _OPS_Element_FEAP @@ -1549,10 +1549,10 @@ FEM_ObjectBrokerAllClasses::getNewNDMaterial(int classTag) case ND_TAG_InitialStateAnalysisWrapper: return new InitialStateAnalysisWrapper(); - +#ifdef OPSDEF_MATERIAL_STRESSDENSITY case ND_TAG_stressDensity: return new stressDensity(); - +#endif case ND_TAG_CycLiqCP3D: return new CycLiqCP3D(); @@ -2204,7 +2204,7 @@ FEM_ObjectBrokerAllClasses::getNewTransientIntegrator(int classTag) case INTEGRATOR_TAGS_NewmarkHSIncrReduct: return new NewmarkHSIncrReduct(); -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) case INTEGRATOR_TAGS_PFEMIntegrator: return new PFEMIntegrator(); #endif // _OPS_Element_PFEM diff --git a/SRC/classTags.h b/SRC/classTags.h index ed8a0ab0d..3dd7a1ab1 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -231,6 +231,11 @@ #define MAT_TAG_PlateBearingConnectionThermal 215 #define MAT_TAG_ASD_SMA_3K 216 +#define MAT_TAG_Masonry 217 +#define MAT_TAG_Masonryt 218 +#define MAT_TAG_Trilinwp 219 +#define MAT_TAG_Trilinwp2 220 +#define MAT_TAG_Trilinwpd 221 #define MAT_TAG_FedeasMaterial 1000 #define MAT_TAG_FedeasBond1 1001 @@ -780,6 +785,9 @@ #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_ExternalElement 99990 diff --git a/SRC/domain/component/TclParameterCommands.cpp b/SRC/domain/component/TclParameterCommands.cpp index 10110307d..d4ae0dcd4 100644 --- a/SRC/domain/component/TclParameterCommands.cpp +++ b/SRC/domain/component/TclParameterCommands.cpp @@ -33,7 +33,6 @@ #include #include - #include #include diff --git a/SRC/domain/domain/CMakeLists.txt b/SRC/domain/domain/CMakeLists.txt index 9d29dbfe5..02529cda5 100644 --- a/SRC/domain/domain/CMakeLists.txt +++ b/SRC/domain/domain/CMakeLists.txt @@ -2,8 +2,10 @@ target_sources(OPS_Domain PRIVATE Domain.cpp + DomainModalProperties.cpp PUBLIC Domain.h + DomainModalProperties.h ElementIter.h LoadCaseIter.h MP_ConstraintIter.h @@ -14,11 +16,6 @@ target_sources(OPS_Domain SubdomainIter.h ) -target_sources(OPS_ASDEA - PRIVATE DomainModalProperties.cpp - PUBLIC DomainModalProperties.h -) - target_include_directories(OPS_Domain PUBLIC ${CMAKE_CURRENT_LIST_DIR}) diff --git a/SRC/domain/domain/Domain.cpp b/SRC/domain/domain/Domain.cpp index 4e2bf979a..b1377abb1 100644 --- a/SRC/domain/domain/Domain.cpp +++ b/SRC/domain/domain/Domain.cpp @@ -3685,4 +3685,3 @@ int Domain::deactivateElements(const ID& elementList) } return 0; } - diff --git a/SRC/element/CMakeLists.txt b/SRC/element/CMakeLists.txt index 55e05aa9f..0373b903c 100644 --- a/SRC/element/CMakeLists.txt +++ b/SRC/element/CMakeLists.txt @@ -70,6 +70,7 @@ add_subdirectory(UP-ucsd) add_subdirectory(UWelements) add_subdirectory(HUelements) add_subdirectory(XMUelements) +add_subdirectory(masonry) #add_subdirectory(dmglib) target_include_directories(OPS_Element PUBLIC ${CMAKE_CURRENT_LIST_DIR}) diff --git a/SRC/element/HUelements/CMakeLists.txt b/SRC/element/HUelements/CMakeLists.txt index 934b77f9f..bbba0e70e 100644 --- a/SRC/element/HUelements/CMakeLists.txt +++ b/SRC/element/HUelements/CMakeLists.txt @@ -1,9 +1,10 @@ + target_sources(OPS_Element PRIVATE MultipleShearSpring.cpp MultipleNormalSpring.cpp - DBESI0.C - DBESI1.C + DBESI0.c + DBESI1.c YamamotoBiaxialHDR.cpp KikuchiBearing.cpp PUBLIC diff --git a/SRC/element/HUelements/DBESI0.C b/SRC/element/HUelements/DBESI0.c similarity index 97% rename from SRC/element/HUelements/DBESI0.C rename to SRC/element/HUelements/DBESI0.c index d65ca53ad..1a5bcb928 100644 --- a/SRC/element/HUelements/DBESI0.C +++ b/SRC/element/HUelements/DBESI0.c @@ -2,6 +2,9 @@ #include +#ifdef __cplusplus +extern "C" +#endif double dbesi0(double x) { int k; diff --git a/SRC/element/HUelements/DBESI1.C b/SRC/element/HUelements/DBESI1.c similarity index 97% rename from SRC/element/HUelements/DBESI1.C rename to SRC/element/HUelements/DBESI1.c index 4dc6be6fb..9585683de 100644 --- a/SRC/element/HUelements/DBESI1.C +++ b/SRC/element/HUelements/DBESI1.c @@ -2,6 +2,9 @@ #include +#ifdef __cplusplus +extern "C" +#endif double dbesi1(double x) { int k; diff --git a/SRC/element/HUelements/KikuchiBearing.cpp b/SRC/element/HUelements/KikuchiBearing.cpp index c594698eb..aceff5639 100644 --- a/SRC/element/HUelements/KikuchiBearing.cpp +++ b/SRC/element/HUelements/KikuchiBearing.cpp @@ -65,13 +65,8 @@ // Bessel function, Copyright(C) 1996 Takuya OOURA -#ifdef _WIN32 extern "C" double dbesi0(double); extern "C" double dbesi1(double); -#else -extern double dbesi0(double); -extern double dbesi1(double); -#endif static bool errDetected(bool ifNoError, const char *msg){ diff --git a/SRC/element/Makefile b/SRC/element/Makefile index 1686df35c..9222a0a87 100644 --- a/SRC/element/Makefile +++ b/SRC/element/Makefile @@ -51,6 +51,7 @@ all: $(OBJS) @$(CD) $(FE)/element/absorbentBoundaries; $(MAKE); @$(CD) $(FE)/element/gradientInelasticBeamColumn; $(MAKE); @$(CD) $(FE)/element/RockingBC; $(MAKE); + @$(CD) $(FE)/element/masonry; $(MAKE); # Miscellaneous tidy: @@ -100,6 +101,7 @@ 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; wipe: spotless diff --git a/SRC/element/TclElementCommands.cpp b/SRC/element/TclElementCommands.cpp index cdfb98e05..f6735273c 100644 --- a/SRC/element/TclElementCommands.cpp +++ b/SRC/element/TclElementCommands.cpp @@ -148,12 +148,12 @@ extern void* OPS_MVLEM_3D(void); // Kristijan Kolozvari extern void* OPS_SFI_MVLEM_3D(void); // Kristijan Kolozvari extern void *OPS_AxEqDispBeamColumn2d(void); extern void *OPS_ElastomericBearingBoucWenMod3d(void); -#if defined(_OPS_ELEMENT_PFEM) +#if defined(OPSDEF_ELEMENT_PFEM) extern void *OPS_PFEMElement2DBubble(const ID &info); extern void *OPS_PFEMElement2Dmini(const ID &info); extern void *OPS_PFEMElement2D(); #endif -#if defined(_HAVE_LHNMYS) || defined(_OPS_ELEMENT_LHNMYS) +#if defined(_HAVE_LHNMYS) || defined(OPSDEF_ELEMENT_LHNMYS) extern void* OPS_BeamColumn2DwLHNMYS(void); extern void* OPS_BeamColumn2DwLHNMYS_Damage(void); extern void* OPS_BeamColumn3DwLHNMYS(void); @@ -186,13 +186,15 @@ 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 -#if defined(_OPS_Element_FEAP) +#if defined(OPSDEF_Element_FEAP) extern int TclModelBuilder_addFeapTruss(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv, Domain*, TclModelBuilder *, int argStart); #endif // _OPS_Element_FEAP @@ -292,6 +294,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); @@ -510,7 +524,7 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, opserr << "TclElementCommand -- unable to create element of type : " << argv[1] << endln; return TCL_ERROR; } -#if defined(_OPS_ELEMENT_PML) +#if defined(OPSDEF_ELEMENT_PML) } else if ((strcmp(argv[1],"PML") == 0) || (strcmp(argv[1],"pml")) == 0) { Element *theEle = 0; ID info; @@ -541,7 +555,7 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, } }*/ -#if defined(_HAVE_LHNMYS) || defined(_OPS_ELEMENT_LHNMYS) +#if defined(_HAVE_LHNMYS) || defined(OPSDEF_ELEMENT_LHNMYS) } else if (strcmp(argv[1],"beamColumn2DwLHNMYS") == 0) { Element *theEle = 0; ID info; @@ -574,9 +588,9 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, opserr << "TclElementCommand -- unable to create element of type : " << argv[1] << endln; return TCL_ERROR; } + #endif -#if defined(_OPS_ELEMENT_WHEELRAIL) // Beginning of WheelRail element TCL command //Added by Quan Gu and Yongdou Liu, et al. on 2018/10/31 @@ -587,7 +601,6 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, theTclDomain, theTclBuilder, eleArgStart); return result; // End of WheelRail element TCL command -#endif } else if ((strcmp(argv[1],"ElasticTimoshenkoBeam") == 0) || (strcmp(argv[1],"elasticTimoshenkoBeam")) == 0) { Element *theEle = 0; @@ -783,6 +796,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)){ @@ -1140,7 +1189,7 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, return TCL_ERROR; } -#if defined(_OPS_ELEMENT_PFEM) +#if defined(OPSDEF_ELEMENT_PFEM) } else if (strcmp(argv[1], "PFEMElement2DBuble") == 0) { ID info; void *theEle = OPS_PFEMElement2DBubble(info); @@ -1473,7 +1522,7 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, } -#ifdef _OPS_ELEMENT_FEAP +#if defined(OPSDEF_ELEMENT_FEAP) if (strcmp(argv[1],"fTruss") == 0) { int eleArgStart = 1; int result = TclModelBuilder_addFeapTruss(clientData, interp, argc, argv, diff --git a/SRC/element/dispBeamColumn/DispBeamColumnAsym3d.cpp b/SRC/element/dispBeamColumn/DispBeamColumnAsym3d.cpp index 46e7319a4..2c6640b93 100644 --- a/SRC/element/dispBeamColumn/DispBeamColumnAsym3d.cpp +++ b/SRC/element/dispBeamColumn/DispBeamColumnAsym3d.cpp @@ -154,9 +154,6 @@ void* OPS_DispBeamColumnAsym3dTcl() { double dData2[2]; //input of ys and zs dData2[0] = 0.0; dData2[1] = 0.0; - int sDataLength = 40; - //char* sData = new char[sDataLength]; - //char* sData2 = new char[sDataLength]; int numData; // Check the number of dimensions @@ -217,10 +214,6 @@ void* OPS_DispBeamColumnAsym3dTcl() { // Loop through remaining arguments to get optional input while (OPS_GetNumRemainingInputArgs() > 0) { const char *sData = OPS_GetString(); - //if (OPS_GetStringCopy(&sData) != 0) { - // opserr << "WARNING invalid input"; - // return 0; - //} if (strcmp(sData, "-cMass") == 0) { cmass = 1; @@ -236,10 +229,6 @@ void* OPS_DispBeamColumnAsym3dTcl() { } else if (strcmp(sData, "-integration") == 0) { const char *sData2 = OPS_GetString(); - //if (OPS_GetStringCopy(&sData2) != 0) { - // opserr << "WARNING invalid input, want: -integration $intType"; - // return 0; - //} if (strcmp(sData2, "Lobatto") == 0) { beamIntegr = new LobattoBeamIntegration(); @@ -273,8 +262,6 @@ void* OPS_DispBeamColumnAsym3dTcl() { opserr << "WARNING invalid integration type, element: " << eleTag; return 0; } - delete [] sData2; - } else if (strcmp(sData, "-shearCenter") == 0) { // Get the coordinates of shear center w.r.t centroid @@ -287,7 +274,6 @@ void* OPS_DispBeamColumnAsym3dTcl() { else { opserr << "WARNING unknown option " << sData << "\n"; } - delete [] sData; } // Set the beam integration object if not in options 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/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/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 8c11c86eb..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; } 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/CMakeLists.txt b/SRC/element/masonry/CMakeLists.txt new file mode 100644 index 000000000..a4aa651ab --- /dev/null +++ b/SRC/element/masonry/CMakeLists.txt @@ -0,0 +1,28 @@ +add_library(OPS_Element_masonry) + +target_sources(OPS_Element_masonry + PUBLIC + BeamGT.cpp + MasonPan12.cpp + MasonPan3D.cpp + PRIVATE + BeamGT.h + MasonPan12.h + MasonPan3D.h + +) + +target_sources(OPS_Material + PRIVATE + "${OPS_SRC_DIR}/material/uniaxial/Masonry.cpp" + "${OPS_SRC_DIR}/material/uniaxial/Masonryt.cpp" + "${OPS_SRC_DIR}/material/uniaxial/Trilinwp.cpp" + "${OPS_SRC_DIR}/material/uniaxial/Trilinwp2.cpp" + "${OPS_SRC_DIR}/material/uniaxial/Trilinwpd.cpp" + PUBLIC + "${OPS_SRC_DIR}/material/uniaxial/Masonry.h" + "${OPS_SRC_DIR}/material/uniaxial/Masonryt.h" + "${OPS_SRC_DIR}/material/uniaxial/Trilinwp.h" + "${OPS_SRC_DIR}/material/uniaxial/Trilinwp2.h" + "${OPS_SRC_DIR}/material/uniaxial/Trilinwpd.h" +) 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/MixedBeamColumnAsym3d.cpp b/SRC/element/mixedBeamColumn/MixedBeamColumnAsym3d.cpp index 57567c2cd..219e0014e 100644 --- a/SRC/element/mixedBeamColumn/MixedBeamColumnAsym3d.cpp +++ b/SRC/element/mixedBeamColumn/MixedBeamColumnAsym3d.cpp @@ -242,9 +242,6 @@ void * OPS_MixedBeamColumnAsym3dTcl() { double dData2[2]; //input of ys and zs dData2[0] = 0.0; dData2[1] = 0.0; - int sDataLength = 40; - //char *sData = new char[sDataLength]; - //char *sData2 = new char[sDataLength]; int numData; // Check the number of dimensions @@ -306,10 +303,6 @@ void * OPS_MixedBeamColumnAsym3dTcl() { // Loop through remaining arguments to get optional input while ( OPS_GetNumRemainingInputArgs() > 0 ) { const char *sData = OPS_GetString(); - //if ( OPS_GetStringCopy(&sData) != 0 ) { - // opserr << "WARNING invalid input"; - // return 0; - //} if ( strcmp(sData,"-mass") == 0 ) { numData = 1; @@ -321,10 +314,6 @@ void * OPS_MixedBeamColumnAsym3dTcl() { } else if ( strcmp(sData,"-integration") == 0 ) { const char *sData2 = OPS_GetString(); - //if ( OPS_GetStringCopy(&sData2) != 0 ) { - // opserr << "WARNING invalid input, want: -integration $intType"; - // return 0; - //} if (strcmp(sData2,"Lobatto") == 0) { beamIntegr = new LobattoBeamIntegration(); @@ -352,8 +341,6 @@ void * OPS_MixedBeamColumnAsym3dTcl() { opserr << "WARNING invalid integration type, element: " << eleTag; return 0; } - delete [] sData2; - } else if ( strcmp(sData,"-doRayleigh") == 0 ) { numData = 1; if (OPS_GetInt(&numData, &doRayleigh) != 0) { @@ -374,10 +361,8 @@ void * OPS_MixedBeamColumnAsym3dTcl() { } else { opserr << "WARNING unknown option " << sData << "\n"; } - delete [] sData; } - // Set the beam integration object if not in options if (beamIntegr == 0) { beamIntegr = new LobattoBeamIntegration(); 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/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/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/OpenSeesUniaxialMaterialCommands.cpp b/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp index 034febede..c88efa717 100644 --- a/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp +++ b/SRC/interpreter/OpenSeesUniaxialMaterialCommands.cpp @@ -176,6 +176,7 @@ void* OPS_IMKBilin(); void* OPS_IMKPinching(); void* OPS_IMKPeakOriented(); void* OPS_SLModel(); +void* OPS_SMAMaterial(); void* OPS_ArctangentBackbone(); void* OPS_BilinearBackbone(); @@ -346,6 +347,7 @@ namespace { 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/material/nD/TclModelBuilderNDMaterialCommand.cpp b/SRC/material/nD/TclModelBuilderNDMaterialCommand.cpp index 9eb3b3986..4ab7e8c3d 100644 --- a/SRC/material/nD/TclModelBuilderNDMaterialCommand.cpp +++ b/SRC/material/nD/TclModelBuilderNDMaterialCommand.cpp @@ -141,7 +141,7 @@ extern void *OPS_FSAMMaterial(void); // K Kolozvari extern void *OPS_Damage2p(void); #endif -#ifdef _OPS_Material_FEAP +#if defined(OPSDEF_Material_FEAP) NDMaterial * TclModelBuilder_addFeapMaterial(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv, @@ -528,6 +528,7 @@ TclModelBuilderNDMaterialCommand (ClientData clientData, Tcl_Interp *interp, int return TCL_ERROR; } +#ifdef OPSDEF_MATERIAL_STRESSDENSITY else if ((strcmp(argv[1],"stressDensity") == 0) || (strcmp(argv[1],"StressDensity") == 0)) { void *theMat = OPS_StressDensityMaterial(); @@ -536,6 +537,7 @@ TclModelBuilderNDMaterialCommand (ClientData clientData, Tcl_Interp *interp, int else return TCL_ERROR; } +#endif else if ((strcmp(argv[1],"ElasticIsotropic3D") == 0)) { @@ -2103,7 +2105,7 @@ TclModelBuilderNDMaterialCommand (ClientData clientData, Tcl_Interp *interp, int //end of adding thermo-mechanical nd materials-L.Jiang[SIF] -#ifdef _OPS_Material_FEAP +#if defined(OPSDEF_Material_FEAP) else { theMaterial = TclModelBuilder_addFeapMaterial(clientData, interp, diff --git a/SRC/material/nD/stressDensityModel/CMakeLists.txt b/SRC/material/nD/stressDensityModel/CMakeLists.txt index 28486c122..2410e79a4 100644 --- a/SRC/material/nD/stressDensityModel/CMakeLists.txt +++ b/SRC/material/nD/stressDensityModel/CMakeLists.txt @@ -1,5 +1,6 @@ +add_library(OPS_Material_StressDensity) -target_sources(OPS_Material +target_sources(OPS_Material_StressDensity PRIVATE stressDensity.cpp StressDensityModel.cpp @@ -22,7 +23,7 @@ target_sources(OPS_Material_nD_StressDensity_f MODULE_ALL_INTERFACES_2D.f90 ) -target_link_libraries(OPS_Material PUBLIC OPS_Material_nD_StressDensity_f) +target_link_libraries(OPS_Material_StressDensity PRIVATE OPS_Material_nD_StressDensity_f) -target_include_directories(OPS_Material PUBLIC ${CMAKE_CURRENT_LIST_DIR}) +target_include_directories(OPS_Material_StressDensity PUBLIC ${CMAKE_CURRENT_LIST_DIR}) 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 d4c6c1454..b57f6fda2 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; for (int j = 0; j < numFibers; j++) { @@ -954,26 +967,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; } @@ -1018,10 +1032,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 index ae6d9adc2..f68ee4269 100644 --- a/SRC/material/section/FiberSectionAsym3d.cpp +++ b/SRC/material/section/FiberSectionAsym3d.cpp @@ -28,7 +28,8 @@ // Description: This file contains the class implementation of FiberSection2d. // Modified by: Xinlong Du and Jerome F. Hajjar, Northeastern University, USA; Year 2019 -// Description: Modified FiberSectionAsym3d.cpp to include shear center coordinates and high-order longitudinal strain terms. +// 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. @@ -55,7 +56,7 @@ #include #include -ID FiberSectionAsym3d::code(4); +ID FiberSectionAsym3d::code(5); void* OPS_FiberSectionAsym3d() { @@ -73,18 +74,23 @@ void* OPS_FiberSectionAsym3d() if (OPS_GetDoubleInput(&numData, dData) < 0) return 0; double GJ = 0.0; - ElasticMaterial *torsion = 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; - return new FiberSectionAsym3d(tag, num, torsion,dData[0],dData[1]); + SectionForceDeformation* section = new FiberSectionAsym3d(tag, num, torsion, dData[0], dData[1]); + if (deleteTorsion) + delete torsion; + return section; } // constructors: @@ -134,13 +140,7 @@ FiberSectionAsym3d::FiberSectionAsym3d(int tag, int num, Fiber **fibers, Uniaxia zBar = QyBar/Abar; } - if (torsion != 0) { - theTorsion = torsion->getCopy(); - } else { - // assign zero torsional stiffness because people often use - // the aggregator section to assign torsional stiffness - theTorsion = new ElasticMaterial(0, 1.0E-10); - } + theTorsion = torsion->getCopy(); if (theTorsion == 0) { opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to get copy of torsion material\n"; } @@ -161,6 +161,7 @@ FiberSectionAsym3d::FiberSectionAsym3d(int tag, int num, Fiber **fibers, Uniaxia 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 @@ -191,13 +192,7 @@ FiberSectionAsym3d::FiberSectionAsym3d(int tag, int num, UniaxialMaterial *torsi } } - if (torsion != 0) { - theTorsion = torsion->getCopy(); - } else { - // assign zero torsional stiffness because people often use - // the aggregator section to assign torsional stiffness - theTorsion = new ElasticMaterial(0, 1.0E-10); - } + theTorsion = torsion->getCopy(); if (theTorsion == 0) { opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to get copy of torsion material\n"; } @@ -218,6 +213,7 @@ FiberSectionAsym3d::FiberSectionAsym3d(int tag, int num, UniaxialMaterial *torsi 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, @@ -271,13 +267,7 @@ FiberSectionAsym3d::FiberSectionAsym3d(int tag, int num, UniaxialMaterial **mats yBar = QzBar/Abar; zBar = QyBar/Abar; - if (torsion != 0) { - theTorsion = torsion->getCopy(); - } else { - // assign zero torsional stiffness because people often use - // the aggregator section to assign torsional stiffness - theTorsion = new ElasticMaterial(0, 1.0E-10); - } + theTorsion = torsion->getCopy(); if (theTorsion == 0) { opserr << "FiberSectionAsym3d::FiberSectionAsym3d -- failed to get copy of torsion material\n"; } @@ -295,6 +285,7 @@ FiberSectionAsym3d::FiberSectionAsym3d(int tag, int num, UniaxialMaterial **mats 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 @@ -319,6 +310,7 @@ FiberSectionAsym3d::FiberSectionAsym3d(): code(1) = SECTION_RESPONSE_MZ; code(2) = SECTION_RESPONSE_MY; code(3) = SECTION_RESPONSE_T; + code(4) = SECTION_RESPONSE_W; } int @@ -516,9 +508,11 @@ FiberSectionAsym3d::setTrialSectionDeformation (const Vector &deforms) kData[16] = kData[8]; kData[17] = kData[13]; - res += theTorsion->setTrial(d4, stress, tangent); - sData[4] = stress; //T - kData[24] = tangent; //GJ + if (theTorsion != 0) { + res += theTorsion->setTrial(d4, stress, tangent); + sData[4] = stress; //T + kData[24] = tangent; //GJ + } return res; } @@ -585,7 +579,8 @@ FiberSectionAsym3d::getInitialTangent(void) kInitialData[16] = kInitialData[8]; kInitialData[17] = kInitialData[13]; - kInitialData[24] = theTorsion->getInitialTangent(); + if (theTorsion != 0) + kInitialData[24] = theTorsion->getInitialTangent(); return kInitial; } @@ -686,7 +681,7 @@ FiberSectionAsym3d::getType () int FiberSectionAsym3d::getOrder () const { - return 4; + return 5; } int @@ -697,7 +692,8 @@ FiberSectionAsym3d::commitState(void) for (int i = 0; i < numFibers; i++) err += theMaterials[i]->commitState(); - err += theTorsion->commitState(); + if (theTorsion != 0) + err += theTorsion->commitState(); return err; } @@ -780,8 +776,12 @@ FiberSectionAsym3d::revertToLastCommit(void) kData[16] = kData[8]; kData[17] = kData[13]; - err += theTorsion->revertToLastCommit(); - kData[24] = theTorsion->getTangent(); + if (theTorsion != 0) { + err += theTorsion->revertToLastCommit(); + kData[24] = theTorsion->getTangent(); + } + else + kData[24] = 0.0; //why do not have sData[4] here? return err; } @@ -864,9 +864,15 @@ FiberSectionAsym3d::revertToStart(void) kData[16] = kData[8]; kData[17] = kData[13]; - err += theTorsion->revertToStart(); - kData[24] = theTorsion->getTangent(); - sData[4] = theTorsion->getStress(); + 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; } @@ -877,23 +883,27 @@ FiberSectionAsym3d::sendSelf(int commitTag, Channel &theChannel) int res = 0; // create an id to send objects tag and numFibers, - // size 3 so no conflict with matData below if just 1 fiber - static Vector data(5); + // 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(); - theTorsion->setDbTag(dbTag); - data(2) = theTorsion->getClassTag(); - data(3) = ys; - data(4) = zs; + 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 << "FiberSection2d::sendSelf - failed to send ID data\n"; + opserr << "FiberSectionAsym3d::sendSelf - failed to send Vector data\n"; return res; } - theTorsion->sendSelf(commitTag, theChannel); + if (theTorsion != 0) + theTorsion->sendSelf(commitTag, theChannel); if (numFibers != 0) { @@ -913,7 +923,7 @@ FiberSectionAsym3d::sendSelf(int commitTag, Channel &theChannel) res += theChannel.sendID(dbTag, commitTag, materialData); if (res < 0) { - opserr << "FiberSection2d::sendSelf - failed to send material data\n"; + opserr << "FiberSectionAsym3d::sendSelf - failed to send material data\n"; return res; } @@ -921,7 +931,7 @@ FiberSectionAsym3d::sendSelf(int commitTag, Channel &theChannel) Vector fiberData(matData, 3*numFibers); res += theChannel.sendVector(dbTag, commitTag, fiberData); if (res < 0) { - opserr << "FiberSection2d::sendSelf - failed to send material data\n"; + opserr << "FiberSectionAsym3d::sendSelf - failed to send fiber data\n"; return res; } @@ -939,31 +949,32 @@ FiberSectionAsym3d::recvSelf(int commitTag, Channel &theChannel, { int res = 0; - static Vector data(5); + static Vector data(6); int dbTag = this->getDbTag(); res += theChannel.recvVector(dbTag, commitTag, data); - ys = data(3); - zs = data(4); + ys = data(4); + zs = data(5); if (res < 0) { - opserr << "FiberSection2d::sendSelf - failed to recv ID data\n"; + opserr << "FiberSectionAsym3d::recvSelf - failed to recv Vector data\n"; return res; } this->setTag((int)data(0)); - if (theTorsion == 0) { - int cTag = (int)data(2); - theTorsion = theBroker.getNewUniaxialMaterial(cTag); - theTorsion->setDbTag(dbTag); - } - if (theTorsion == 0) { - opserr << "FiberSectionAsym3d::sendSelf - failed to get torsion material \n"; - return -1; + 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::sendSelf - torsion failed to recvSelf \n"; + opserr << "FiberSectionAsym3d::recvSelf - torsion failed to recvSelf \n"; return -2; } @@ -972,7 +983,7 @@ FiberSectionAsym3d::recvSelf(int commitTag, Channel &theChannel, ID materialData(2*(int)data(1)); res += theChannel.recvID(dbTag, commitTag, materialData); if (res < 0) { - opserr << "FiberSection2d::sendSelf - failed to send material data\n"; + opserr << "FiberSectionAsym3d::recvSelf - failed to send material data\n"; return res; } @@ -997,7 +1008,7 @@ FiberSectionAsym3d::recvSelf(int commitTag, Channel &theChannel, theMaterials = new UniaxialMaterial *[numFibers]; if (theMaterials == 0) { - opserr << "FiberSection2d::recvSelf -- failed to allocate Material pointers\n"; + opserr << "FiberSectionAsym3d::recvSelf -- failed to allocate Material pointers\n"; exit(-1); } @@ -1007,7 +1018,7 @@ FiberSectionAsym3d::recvSelf(int commitTag, Channel &theChannel, matData = new double [numFibers*3]; if (matData == 0) { - opserr << "FiberSection2d::recvSelf -- failed to allocate double array for material data\n"; + opserr << "FiberSectionAsym3d::recvSelf -- failed to allocate double array for material data\n"; exit(-1); } } @@ -1016,7 +1027,7 @@ FiberSectionAsym3d::recvSelf(int commitTag, Channel &theChannel, Vector fiberData(matData, 3*numFibers); res += theChannel.recvVector(dbTag, commitTag, fiberData); if (res < 0) { - opserr << "FiberSection2d::sendSelf - failed to send material data\n"; + opserr << "FiberSectionAsym3d::recvSelf - failed to recv fiber data\n"; return res; } @@ -1035,7 +1046,7 @@ FiberSectionAsym3d::recvSelf(int commitTag, Channel &theChannel, } if (theMaterials[i] == 0) { - opserr << "FiberSection2d::recvSelf -- failed to allocate double array for material data\n"; + opserr << "FiberSectionAsym3d::recvSelf -- failed to allocate double array for material data\n"; exit(-1); } @@ -1123,128 +1134,113 @@ FiberSectionAsym3d::Print(OPS_Stream &s, int flag) Response* FiberSectionAsym3d::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; @@ -1273,99 +1269,12 @@ FiberSectionAsym3d::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); } + 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/FiberSectionAsym3d.h b/SRC/material/section/FiberSectionAsym3d.h index bdead7418..af074bb06 100644 --- a/SRC/material/section/FiberSectionAsym3d.h +++ b/SRC/material/section/FiberSectionAsym3d.h @@ -31,7 +31,8 @@ // stress resultants are obtained by summing fiber contributions. // Modified by: Xinlong Du and Jerome F. Hajjar, Northeastern University, USA; Year 2019 -// Description: Modified FiberSectionAsym3d.h to include shear center coordinates and high-order longitudinal strain terms. +// 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. 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 1ff044da8..66db68cf6 100644 --- a/SRC/material/section/Makefile +++ b/SRC/material/section/Makefile @@ -22,19 +22,16 @@ OBJS = SectionForceDeformation.o \ FiberSection3d.o \ FiberSectionWarping3d.o \ FiberSectionAsym3d.o \ - FiberSectionGJ.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 9307b1f9c..fefc102ec 100644 --- a/SRC/material/section/MembranePlateFiberSection.cpp +++ b/SRC/material/section/MembranePlateFiberSection.cpp @@ -654,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/uniaxial/CMakeLists.txt b/SRC/material/uniaxial/CMakeLists.txt index 4526d0d89..3d730b1a3 100644 --- a/SRC/material/uniaxial/CMakeLists.txt +++ b/SRC/material/uniaxial/CMakeLists.txt @@ -157,12 +157,15 @@ target_sources(OPS_Material TDConcreteMC10.cpp TDConcreteMC10NL.cpp TensionOnlyMaterial.cpp - TriMatrix.cpp UniaxialJ2Plasticity.cpp ViscousDamper.cpp ViscousMaterial.cpp WrapperUniaxialMaterial.cpp pyUCLA.cpp + SMAMaterial.cpp + + TriMatrix.cpp + PUBLIC ASD_SMA_3K.h BackboneMaterial.h @@ -258,17 +261,19 @@ target_sources(OPS_Material TDConcreteMC10.h TDConcreteMC10NL.h TensionOnlyMaterial.h - TriMatrix.h UniaxialJ2Plasticity.h ViscousDamper.h ViscousMaterial.h WrapperUniaxialMaterial.h pyUCLA.h + + TriMatrix.h # move to SRC/matrix ? ) + add_library(OPS_Material_f) -target_sources(OPS_Material_f PUBLIC +target_sources(OPS_Material_f PRIVATE DoddRestrepo.f STEELDR.f c14-SK-M.f 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/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..cf61568e1 100644 --- a/SRC/material/uniaxial/Makefile +++ b/SRC/material/uniaxial/Makefile @@ -135,6 +135,12 @@ OBJS = UniaxialMaterial.o \ PlateBearingConnectionThermal.o \ DegradingPinchedBW.o \ HystereticPoly.o \ + SMAMaterial.o \ + Masonry.o \ + Masonryt.o \ + Trilinwpd.o \ + Trilinwp.o \ + Trilinwp2.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= "<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/TclModelBuilderUniaxialMaterialCommand.cpp b/SRC/material/uniaxial/TclModelBuilderUniaxialMaterialCommand.cpp index 7546322fc..6d959f183 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 @@ -172,7 +176,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); @@ -815,6 +824,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 +2480,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/drain/CMakeLists.txt b/SRC/material/uniaxial/drain/CMakeLists.txt index cf204d0fb..db5767526 100644 --- a/SRC/material/uniaxial/drain/CMakeLists.txt +++ b/SRC/material/uniaxial/drain/CMakeLists.txt @@ -15,7 +15,7 @@ target_sources(OPS_Material ) add_library(OPS_Material_Uniaxial_Drain_f) -target_sources(OPS_Material_Uniaxial_Drain_f PUBLIC anal00.f common00.f) +target_sources(OPS_Material_Uniaxial_Drain_f PRIVATE anal00.f common00.f) target_link_libraries(OPS_Material PUBLIC OPS_Material_Uniaxial_Drain_f) target_include_directories(OPS_Material PUBLIC ${CMAKE_CURRENT_LIST_DIR}) diff --git a/SRC/modelbuilder/tcl/TclModelBuilder.cpp b/SRC/modelbuilder/tcl/TclModelBuilder.cpp index 38df16dc1..79df7d263 100644 --- a/SRC/modelbuilder/tcl/TclModelBuilder.cpp +++ b/SRC/modelbuilder/tcl/TclModelBuilder.cpp @@ -172,7 +172,7 @@ TclCommand_mesh(ClientData clientData, Tcl_Interp *interp, int argc, int TclCommand_remesh(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) int TclCommand_backgroundMesh(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); #endif // _OPS_Element_PFEM @@ -469,7 +469,7 @@ TclModelBuilder::TclModelBuilder(Domain &theDomain, Tcl_Interp *interp, int NDM, (ClientData)NULL, NULL); Tcl_CreateCommand(interp, "remesh", TclCommand_remesh, (ClientData)NULL, NULL); -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) Tcl_CreateCommand(interp, "background", &TclCommand_backgroundMesh, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); #endif // _OPS_Element_PFEM @@ -654,6 +654,8 @@ TclModelBuilder::TclModelBuilder(Domain &theDomain, Tcl_Interp *interp, int NDM, nodeLoadTag = 0; eleArgStart = 0; + Tcl_SetAssocData(interp, "OPS::theTclModelBuilder", NULL, (ClientData)this); + Tcl_SetAssocData(interp, "OPS::theTclDomain", NULL, (ClientData)&theDomain); } TclModelBuilder::~TclModelBuilder() @@ -1357,7 +1359,7 @@ TclCommand_remesh(ClientData clientData, Tcl_Interp *interp, int argc, } -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) extern int OPS_BgMesh(); int diff --git a/SRC/recorder/TclRecorderCommands.cpp b/SRC/recorder/TclRecorderCommands.cpp index a40d148b8..0814b77ef 100644 --- a/SRC/recorder/TclRecorderCommands.cpp +++ b/SRC/recorder/TclRecorderCommands.cpp @@ -56,7 +56,7 @@ #include #include -#ifdef _OPS_Recorder_PVD +#if defined(OPSDEF_Recorder_PVD) #include #endif // _OPS_Recorder_PVD @@ -64,7 +64,7 @@ #include #include -#ifdef _OPS_Recorder_PVD +#if defined(OPSDEF_Recorder_PVD) extern void* OPS_PVDRecorder(); #endif // _OPS_Recorder_PVD @@ -1844,7 +1844,7 @@ enum outputMode {STANDARD_STREAM, DATA_STREAM, XML_STREAM, DATABASE_STREAM, BIN (*theRecorder) = thePlotter; #endif // _NOGRAPHICS } -#ifdef _OPS_Recorder_PVD +#if defined(OPSDEF_Recorder_PVD) else if (strcmp(argv[1],"pvd") == 0 || strcmp(argv[1],"PVD") == 0) { OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); (*theRecorder) = (Recorder*) OPS_PVDRecorder(); diff --git a/SRC/renderer/CMakeLists.txt b/SRC/renderer/CMakeLists.txt index 8e33757cf..2a645291b 100644 --- a/SRC/renderer/CMakeLists.txt +++ b/SRC/renderer/CMakeLists.txt @@ -1,6 +1,6 @@ target_sources(OPS_Renderer PRIVATE - #PlainMap.cpp # currently added in libOpenSees + PlainMap.cpp # currently added in libOpenSees #AGL_Device.cpp Clipping.cpp db.cpp diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index 13c13082a..9ad4402af 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -139,7 +139,7 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp #include #include -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) #include #endif @@ -191,7 +191,7 @@ extern "C" int OPS_ResetInputNoBuilder(ClientData clientData, Tcl_Interp #include #include -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) #include #endif @@ -260,7 +260,7 @@ extern void OPS_ResponseSpectrumAnalysis(void); #include #include -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) #include #endif @@ -296,7 +296,7 @@ extern void OPS_ResponseSpectrumAnalysis(void); #include -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) #include #include #include @@ -350,7 +350,7 @@ extern void OPS_ResponseSpectrumAnalysis(void); #include #include -#ifdef _OPS_Numerics_UMFPACK +#if defined(OPSDEF_Numerics_UMFPACK) #include #include #endif // _OPS_Numerics_UMFPACK @@ -543,7 +543,7 @@ DirectIntegrationAnalysis *theTransientAnalysis = 0; VariableTimeStepDirectIntegrationAnalysis *theVariableTimeStepTransientAnalysis = 0; int numEigen = 0; -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) static PFEMAnalysis* thePFEMAnalysis = 0; #endif @@ -1150,7 +1150,7 @@ int OpenSeesAppInit(Tcl_Interp *interp) { // create an error handler -#ifdef _NOGRAPHICS +#if defined(_NOGRAPHICS) #else theTclVideoPlayer = 0; @@ -1510,7 +1510,7 @@ wipeAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **arg theTransientAnalysis =0; theVariableTimeStepTransientAnalysis =0; // theSensitivityAlgorithm=0; -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) thePFEMAnalysis = 0; #endif theTest = 0; @@ -1922,7 +1922,7 @@ analyzeModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **arg return TCL_ERROR; result = theStaticAnalysis->analyze(numIncr); -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) } else if(thePFEMAnalysis != 0) { result = thePFEMAnalysis->analyze(); #endif @@ -2469,7 +2469,7 @@ specifyAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, #endif // AddingSensitivity:END ///////////////////////////////// -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) } else if(strcmp(argv[1], "PFEM") == 0) { if(argc < 5) { @@ -3029,7 +3029,7 @@ specifySOE(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) } #endif -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) else if(strcmp(argv[1], "PFEM") == 0) { if(argc <= 2) { PFEMSolver* theSolver = new PFEMSolver(); @@ -3320,7 +3320,7 @@ specifySOE(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) SymSparseLinSolver *theSolver = new SymSparseLinSolver(); theSOE = new SymSparseLinSOE(*theSolver, lSparse); } -#ifdef _OPS_Numerics_UMFPACK +#if defined(OPSDEF_Numerics_UMFPACK) else if ((strcmp(argv[1],"UmfPack") == 0) || (strcmp(argv[1],"Umfpack") == 0)) { // now must determine the type of solver to create from rest of args @@ -4220,7 +4220,7 @@ specifyCTest(ClientData clientData, Tcl_Interp *interp, int argc, if (Tcl_GetInt(interp, argv[7], &maxIncr) != TCL_OK) return TCL_ERROR; } -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) } else if (strcmp(argv[1],"PFEM") == 0) { if(argc > 8) { if(Tcl_GetDouble(interp, argv[2], &tol) != TCL_OK) @@ -4349,7 +4349,7 @@ specifyCTest(ClientData clientData, Tcl_Interp *interp, int argc, theNewTest = new CTestRelativeEnergyIncr(tol,numIter,printIt,normType); else if (strcmp(argv[1],"RelativeTotalNormDispIncr") == 0) theNewTest = new CTestRelativeTotalNormDispIncr(tol,numIter,printIt,normType); -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) else if (strcmp(argv[1],"PFEM") == 0) theNewTest = new CTestPFEM(tol,tolp,tol2,tolp2,tolrel,tolprel,numIter,maxIncr,printIt,normType); #endif // _OPS_Element_PFEM @@ -4772,7 +4772,7 @@ specifyIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, if (theTransientAnalysis != 0) theTransientAnalysis->setIntegrator(*theTransientIntegrator); } -#ifdef _OPS_Element_PFEM +#if defined(OPSDEF_Element_PFEM) else if (strcmp(argv[1],"PFEM") == 0) { theTransientIntegrator = new PFEMIntegrator(); diff --git a/Win64/proj/element/element.vcxproj b/Win64/proj/element/element.vcxproj index a5f41e8f0..c3087c05a 100644 --- a/Win64/proj/element/element.vcxproj +++ b/Win64/proj/element/element.vcxproj @@ -208,6 +208,7 @@ + @@ -222,6 +223,9 @@ + + + diff --git a/Win64/proj/element/element.vcxproj.filters b/Win64/proj/element/element.vcxproj.filters index ca82be0cd..5f1542849 100644 --- a/Win64/proj/element/element.vcxproj.filters +++ b/Win64/proj/element/element.vcxproj.filters @@ -132,6 +132,9 @@ {962a9734-043f-43c1-8e90-1a79eeef085f} + + {61bce605-5c0a-4311-b059-28f47dbe6364} + @@ -953,6 +956,18 @@ mixedBeamColumn + + masonry + + + masonry + + + masonry + + + forceBeamColumn\beamIntegration + diff --git a/Win64/proj/material/material.vcxproj b/Win64/proj/material/material.vcxproj index 6aa489bbd..d60bcec0f 100644 --- a/Win64/proj/material/material.vcxproj +++ b/Win64/proj/material/material.vcxproj @@ -323,6 +323,8 @@ + + @@ -353,6 +355,7 @@ + @@ -388,6 +391,8 @@ + + diff --git a/Win64/proj/material/material.vcxproj.filters b/Win64/proj/material/material.vcxproj.filters index 10f762fe1..b7a9529b3 100644 --- a/Win64/proj/material/material.vcxproj.filters +++ b/Win64/proj/material/material.vcxproj.filters @@ -1370,6 +1370,21 @@ section + + uniaxial + + + uniaxial + + + uniaxial + + + uniaxial + + + uniaxial +