From 37230d18877dc4ac58b7b56539fadf4f92466b1a Mon Sep 17 00:00:00 2001 From: Long Date: Fri, 15 Nov 2019 15:59:18 -0800 Subject: [PATCH 001/207] Adding bounding surface correction. --- SRC/material/nD/UWmaterials/PM4Silt.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/SRC/material/nD/UWmaterials/PM4Silt.cpp b/SRC/material/nD/UWmaterials/PM4Silt.cpp index 802c1ff71..c9d90bdbd 100644 --- a/SRC/material/nD/UWmaterials/PM4Silt.cpp +++ b/SRC/material/nD/UWmaterials/PM4Silt.cpp @@ -398,6 +398,15 @@ int PM4Silt::commitState(void) { Vector n(3), R(3), dFabric(3); + this->GetElasticModuli(mSigma, mK, mG, mMcur, mzcum); + + // Bounding surface correction + if (mMcur > mMb) { + double p = 0.5 * GetTrace(mSigma); + Vector r = (mSigma - p * mI1) * (mMb / mMcur / p);; + mSigma = p * mI1 + r * p; + mAlpha = r * (mMb - m_m) / mMb; + } mAlpha_in_n = mAlpha_in; mAlpha_n = mAlpha; @@ -417,7 +426,6 @@ PM4Silt::commitState(void) mDGamma_n = mDGamma; mVoidRatio = m_e_init - (1 + m_e_init) * GetTrace(mEpsilon); - this->GetElasticModuli(mSigma, mK, mG, mMcur, mzcum); mCe = GetStiffness(mK, mG); mCep = GetElastoPlasticTangent(mSigma_n, mCe, R, n, mKp); mCep_Consistent = mCe; From 0aec74fd25b2f63c244934dfcbbd14ef71c9ec33 Mon Sep 17 00:00:00 2001 From: Long Date: Mon, 25 Nov 2019 16:08:29 -0800 Subject: [PATCH 002/207] add bounding surface correction for elastoplastic stage --- SRC/material/nD/UWmaterials/PM4Silt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/material/nD/UWmaterials/PM4Silt.cpp b/SRC/material/nD/UWmaterials/PM4Silt.cpp index c9d90bdbd..3b597f5af 100644 --- a/SRC/material/nD/UWmaterials/PM4Silt.cpp +++ b/SRC/material/nD/UWmaterials/PM4Silt.cpp @@ -401,7 +401,7 @@ PM4Silt::commitState(void) this->GetElasticModuli(mSigma, mK, mG, mMcur, mzcum); // Bounding surface correction - if (mMcur > mMb) { + if (mMcur > mMb && me2p) { double p = 0.5 * GetTrace(mSigma); Vector r = (mSigma - p * mI1) * (mMb / mMcur / p);; mSigma = p * mI1 + r * p; From d0292aa7771d5f0612ee9e586e37cf96fa80c776 Mon Sep 17 00:00:00 2001 From: Long Date: Fri, 13 Dec 2019 19:04:00 -0800 Subject: [PATCH 003/207] Add bounding surface correction for PM4Sand model. --- SRC/material/nD/UWmaterials/PM4Sand.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/SRC/material/nD/UWmaterials/PM4Sand.cpp b/SRC/material/nD/UWmaterials/PM4Sand.cpp index d21706989..0a6ea5796 100644 --- a/SRC/material/nD/UWmaterials/PM4Sand.cpp +++ b/SRC/material/nD/UWmaterials/PM4Sand.cpp @@ -414,7 +414,14 @@ int PM4Sand::commitState(void) { Vector n(3), R(3), dFabric(3); + this->GetElasticModuli(mSigma, mK, mG, mMcur, mzcum); + if (mMcur > mMb && me2p) { + double p = 0.5 * GetTrace(mSigma); + Vector r = (mSigma - p * mI1) * (mMb / mMcur / p); + mSigma = p * mI1 + r * p; + mAlpha = r * (mMb - m_m) / mMb; + } mAlpha_in_n = mAlpha_in; mAlpha_n = mAlpha; mAlpha_in_p_n = mAlpha_in_p; @@ -433,7 +440,6 @@ PM4Sand::commitState(void) mDGamma_n = mDGamma; mVoidRatio = m_e_init - (1 + m_e_init) * GetTrace(mEpsilon); - this->GetElasticModuli(mSigma, mK, mG, mMcur, mzcum); mCe = GetStiffness(mK, mG); mCep = GetElastoPlasticTangent(mSigma_n, mCe, R, n, mKp); mCep_Consistent = mCe; From fd53d045eb880fecade5eccefe227ffc17c82dd8 Mon Sep 17 00:00:00 2001 From: mhscott Date: Sun, 25 Oct 2020 17:54:20 -0700 Subject: [PATCH 004/207] Adding OPS command for Simpson beam integration --- .../SimpsonBeamIntegration.cpp | 197 ++++++++++-------- 1 file changed, 112 insertions(+), 85 deletions(-) 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; +} From ebffb776a3f15bd5402eb2744b78903836a3ddf4 Mon Sep 17 00:00:00 2001 From: mhscott Date: Sun, 25 Oct 2020 17:55:01 -0700 Subject: [PATCH 005/207] Modifying OPS command for gradientInelasticBC 2d and 3d --- .../GradientInelasticBeamColumn2d.cpp | 20 +++++++++++-------- .../GradientInelasticBeamColumn3d.cpp | 19 ++++++++++-------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/SRC/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn2d.cpp b/SRC/element/gradientInelasticBeamColumn/GradientInelasticBeamColumn2d.cpp index e76b82b76..b0b87d04a 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 13fac7695..49da58e1d 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; } From 7dcc82bbf9a9f8152c06a7823fb5e71b26744b1d Mon Sep 17 00:00:00 2001 From: mhscott Date: Sun, 25 Oct 2020 17:55:49 -0700 Subject: [PATCH 006/207] Adding Simpson integration to beam integration command --- SRC/interpreter/OpenSeesBeamIntegrationCommands.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SRC/interpreter/OpenSeesBeamIntegrationCommands.cpp b/SRC/interpreter/OpenSeesBeamIntegrationCommands.cpp index 3cec41720..6055a6516 100644 --- a/SRC/interpreter/OpenSeesBeamIntegrationCommands.cpp +++ b/SRC/interpreter/OpenSeesBeamIntegrationCommands.cpp @@ -51,6 +51,7 @@ 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&); @@ -81,6 +82,7 @@ namespace { 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)); From 0860617dcf1a533889aa9261dc96c1e126670a7c Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Tue, 2 Feb 2021 19:21:41 +0100 Subject: [PATCH 007/207] use a serializer --- .../domain/partitioned/PartitionedDomain.cpp | 2 +- SRC/recorder/MPCORecorder.cpp | 402 ++++++++++-------- 2 files changed, 214 insertions(+), 190 deletions(-) diff --git a/SRC/domain/domain/partitioned/PartitionedDomain.cpp b/SRC/domain/domain/partitioned/PartitionedDomain.cpp index e1d1334b0..b9f44a168 100644 --- a/SRC/domain/domain/partitioned/PartitionedDomain.cpp +++ b/SRC/domain/domain/partitioned/PartitionedDomain.cpp @@ -1498,7 +1498,7 @@ PartitionedDomain::partition(int numPartitions, bool usingMain, int mainPartitio Graph &theEleGraph = this->getElementGraph(); // now we call partition on the domainPartitioner which does the partitioning - DomainPartitioner *thePartitioner = 0;//this->getPartitioner(); + DomainPartitioner *thePartitioner = this->getPartitioner(); if (thePartitioner != 0) { thePartitioner->setPartitionedDomain(*this); result = thePartitioner->partition(numPartitions, usingMain, mainPartitionID, specialElementTag); diff --git a/SRC/recorder/MPCORecorder.cpp b/SRC/recorder/MPCORecorder.cpp index 7f1dbf8c5..69ceac043 100755 --- a/SRC/recorder/MPCORecorder.cpp +++ b/SRC/recorder/MPCORecorder.cpp @@ -4009,6 +4009,122 @@ namespace mpco { } +/*utilities for serialization into a string*/ +namespace mpco +{ + + namespace serialization + { + +#define SerializerFormatDouble std::setprecision(std::numeric_limits::digits10 + 1) + + class Serializer + { + private: + std::stringstream ss; + + public: + Serializer() = default; + Serializer(const char* c) + : ss(c) + {} + inline std::string str() const { + return ss.str(); + } + explicit operator bool() const { + return !ss.fail(); + } + bool operator!() const { + return ss.fail(); + } + + public: + inline Serializer& operator << (const std::string& x) { + ss << x << '\n'; + return *this; + } + inline Serializer& operator << (bool x) { + ss << x << '\n'; + return *this; + } + inline Serializer& operator << (int x) { + ss << x << '\n'; + return *this; + } + inline Serializer& operator << (std::size_t x) { + ss << x << '\n'; + return *this; + } + inline Serializer& operator << (double x) { + ss << SerializerFormatDouble << x << '\n'; + return *this; + } + inline Serializer& operator << (const std::vector& x) { + ss << x.size() << '\n'; + for (auto i : x) + ss << i << '\n'; + return *this; + } + inline Serializer& operator << (const std::vector& x) { + ss << x.size() << '\n'; + for (auto i : x) + ss << i << '\n'; + return *this; + } + + public: + inline Serializer& operator >> (std::string& x) { + std::getline(ss, x, '\n'); + return *this; + } + inline Serializer& operator >> (bool& x) { + ss >> x; + return *this; + } + inline Serializer& operator >> (int& x) { + ss >> x; + return *this; + } + inline Serializer& operator >> (mpco::OutputFrequency::IncrementType& x) { + int temp; + ss >> temp; + x = static_cast(temp); + return *this; + } + inline Serializer& operator >> (std::size_t& x) { + ss >> x; + return *this; + } + inline Serializer& operator >> (double& x) { + ss >> x; + return *this; + } + inline Serializer& operator >> (std::vector& x) { + std::size_t n; + if (!(ss >> n)) + return *this; + x.resize(n); + for(std::size_t i = 0; i < n; ++i) + ss >> x[i]; + return *this; + } + inline Serializer& operator >> (std::vector& x) { + std::size_t n; + if (!(ss >> n)) + return *this; + x.resize(n); + for (std::size_t i = 0; i < n; ++i) { + int temp; + ss >> temp; + x[i] = static_cast(temp); + } + return *this; + } + }; + + } +} + /************************************************************************************* private_data class. @@ -4047,7 +4163,6 @@ class MPCORecorder::private_data // domain changed stuff... bool first_domain_changed_done; - int domain_changed_stamp; // info mpco::ProcessInfo info; @@ -4262,9 +4377,10 @@ int MPCORecorder::sendSelf(int commitTag, Channel &theChannel) m_data->send_self_count++; + // info... std::stringstream _info; _info << "MPCORecorder sendSelf from: " << m_data->p_id << ", send self count = " << m_data->send_self_count << "\n"; - std::cout << _info.str(); + opserr << _info.str().c_str(); // element results requests std::string elem_res_merged_string; @@ -4274,7 +4390,7 @@ int MPCORecorder::sendSelf(int commitTag, Channel &theChannel) if (i > 0) { ss << ':'; // char separator for results } - const std::vector &i_request = m_data->elemental_results_requests[i]; + const std::vector& i_request = m_data->elemental_results_requests[i]; for (size_t j = 0; j < i_request.size(); j++) { if (j > 0) { ss << '.'; // char separator for jth token @@ -4283,102 +4399,57 @@ int MPCORecorder::sendSelf(int commitTag, Channel &theChannel) } elem_res_merged_string = ss.str(); } - - // send misc info - { - ID aux(9); - aux(0) = getTag(); - aux(1) = m_data->send_self_count; // use the send self counter as p_id in the receiver - aux(2) = static_cast(m_data->filename.size()); - aux(3) = static_cast(m_data->nodal_results_requests.size()); - aux(4) = static_cast(elem_res_merged_string.size()); - aux(5) = static_cast(m_data->has_region); - aux(6) = static_cast(m_data->node_set.size()); - aux(7) = static_cast(m_data->elem_set.size()); - aux(8) = static_cast(m_data->sens_grad_indices.size()); - - if (theChannel.sendID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to send misc info\n"; - return -1; - } - } - - // send filename - if (m_data->filename.size() > 0) { - std::vector aux(m_data->filename.begin(), m_data->filename.end()); - Message msg(aux.data(), static_cast(m_data->filename.size())); - if (theChannel.sendMsg(0, commitTag, msg) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to send filename\n"; - return -1; - } - } - // send output frequency + // serializer + mpco::serialization::Serializer ser; + + // serialize everything + if (!(ser + // misc info + << getTag() + << m_data->send_self_count + // filename + << m_data->filename + // output frequency + << m_data->output_freq.type + << m_data->output_freq.dt + << m_data->output_freq.nsteps + // node result requests + << m_data->nodal_results_requests + // node result requests (sens grad indices) + << m_data->sens_grad_indices + // element result requests + << elem_res_merged_string + // region + << m_data->has_region + << m_data->node_set + << m_data->elem_set + )) { - Vector aux(3); - aux(0) = static_cast(m_data->output_freq.type); - aux(1) = static_cast(m_data->output_freq.dt); - aux(2) = static_cast(m_data->output_freq.nsteps); - if (theChannel.sendVector(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to send output frequency\n"; - return -1; - } - } - - // send node result requests - if (m_data->nodal_results_requests.size() > 0) { - ID aux(static_cast(m_data->nodal_results_requests.size())); - for (size_t i = 0; i < m_data->nodal_results_requests.size(); i++) - aux(static_cast(i)) = static_cast(m_data->nodal_results_requests[i]); - if (theChannel.sendID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to send node result requests\n"; - return -1; - } - } - - // send node result requests (sens grad indices) - if (m_data->sens_grad_indices.size() > 0) { - ID aux(static_cast(m_data->sens_grad_indices.size())); - for (size_t i = 0; i < m_data->sens_grad_indices.size(); i++) - aux(static_cast(i)) = static_cast(m_data->sens_grad_indices[i]); - if (theChannel.sendID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to send node result requests (sensitivity parameter indices)\n"; - return -1; - } + opserr << "MPCORecorder::sendSelf() - failed to serialzie data\n"; + return -1; } - // send element result requests - if (elem_res_merged_string.size() > 0) { - std::vector aux(elem_res_merged_string.begin(), elem_res_merged_string.end()); - Message msg(aux.data(), static_cast(elem_res_merged_string.size())); - if (theChannel.sendMsg(0, commitTag, msg) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to send element result requests\n"; - return -1; - } + // get message string and size + std::string msg_string = ser.str(); + std::vector msg_data(msg_string.size() + 1); + std::copy(msg_string.begin(), msg_string.end(), msg_data.begin()); + msg_data.back() = '\0'; + int msg_data_size = static_cast(msg_string.size()); + + // send message size + ID idata(1); + idata(0) = msg_data_size; + if (theChannel.sendID(0, commitTag, idata) < 0) { + opserr << "MPCORecorder::sendSelf() - failed to send message size\n"; + return -1; } - if (m_data->has_region) { - // send node set - if (m_data->node_set.size()) { - ID aux(static_cast(m_data->node_set.size())); - for (size_t i = 0; i < m_data->node_set.size(); i++) - aux(static_cast(i)) = m_data->node_set[i]; - if (theChannel.sendID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to send node set\n"; - return -1; - } - } - - // send elem set - if (m_data->elem_set.size()) { - ID aux(static_cast(m_data->elem_set.size())); - for (size_t i = 0; i < m_data->elem_set.size(); i++) - aux(static_cast(i)) = m_data->elem_set[i]; - if (theChannel.sendID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::sendSelf() - failed to send element set\n"; - return -1; - } - } + // send message + Message msg(msg_data.data(), msg_data_size); + if (theChannel.sendMsg(0, commitTag, msg) < 0) { + opserr << "MPCORecorder::sendSelf() - failed to send message\n"; + return -1; } return 0; @@ -4399,86 +4470,64 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker m_data = new private_data(); m_data->send_self_count = -1; - // recv misc info - size_t aux_filename_size(0); - size_t aux_node_res_size(0); - size_t aux_res_merged_string_size(0); - size_t aux_node_set_size(0); - size_t aux_elem_set_size(0); - size_t aux_sens_grad_indices_size(0); - { - ID aux(9); - if (theChannel.recvID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::recvSelf() - " << m_data->p_id << " - failed to recv misc info\n"; - return -1; - } - setTag(aux(0)); - m_data->p_id = aux(1); // use the send self counter as p_id in the receiver - aux_filename_size = aux(2); - aux_node_res_size = aux(3); - aux_res_merged_string_size = aux(4); - m_data->has_region = aux(5);// != 0; - aux_node_set_size = static_cast(aux(6)); - aux_elem_set_size = static_cast(aux(7)); + // recv message size + ID idata(1); + if (theChannel.recvID(0, commitTag, idata) < 0) { + opserr << "MPCORecorder::recvSelf() - failed to recv message size\n"; + return -1; } + int msg_data_size = idata(0); - // recv filename - if (aux_filename_size > 0) { - std::vector aux(aux_filename_size); - Message msg(aux.data(), static_cast(aux_filename_size)); - if (theChannel.recvMsg(0, commitTag, msg) < 0) { - opserr << "MPCORecorder::recvSelf() - failed to recv filename\n"; - return -1; - } - m_data->filename = std::string(aux.begin(), aux.end()); + // recv message + std::vector msg_data(static_cast(msg_data_size) + 1); + Message msg(msg_data.data(), msg_data_size); + if (theChannel.recvMsg(0, commitTag, msg) < 0) { + opserr << "MPCORecorder::recvSelf() - failed to recv message\n"; + return -1; } + msg_data.back() = '\0'; - // recv output frequency - { - Vector aux(3); - if (theChannel.recvVector(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::recvSelf() - failed to recv output frequency\n"; - return -1; - } - m_data->output_freq.type = static_cast(static_cast(aux(0))); - m_data->output_freq.dt = aux(1); - m_data->output_freq.nsteps = static_cast(aux(2)); - } + // serializer + mpco::serialization::Serializer ser(msg_data.data()); - // recv node result requests - if (aux_node_res_size > 0) { - ID aux(static_cast(aux_node_res_size)); - if (theChannel.recvID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::recvSelf() - failed to recv node result requests\n"; - return -1; - } - m_data->nodal_results_requests.resize(aux_node_res_size); - for (size_t i = 0; i < aux_node_res_size; i++) - m_data->nodal_results_requests[i] = static_cast(aux(static_cast(i))); - } + // aux data for de-serialziation + int my_tag; + std::string elem_res_merged_string; - // recv node result requests (sens grad indices) - if (aux_sens_grad_indices_size > 0) { - ID aux(static_cast(aux_sens_grad_indices_size)); - if (theChannel.recvID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::recvSelf() - failed to recv node result requests (sensitivity parameter indices)\n"; - return -1; - } - m_data->sens_grad_indices.resize(aux_sens_grad_indices_size); - for (size_t i = 0; i < aux_sens_grad_indices_size; i++) - m_data->sens_grad_indices[i] = aux(static_cast(i)); + // de-serialize everything + if (!(ser + // misc info + >> my_tag + >> m_data->p_id // use the send self counter as p_id in the receiver + // filename + >> m_data->filename + // output frequency + >> m_data->output_freq.type + >> m_data->output_freq.dt + >> m_data->output_freq.nsteps + // node result requests + >> m_data->nodal_results_requests + // node result requests (sens grad indices) + >> m_data->sens_grad_indices + // element result requests + >> elem_res_merged_string + // region + >> m_data->has_region + >> m_data->node_set + >> m_data->elem_set + )) + { + opserr << "MPCORecorder::recvSelf() - failed to de-serialzie data\n"; + return -1; } + // set tag + setTag(my_tag); + // recv element result requests - if (aux_res_merged_string_size > 0) { - std::vector aux(aux_res_merged_string_size); - Message msg(aux.data(), static_cast(aux_res_merged_string_size)); - if (theChannel.recvMsg(0, commitTag, msg) < 0) { - opserr << "MPCORecorder::recvSelf() - failed to recv element result requests\n"; - return -1; - } + if (elem_res_merged_string.size() > 0) { std::vector aux_1; - utils::strings::split(std::string(aux.begin(), aux.end()), ':', aux_1, true); + utils::strings::split(std::string(elem_res_merged_string.begin(), elem_res_merged_string.end()), ':', aux_1, true); for (size_t i = 0; i < aux_1.size(); i++) { std::vector aux_2; utils::strings::split(aux_1[i], '.', aux_2, true); @@ -4486,32 +4535,7 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker } } - if (m_data->has_region) { - // recv node set - if (aux_node_set_size > 0) { - ID aux(static_cast(aux_node_set_size)); - if (theChannel.recvID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::recvSelf() - failed to recv node set\n"; - return -1; - } - m_data->node_set.resize(aux_node_set_size); - for (size_t i = 0; i < aux_node_set_size; i++) - m_data->node_set[i] = aux(static_cast(i)); - } - - // recv elem set - if (aux_elem_set_size > 0) { - ID aux(static_cast(aux_elem_set_size)); - if (theChannel.recvID(0, commitTag, aux) < 0) { - opserr << "MPCORecorder::recvSelf() - failed to recv elem set\n"; - return -1; - } - m_data->elem_set.resize(aux_elem_set_size); - for (size_t i = 0; i < aux_elem_set_size; i++) - m_data->elem_set[i] = aux(static_cast(i)); - } - } - + // print to debug std::stringstream _info; _info << "MPCORecorder recvSelf from: " << m_data->p_id << ", send self count = " << m_data->send_self_count << "\n"; _info << "filename = " << m_data->filename << "\n"; From c640c8cd504f5b622f6e3537806f60388bb83af8 Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Wed, 3 Feb 2021 15:37:26 +0100 Subject: [PATCH 008/207] last fixes --- SRC/recorder/MPCORecorder.cpp | 76 +++++++---------------------------- 1 file changed, 14 insertions(+), 62 deletions(-) diff --git a/SRC/recorder/MPCORecorder.cpp b/SRC/recorder/MPCORecorder.cpp index 69ceac043..9435e60f9 100755 --- a/SRC/recorder/MPCORecorder.cpp +++ b/SRC/recorder/MPCORecorder.cpp @@ -4040,7 +4040,7 @@ namespace mpco public: inline Serializer& operator << (const std::string& x) { - ss << x << '\n'; + ss << x.length() << ' ' << x << '\n'; return *this; } inline Serializer& operator << (bool x) { @@ -4051,6 +4051,10 @@ namespace mpco ss << x << '\n'; return *this; } + inline Serializer& operator << (mpco::OutputFrequency::IncrementType x) { + ss << static_cast(x) << '\n'; + return *this; + } inline Serializer& operator << (std::size_t x) { ss << x << '\n'; return *this; @@ -4074,6 +4078,10 @@ namespace mpco public: inline Serializer& operator >> (std::string& x) { + std::size_t n; + ss >> n; // needed to make it work even when string is not the first entry + char dummy; + ss.read(&dummy, 1); // 1 white space std::getline(ss, x, '\n'); return *this; } @@ -4377,24 +4385,18 @@ int MPCORecorder::sendSelf(int commitTag, Channel &theChannel) m_data->send_self_count++; - // info... - std::stringstream _info; - _info << "MPCORecorder sendSelf from: " << m_data->p_id << ", send self count = " << m_data->send_self_count << "\n"; - opserr << _info.str().c_str(); - // element results requests std::string elem_res_merged_string; { std::stringstream ss; for (size_t i = 0; i < m_data->elemental_results_requests.size(); i++) { - if (i > 0) { + if (i > 0) ss << ':'; // char separator for results - } const std::vector& i_request = m_data->elemental_results_requests[i]; for (size_t j = 0; j < i_request.size(); j++) { - if (j > 0) { + if (j > 0) ss << '.'; // char separator for jth token - } + ss << i_request[j]; } } elem_res_merged_string = ss.str(); @@ -4535,57 +4537,7 @@ int MPCORecorder::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker } } - // print to debug - std::stringstream _info; - _info << "MPCORecorder recvSelf from: " << m_data->p_id << ", send self count = " << m_data->send_self_count << "\n"; - _info << "filename = " << m_data->filename << "\n"; - _info << "freq: "; - if (m_data->output_freq.type == mpco::OutputFrequency::DeltaTime) - _info << "dt = " << m_data->output_freq.dt << "\n"; - else - _info << "nsteps = " << m_data->output_freq.nsteps << "\n"; - _info << "nodal results [" << m_data->nodal_results_requests.size() << "]" << "\n"; - for (size_t i = 0; i < m_data->nodal_results_requests.size(); i++) { - _info << " " << m_data->nodal_results_requests[i] << "\n"; - } - _info << "elemental results [" << m_data->elemental_results_requests.size() << "]" << "\n"; - for (size_t i = 0; i < m_data->elemental_results_requests.size(); i++) { - const std::vector &ireq = m_data->elemental_results_requests[i]; - for (size_t j = 0; j < ireq.size(); j++) { - if (j > 0) - _info << "."; - _info << ireq[j]; - } - _info << "\n"; - } - _info << "node set:" << "\n" << "["; - { - int n_counter(0); - for (size_t i = 0; i < m_data->node_set.size(); i++) { - _info << m_data->node_set[i] << " "; - n_counter++; - if (n_counter >= 5) { - _info << "\n"; - n_counter = 0; - } - } - } - _info << "]\n"; - _info << "elem set:" << "\n" << "["; - { - int n_counter(0); - for (size_t i = 0; i < m_data->elem_set.size(); i++) { - _info << m_data->elem_set[i] << " "; - n_counter++; - if (n_counter >= 5) { - _info << "\n"; - n_counter = 0; - } - } - } - _info << "]" << "\n"; - std::cout << _info.str(); - + // done return 0; } @@ -4650,7 +4602,7 @@ int MPCORecorder::initialize() for (size_t i = 0; i < filename_words.size() - 1; i++) ss_filename << filename_words[i] << '.'; if (m_data->send_self_count != 0) { // > 0 -> we are in p0, < 0 -> we are in secondary procs, = 0 -> not in parallel - ss_filename << "p" << m_data->p_id << '.'; + ss_filename << "part-" << m_data->p_id << '.'; } ss_filename << filename_words.back(); the_filename = ss_filename.str(); From 03638b1f1defad409157ad32e653a075cc655623 Mon Sep 17 00:00:00 2001 From: Massimo Petracca Date: Fri, 5 Feb 2021 11:04:50 +0100 Subject: [PATCH 009/207] remove an old workaround for a bug that has been fixed recently There was a bug in the output of the yLoc of the fiber in FiberSection3d (changed sign) that has been now fixed in a recent commit. So we need to remove the workaround we had in the MPCORecorder to deal with that --- SRC/recorder/MPCORecorder.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/SRC/recorder/MPCORecorder.cpp b/SRC/recorder/MPCORecorder.cpp index 9435e60f9..2b381a432 100755 --- a/SRC/recorder/MPCORecorder.cpp +++ b/SRC/recorder/MPCORecorder.cpp @@ -5411,7 +5411,7 @@ int MPCORecorder::writeSections() FiberSection3d SEC_TAG_FiberSection3d FiberSectionGJ SEC_TAG_FiberSectionGJ */ - switch (sfd->getClassTag()) { + /*switch (sfd->getClassTag()) { case SEC_TAG_FiberSection3d: case SEC_TAG_FiberSectionGJ: { mpco::element::SectionAssignment &i_sec_asgn = it->second; @@ -5419,7 +5419,12 @@ int MPCORecorder::writeSections() i_sec_asgn.fiber_section_data.fibers[fiber_id].y *= -1.0; } } - } + }*/ + /* + $MP(2021/02/05). Update: This bug in the FiberSection3d has been solved by prof. Scott + in commit: https://github.com/OpenSees/OpenSees/commit/948b6f94c602e5d0140645c95a836ffb806e1eb6 + (Making centroid computation an option for fiber sections) + */ } } /* From 05ceb4bef820f8cbfe8a4d2e1225fad8bf485a07 Mon Sep 17 00:00:00 2001 From: Long Chen Date: Thu, 25 Feb 2021 14:55:50 -0800 Subject: [PATCH 010/207] Add bounding surface correction to PM4Silt and remove a limit on Cdz --- SRC/material/nD/UWmaterials/PM4Silt.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/SRC/material/nD/UWmaterials/PM4Silt.cpp b/SRC/material/nD/UWmaterials/PM4Silt.cpp index cff774c9c..ce51b4558 100644 --- a/SRC/material/nD/UWmaterials/PM4Silt.cpp +++ b/SRC/material/nD/UWmaterials/PM4Silt.cpp @@ -22,7 +22,7 @@ // Computational Geomechanics Group // University of Washington // Date: Sep 2018 -// Last Modified: Aug 2019 +// Last Modified: Feb 2021 // Description: This file contains the implementation for the PM4Silt class. // PM4Silt(Version 1): A Silt Plasticity Model For Earthquake Engineering Applications @@ -400,10 +400,11 @@ PM4Silt::commitState(void) Vector n(3), R(3), dFabric(3); this->GetElasticModuli(mSigma, mK, mG, mMcur, mzcum); - // Bounding surface correction - if (mMcur > mMb && me2p) { + // Bounding surface correction for non K0 condition + if (mMcur > mMb && me2p && fabs(mSigma(1) - mSigma(0)) < 1e-5) { + // if (mMcur > mMb && me2p) { double p = 0.5 * GetTrace(mSigma); - Vector r = (mSigma - p * mI1) * (mMb / mMcur / p);; + Vector r = (mSigma - p * mI1) * (mMb / mMcur / p); mSigma = p * mI1 + r * p; mAlpha = r * (mMb - m_m) / mMb; } @@ -2472,8 +2473,8 @@ PM4Silt::GetStateDependent(const Vector &stress, const Vector &alpha, const Vect K_p = fmax(0.0, K_p); hp = m_hpo * exp(-0.7 + 0.2 * pow(Macauley(3 - ksi / m_lambda), 2.0)); Crot2 = 1 - Czpk2; - Cdz = fmax((1 - Crot2 * sqrt(2.0) * zpeak / m_z_max)*(m_z_max / (m_z_max + Crot2*zcum)), 1 / (1 + m_z_max / 2.0)); - // double Cdz = (1 - Crot2 * sqrt(2.0) * zpeak / m_z_max)*(m_z_max / (m_z_max + Crot2*zcum)); + // Cdz = fmax((1 - Crot2 * sqrt(2.0) * zpeak / m_z_max)*(m_z_max / (m_z_max + Crot2*zcum)), 1 / (1 + m_z_max / 2.0)); + Cdz = (1 - Crot2 * sqrt(2.0) * zpeak / m_z_max)*(m_z_max / (m_z_max + Crot2*zcum)); Cwet = fmin(1.0, (1.0 / (1 + pow(0.02 / AlphaAlphaBDotN, 4.0)) + 1.0 / (1 + pow(ksi / m_lambda / 0.1, 2.0)))); Adc = m_Ado * (1 + Macauley(DoubleDot2_2_Contr(fabric, n))) / (hp * Cdz * Cwet); Cin = Macauley(DoubleDot2_2_Contr(fabric, n)) * sqrt(2.0) / m_z_max; From 8b3f0d58735eaf4cc36db0ec783a01ecd46b92a6 Mon Sep 17 00:00:00 2001 From: kkolozvari <53920372+kkolozvari@users.noreply.github.com> Date: Sun, 7 Mar 2021 17:21:39 -0800 Subject: [PATCH 011/207] Add SFI-MVLEM-3D --- SRC/Makefile | 1 + .../FEM_ObjectBrokerAllClasses.cpp | 4 + SRC/classTags.h | 1 + SRC/element/TclElementCommands.cpp | 12 + SRC/element/mvlem/Makefile | 3 +- SRC/element/mvlem/SFI_MVLEM_3D.cpp | 3133 +++++++++++++++++ SRC/element/mvlem/SFI_MVLEM_3D.h | 225 ++ SRC/interpreter/OpenSeesElementCommands.cpp | 2 + SRC/material/nD/FSAM.cpp | 37 +- SRC/material/nD/FSAM.h | 2 + SRC/recorder/GmshRecorder.cpp | 1 + SRC/recorder/PVDRecorder.cpp | 1 + SRC/recorder/VTK_Recorder.cpp | 1 + Win32/proj/element/element.vcxproj | 2 + Win32/proj/element/element.vcxproj.filters | 6 + Win64/proj/element/element.vcxproj | 2 + Win64/proj/element/element.vcxproj.filters | 6 + Win64/proj/openSees/OpenSees.vcxproj | 2 +- 18 files changed, 3437 insertions(+), 4 deletions(-) create mode 100644 SRC/element/mvlem/SFI_MVLEM_3D.cpp create mode 100644 SRC/element/mvlem/SFI_MVLEM_3D.h diff --git a/SRC/Makefile b/SRC/Makefile index 40c35e7d0..b84d17ca0 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -630,6 +630,7 @@ ELE_LIBS = $(FE)/element/Element.o \ $(FE)/element/mvlem/MVLEM.o \ $(FE)/element/mvlem/SFI_MVLEM.o \ $(FE)/element/mvlem/MVLEM_3D.o \ + $(FE)/element/mvlem/SFI_MVLEM_3D.o \ $(FE)/element/UWelements/Quad4FiberOverlay.o \ $(FE)/element/UWelements/Brick8FiberOverlay.o \ $(FE)/element/UWelements/QuadBeamEmbedContact.o \ diff --git a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp index 2dcbbed0f..de4b7ef96 100644 --- a/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp +++ b/SRC/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp @@ -276,6 +276,7 @@ #include "mvlem/MVLEM.h" // Kristijan Kolozvari #include "mvlem/SFI_MVLEM.h" // Kristijan Kolozvari #include "mvlem/MVLEM_3D.h" // Kristijan Kolozvari +#include "mvlem/SFI_MVLEM_3D.h" // Kristijan Kolozvari #include "elastomericBearing/ElastomericBearingBoucWen2d.h" #include "elastomericBearing/ElastomericBearingBoucWen3d.h" @@ -811,6 +812,9 @@ FEM_ObjectBrokerAllClasses::getNewElement(int classTag) case ELE_TAG_MVLEM_3D: // Kristijan Kolozvari return new MVLEM_3D(); // Kristijan Kolozvari + case ELE_TAG_SFI_MVLEM_3D: // Kristijan Kolozvari + return new SFI_MVLEM_3D(); // Kristijan Kolozvari + case ELE_TAG_BBarFourNodeQuadUP: return new BBarFourNodeQuadUP(); diff --git a/SRC/classTags.h b/SRC/classTags.h index bad9b2d8e..8f3076979 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -775,6 +775,7 @@ #define ELE_TAG_RockingBC 210 #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_ExternalElement 99990 diff --git a/SRC/element/TclElementCommands.cpp b/SRC/element/TclElementCommands.cpp index 3b3f574d7..e04041658 100644 --- a/SRC/element/TclElementCommands.cpp +++ b/SRC/element/TclElementCommands.cpp @@ -146,6 +146,7 @@ extern void *OPS_VS3D4WuadWithSensitivity(void); extern void *OPS_MVLEM(void); // Kristijan Kolozvari extern void *OPS_SFI_MVLEM(void); // Kristijan Kolozvari 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); extern void *OPS_PFEMElement2DBubble(const ID &info); @@ -770,6 +771,17 @@ TclModelBuilderElementCommand(ClientData clientData, Tcl_Interp *interp, return TCL_ERROR; } + } + else if (strcmp(argv[1], "SFI_MVLEM_3D") == 0) { // Kristijan Kolozvari + + void* theEle = OPS_SFI_MVLEM_3D(); + 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)){ void *theEle = OPS_MultiFP2d(); diff --git a/SRC/element/mvlem/Makefile b/SRC/element/mvlem/Makefile index 22ebfe141..7d9974316 100644 --- a/SRC/element/mvlem/Makefile +++ b/SRC/element/mvlem/Makefile @@ -2,7 +2,8 @@ include ../../../Makefile.def OBJS = MVLEM.o \ SFI_MVLEM.o \ - MVLEM_3D.o + MVLEM_3D.o \ + SFI_MVLEM_3D.o all: $(OBJS) diff --git a/SRC/element/mvlem/SFI_MVLEM_3D.cpp b/SRC/element/mvlem/SFI_MVLEM_3D.cpp new file mode 100644 index 000000000..d9a9a89db --- /dev/null +++ b/SRC/element/mvlem/SFI_MVLEM_3D.cpp @@ -0,0 +1,3133 @@ +// Code written/implemented by: Kristijan Kolozvari (kkolozvari@fullerton.edu) +// Kamiar Kalbasi +// Kutay Orakcal +// John Wallace +// +// User documentation available at: https://kkolozvari.github.io/SFI-MVLEM-3D/ +// +// Created: 03/2021 +// +// Description: The MVLEM-3D model is a three-dimenaional four-node element with 24 DOFs for nonlinear analysis of +// flexure-controlled non-rectangular reinforced concrete walls subjected to multidirectional loading. The model is +// an extension of the two-dimensional, two-node Multiple-Vertical-Line-Element-Model (MVLEM). The baseline MVLEM, +// which is essentially a line element for rectangular walls subjected to in-plane loading, is extended to a +// three-dimensional model formulation by: 1) applying geometric transformation of the element in-plane degrees of +// freedom that convert it into a four-node element formulation and by 2) incorporating linear +// elastic out-of-plane behavior based on the Kirchhoff plate theory. The in-plane and the out-of-plane +// element behaviors are uncoupled in the present model formulation. +// +// Notes: +// Nodes should be assigned in counterclockwise direction. +// 4........3 +// . . +// . . +// . . ^ y +// 1........2 |-> x +// +// Reference: +// K. Kolozvari, K. Kalbasi, K. Orakcal & J. W. Wallace (2021), "Three-dimensional shear-flexure interaction model for analysis of non-planar reinforced concrete walls", Journal of Building Engineering. +// +// Source: /usr/local/cvs/OpenSees/SRC/element/mvlem/SFI_MVLEM_3D.cpp +// +// Rev: 1.0 + +#include +#include + +#include +#include +#include +#include +#include "SFI_MVLEM_3D.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// Read input parameters and build the element +void* OPS_SFI_MVLEM_3D(void) +{ + // Pointer to a uniaxial material that will be returned + Element* theElement = 0; + + int numArgs = OPS_GetNumRemainingInputArgs(); + + // Parse the script for material parameters + if (numArgs < 14) { + opserr << "Want: element SFI_MVLEM_3D eleTag iNode jNode kNode lNode m -thick {Thicknesses} -width {Widths} -mat {Material_tags} <-CoR c> <-ThickMod tMod> <-Poisson Nu> <-Density Dens>\n"; + return 0; + } + + int iData[6]; + double dData[4]; + + // set defaults + dData[0] = 0.4; // c + dData[1] = 0.63; // tMod (equivalent to cracked out-of-plan stiffness of 0.25Ig) + dData[2] = 0.25; // Poisson (concrete) + dData[3] = 0.0; // Density + + int numData = 1; + if (OPS_GetIntInput(&numData, iData) != 0) { + opserr << "WARNING invalid tag for element SFI_MVLEM_3D" << endln; + return 0; + } + + numData = 5; + if (OPS_GetIntInput(&numData, &iData[1]) != 0) { + opserr << "WARNING iNode jNode kNode lNode or m for element SFI_MVLEM_3D" << iData[0] << endln; + return 0; + } + + int m = iData[5]; + const char* str = 0; + + double* theThickness = new double[m]; + double* theWidth = new double[m]; + int* matTags = new int[m]; + + NDMaterial** theMaterials = new NDMaterial * [m]; + + numArgs = OPS_GetNumRemainingInputArgs(); + + while (numArgs > 0) { + //OPS_GetStringCopy(&str); + str = OPS_GetString(); + if (strcmp(str, "-thick") == 0) { + numData = m; + if (OPS_GetDoubleInput(&numData, theThickness) != 0) { + opserr << "Invalid thick parameter for SFI_MVLEM " << iData[0] << endln; + return 0; + } + } + else if (strcmp(str, "-width") == 0) { + numData = m; + if (OPS_GetDoubleInput(&numData, theWidth) != 0) { + opserr << "Invalid width value for SFI_MVLEM " << iData[0] << endln; + return 0; + } + } + else if (strcmp(str, "-mat") == 0) { + numData = m; + if (OPS_GetIntInput(&numData, matTags) != 0) { + opserr << "Invalid mat tags for SFI_MVLEM " << iData[0] << endln; + return 0; + } + for (int i = 0; i < m; i++) { + theMaterials[i] = 0; + theMaterials[i] = OPS_getNDMaterial(matTags[i]); + if (theMaterials[i] == 0) { + opserr << "Invalid material tag " << matTags[i] << " for SFI_MVLEM " << iData[0] << endln; + return 0; + } + } + } + + // optional parameters + else if (strcmp(str, "-CoR") == 0) { + numData = 1; + if (OPS_GetDoubleInput(&numData, &dData[0]) != 0) { + opserr << "Invalid CoR parameter for MVLEM " << iData[0] << endln; + return 0; + } + } + else if (strcmp(str, "-ThickMod") == 0) { + numData = 1; + if (OPS_GetDoubleInput(&numData, &dData[1]) != 0) { + opserr << "Invalid ThickMod parameter for MVLEM " << iData[0] << endln; + return 0; + } + } + else if (strcmp(str, "-Poisson") == 0) { + numData = 1; + if (OPS_GetDoubleInput(&numData, &dData[2]) != 0) { + opserr << "Invalid Poisson parameter for MVLEM " << iData[0] << endln; + return 0; + } + } + else if (strcmp(str, "-Density") == 0) { + numData = 1; + if (OPS_GetDoubleInput(&numData, &dData[3]) != 0) { + opserr << "Invalid Dens parameter for MVLEM " << iData[0] << endln; + return 0; + } + } + numArgs = OPS_GetNumRemainingInputArgs(); + + } + + theElement = new SFI_MVLEM_3D(iData[0], dData[3], + iData[1], iData[2], iData[3], iData[4], + theMaterials, + theThickness, + theWidth, + iData[5], dData[0], dData[2], dData[1]); + + // Cleanup dynamic memory + if (theThickness != 0) + delete[] theThickness; + if (theWidth != 0) + delete[] theWidth; + if (matTags != 0) + delete[] matTags; + + if (theMaterials != 0) + delete[] theMaterials; + + return theElement; +} + +// Typical constructor +SFI_MVLEM_3D::SFI_MVLEM_3D(int tag, + double Dens, + int Nd1, int Nd2, int Nd3, int Nd4, + NDMaterial **materials, + double *thickness, + double *width, + int mm = 0, + double cc = 0.0, + double nn = 0.0, + double tf = 0.0) + + :Element(tag, ELE_TAG_SFI_MVLEM_3D), + density(Dens), + externalNodes(4 + mm), + theNodesX(0), + theNodesALL(0), + theMaterial(0), theLoad(0), + SFI_MVLEM_3DStrainX(0), SFI_MVLEM_3DStrainY(0), SFI_MVLEM_3DStrainXY(0), SFI_MVLEM_3DStrain(0), + x(0), b(0), AcX(0), AcY(0), kx(0), ky(0), Kh(0), Fx(0), Fy(0), Fxy(0), Dx(0), Dy(0), Dxy(0), + SFI_MVLEM_3DK(24 + m, 24 + m), SFI_MVLEM_3DR(24 + m), SFI_MVLEM_3DD(24 + m, 24 + m), SFI_MVLEM_3DM(24 + m, 24 + m), + SFI_MVLEM_3DKlocal(24 + m, 24 + m), SFI_MVLEM_3DDlocal(24 + m, 24 + m), SFI_MVLEM_3DRlocal(24 + m), SFI_MVLEM_3DMlocal(24 + m, 24 + m), + P_24DOF(24), P_24DOF_local(24), + m(mm), c(cc), NUelastic(nn), Tfactor(tf), + T(24 + m, 24 + m), Tt(3, 3), T6(6, 6), + nd1Crds(3), nd2Crds(3), nd3Crds(3), nd4Crds(3), modifiedT(0), t(0) +{ + + TotalMass = 0.0; + NodeMass = 0.0; + h = 0.0; + d = 0.0; + + // Out of Plane parameters + Eave = 0.0; + Tave = 0.0; + + // Imaginary beam properties + Eib = 0.0; + Hib = 0.0; + Iib = 0.0; + Aib = 0.0; + + // Check number of fibers - max is 999 to avoid overlapping in internal node tags + if (m > 999) { + opserr << "WARNING: Number of fibers assigned is " << m << ". Maximum allowed number of fibers is 999!\n"; + exit(-1); + } + + // Fill in the ID containing external node info with node id's + if (externalNodes.Size() != 4 + m) + opserr << "FATAL SFI_MVLEM_3D::SFI_MVLEM_3D() - out of memory, could not create an ID of size 2+m\n"; + + // Assign node tags to external nodes - Node ordering switched on purpose to match the theoretical derivation + externalNodes(0) = Nd1; + externalNodes(1) = Nd2; + externalNodes(3) = Nd3; + externalNodes(2) = Nd4; + + // Set external node pointers to NULL - external nodes + theNodes[0] = 0; + theNodes[1] = 0; + theNodes[2] = 0; + theNodes[3] = 0; + + // Create a internal node tags equal to first to get past OpenSees check + for (int i = 0; i < m; i++) { + externalNodes(i + 4) = Nd1; + } + + // Allocate memory for the m internal nodes + theNodesX = new Node*[m]; + theNodesALL = new Node*[m + 4]; + + // Set NodeX pointers to NULL - m internal nodes + for (int i = 0; i < m; i++) { + theNodesX[i] = 0; + } + + // Set theNodesALL pointers to NULL - m internal nodes + for (int i = 0; i < m + 4; i++) { + theNodesALL[i] = 0; + } + + // Check thickness and width input + if (thickness == 0) { + opserr << "SFI_MVLEM_3D::SFI_MVLEM_3D() - " + << "Null thickness array passed.\n"; + exit(-1); + } + + if (width == 0) { + opserr << "SFI_MVLEM_3D::SFI_MVLEM_3D() - " + << "Null width array passed.\n"; + exit(-1); + } + + // Allocate memory for the thickness and width + // Input parameters + t = new double[m]; + b = new double[m]; + Lw = 0.0; + + for (int i = 0; igetCopy(); + + if (theMaterial[i] == 0) { + opserr << "SFI_MVLEM_3D::SFI_MVLEM_3D() - " + << "Failed to copy ND material.\n"; + exit(-1); + } + } + + // Allocate memory for element arrays + // Area of concrete fibers + AcX = new double[m]; + AcY = new double[m]; + + // Panel stiffness (trial) + kx = new double[m]; + ky = new double[m]; + + // Panel force (trial) + Fx = new double[m]; + Fy = new double[m]; + Fxy = new double[m]; + + // Panel stiffness (trial) + Dx = new double[m]; + Dy = new double[m]; + Dxy = new double[m]; + + // Panel strains + SFI_MVLEM_3DStrainX = new double[m]; + SFI_MVLEM_3DStrainY = new double[m]; + SFI_MVLEM_3DStrainXY = new double[m]; + SFI_MVLEM_3DStrain = new double[3 * m]; + + // Assign zero to element arrays + for (int i = 0; i < m; i++) { + + AcX[i] = 0.0; + AcY[i] = 0.0; + + kx[i] = 0.0; + ky[i] = 0.0; + + Fx[i] = 0.0; + Fy[i] = 0.0; + Fxy[i] = 0.0; + + Dx[i] = 0.0; + Dy[i] = 0.0; + Dxy[i] = 0.0; + + SFI_MVLEM_3DStrainX[i] = 0.0; + SFI_MVLEM_3DStrainY[i] = 0.0; + SFI_MVLEM_3DStrainXY[i] = 0.0; + + SFI_MVLEM_3DStrain[i] = 0.0; + SFI_MVLEM_3DStrain[i + m] = 0.0; + SFI_MVLEM_3DStrain[i + 2 * m] = 0.0; + } + + Kh = 0.0; + + // Revert to start + this->revertToStart(); +} + +// Constructor which should be invoked by an FE_ObjectBroker only +SFI_MVLEM_3D::SFI_MVLEM_3D() + :Element(0, ELE_TAG_SFI_MVLEM_3D), + externalNodes(4 + m), + theNodesX(0), + theNodesALL(0), + theMaterial(0), theLoad(0), + SFI_MVLEM_3DStrainX(0), SFI_MVLEM_3DStrainY(0), SFI_MVLEM_3DStrainXY(0), SFI_MVLEM_3DStrain(0), + x(0), b(0), AcX(0), AcY(0), kx(0), ky(0), Kh(0), Fx(0), Fy(0), Fxy(0), Dx(0), Dy(0), Dxy(0), + SFI_MVLEM_3DK(24 + m, 24 + m), SFI_MVLEM_3DR(24 + m), SFI_MVLEM_3DD(24 + m, 24 + m), SFI_MVLEM_3DM(24 + m, 24 + m), + SFI_MVLEM_3DKlocal(24 + m, 24 + m), SFI_MVLEM_3DDlocal(24 + m, 24 + m), SFI_MVLEM_3DRlocal(24 + m), SFI_MVLEM_3DMlocal(24 + m, 24 + m), + P_24DOF(24), P_24DOF_local(24), + m(m), c(c), NUelastic(NUelastic), Tfactor(Tfactor), + T(24 + m, 24 + m), Tt(3, 3), T6(6, 6), + nd1Crds(3), nd2Crds(3), nd3Crds(3), nd4Crds(3), modifiedT(0), t(0) +{ + if (externalNodes.Size() != 4 + m) + opserr << "FATAL SFI_MVLEM_3D::SFI_MVLEM_3D() - out of memory, could not create an ID of size 2\n"; + + theNodes[0] = 0; + theNodes[1] = 0; + theNodes[2] = 0; + theNodes[3] = 0; + + // Allocate memory for all nodes (internal and external) + theNodesX = new Node*[m]; // internal nodes + theNodesALL = new Node*[m + 4]; // all nodes + + // Set NodeX pointers to zero + for (int i = 0; i < m; i++) + { + theNodesX[i] = 0; + } + + // Set theNodesALL pointers to zero + for (int i = 0; i < m + 4; i++) + { + theNodesALL[i] = 0; + } + +} + +// Destructor - provided to clean up any memory +SFI_MVLEM_3D::~SFI_MVLEM_3D() +{ + // clean up the memory associated with the element, this is + // memory the SFI_MVLEM_3D objects allocates and memory allocated + // by other objects that the SFI_MVLEM_3D object is responsible for + // cleaning up, i.e. the MaterialObject. + + if (theMaterial != 0) { + for (int i = 0; i < m; i++) + if (theMaterial[i] != 0) + delete theMaterial[i]; + delete[] theMaterial; + } + + if (theLoad != 0) + delete theLoad; + if (x != 0) + delete x; + if (b != 0) + delete b; + if (AcX != 0) + delete AcX; + if (AcY != 0) + delete AcY; + if (kx != 0) + delete kx; + if (ky != 0) + delete ky; + if (Fx != 0) + delete Fx; + if (Fy != 0) + delete Fy; + if (Fxy != 0) + delete Fxy; + if (Dx != 0) + delete Dx; + if (Dy != 0) + delete Dy; + if (Dxy != 0) + delete Dxy; + if (SFI_MVLEM_3DStrainX != 0) + delete SFI_MVLEM_3DStrainX; + if (SFI_MVLEM_3DStrainY != 0) + delete SFI_MVLEM_3DStrainY; + if (SFI_MVLEM_3DStrainXY != 0) + delete SFI_MVLEM_3DStrainXY; + if (SFI_MVLEM_3DStrain != 0) + delete SFI_MVLEM_3DStrain; + if (theNodesX != 0) + delete theNodesX; + if (theNodesALL != 0) + delete theNodesALL; + if (modifiedT != 0) + delete modifiedT; + if (t != 0) + delete t; + +} + +// Get number of nodes (external + internal) +int SFI_MVLEM_3D::getNumExternalNodes(void) const +{ + return 4 + m; +} + +// Get node tags +const ID & SFI_MVLEM_3D::getExternalNodes(void) +{ + return externalNodes; +} + +// Get node pointers +Node ** SFI_MVLEM_3D::getNodePtrs(void) +{ + + // Pack external and internal node pointers into one array + for (int i = 0; i < 4; i++) { + theNodesALL[i] = theNodes[i]; + } + + for (int i = 4; i < m + 4; i++) { + theNodesALL[i] = theNodesX[i - 4]; + } + + return theNodesALL; +} + +// Get number of DOFs +int SFI_MVLEM_3D::getNumDOF(void) { + + int NumDOF = 24 + m; // 6 DOFs per external node x 4 external nodes x 1 DOF per m internal nodes + + return NumDOF; +} + +// Set Domain +void SFI_MVLEM_3D::setDomain(Domain *theDomain) +{ + // Check Domain is not null - invoked when object removed from a domain + if (theDomain == 0) + { + return; + } + + // Set node pointers to NULL + theNodes[0] = 0; + theNodes[1] = 0; + theNodes[2] = 0; + theNodes[3] = 0; + + for (int i = 0; i < m; i++) { + theNodesX[i] = 0; + } + + // First ensure external nodes exist in Domain and set the node pointers + int Nd1 = externalNodes(0); + int Nd2 = externalNodes(1); + int Nd3 = externalNodes(2); + int Nd4 = externalNodes(3); + + theNodes[0] = theDomain->getNode(Nd1); + theNodes[1] = theDomain->getNode(Nd2); + theNodes[2] = theDomain->getNode(Nd3); + theNodes[3] = theDomain->getNode(Nd4); + + // Get coordinates of end nodes + nd1Crds = theNodes[0]->getCrds(); + nd2Crds = theNodes[1]->getCrds(); + nd3Crds = theNodes[2]->getCrds(); + nd4Crds = theNodes[3]->getCrds(); + + // Compute coordinate transformation matrix + setTransformationMatrix(); + + // Node coordinates in local coordinate system + Vector nd1CrdL(3); nd1CrdL.Zero(); + Vector nd2CrdL(3); nd2CrdL.Zero(); + Vector nd3CrdL(3); nd3CrdL.Zero(); + Vector nd4CrdL(3); nd4CrdL.Zero(); + + nd1CrdL.addMatrixVector(0.0, Tt, nd1Crds, 1.0); + nd2CrdL.addMatrixVector(0.0, Tt, nd2Crds, 1.0); + nd3CrdL.addMatrixVector(0.0, Tt, nd3Crds, 1.0); + nd4CrdL.addMatrixVector(0.0, Tt, nd4Crds, 1.0); + + // Calculate the element height and perform checks + double h1 = pow(pow(nd3Crds(0) - nd1Crds(0), 2.0) + pow(nd3Crds(1) - nd1Crds(1), 2.0) + pow(nd3Crds(2) - nd1Crds(2), 2.0), 0.5); + double h2 = pow(pow(nd4Crds(0) - nd2Crds(0), 2.0) + pow(nd4Crds(1) - nd2Crds(1), 2.0) + pow(nd4Crds(2) - nd2Crds(2), 2.0), 0.5); + + // Check if element height is zero + if ((h1 == 0.0) || (h2 == 0.0)) { + opserr << "WARNING: One of the element sides is ZERO. Check geometry"; + exit(-1); + } + + // Check if element has constant height + if ((h1 / h2 > 1.01) || (h1 / h2 < 0.99)) { + opserr << "WARNING: Element does not have constant height. Check geometry."; + exit(-1); + } + + // Element height + h = (h1 + h2) / 2.0; + + // Calculate average wall thickness + for (int i = 0; i < m; i++) { + Tave += t[i] * b[i] / Lw; + } + + // Calculate the element width and perform checks + double b1 = pow(pow(nd1Crds(0) - nd2Crds(0), 2.0) + pow(nd1Crds(1) - nd2Crds(1), 2.0) + pow(nd1Crds(2) - nd2Crds(2), 2.0), 0.5); + double b2 = pow(pow(nd4Crds(0) - nd3Crds(0), 2.0) + pow(nd4Crds(1) - nd3Crds(1), 2.0) + pow(nd4Crds(2) - nd3Crds(2), 2.0), 0.5); + + // Check width of element + if ((Lw / b1 > 1.01) || (Lw / b1 < 0.99)) { + opserr << "WARNING: Element nodes coordinates are not matched with fibers width. Check geometry."; + exit(-1); + } + + if ((Lw / b2 > 1.01) || (Lw / b2 < 0.99)) { + opserr << "WARNING: Element nodes coordinates are not matched with fibers width. Check geometry."; + exit(-1); + } + + // Calculate distance of corner nodes from center axis + d = Lw / 2.0; + + // Create a internal node tag + for (int i = 0; i < m; i++) { // Large NEGATIVE integer starting with tag of the element + externalNodes(i + 4) = -(Nd1 * 1000 + i + 1); // Max fibers is 999 to avoid overlap + } + + // Build m internal nodes (NodesX) and add them to the domain + for (int i = 0; i < m; i++) { + + int nodeId_temp = externalNodes(i + 4); // Store node tag temporarily + + // Create coordinates wrt top and bottom element node + double xLoc_temp = nd1CrdL(0) + x[i]; + double yLoc_temp = 0.5 * (nd1CrdL(1) + nd3CrdL(1)); // Mid-height + double zLoc_temp = nd1CrdL(2); + + Vector Dummy_LCcs(3); + Dummy_LCcs(0) = xLoc_temp; + Dummy_LCcs(1) = yLoc_temp; + Dummy_LCcs(2) = zLoc_temp; + + Vector Dummy_GLcs(3); Dummy_GLcs.Zero(); + Dummy_GLcs.addMatrixTransposeVector(0.0, Tt, Dummy_LCcs, 1.0); + + // Create Node and add it to the domain + Node* theNode = 0; + + theNode = new Node(nodeId_temp, 1, Dummy_GLcs(0), Dummy_GLcs(1), Dummy_GLcs(2)); // create internal node with 1 DOF + + if (theNode == 0) { + opserr << "WARNING ran out of memory creating node\n"; + opserr << "node: " << nodeId_temp << " in SFI_MVLEM_3D." << endln; endln; + exit(-1); + } + + if (theDomain->addNode(theNode) == false) { // add internal node to the domain + opserr << "WARNING failed to add node to the domain\n"; + opserr << "node: " << nodeId_temp << " in SFI_MVLEM." << endln; + delete theNode; // otherwise memory leak + exit(-1); + } + } // END create/add internal nodes + + if (theNodes[0] == 0) { + opserr << "WARNING SFI_MVLEM_3D::setDomain() - at SFI_MVLEM_3D " << this->getTag() << " node " << + Nd1 << " does not exist in domain\n"; + return; // Don't go any further - otherwise segemntation fault + } + + if (theNodes[1] == 0) { + opserr << "WARNING SFI_MVLEM_3D::setDomain() - at SFI_MVLEM_3D " << this->getTag() << " node " << + Nd2 << " does not exist in domain\n"; + return; + } + + if (theNodes[2] == 0) { + opserr << "WARNING SFI_MVLEM_3D::setDomain() - at SFI_MVLEM_3D " << this->getTag() << " node " << + Nd3 << " does not exist in domain\n"; + return; // Don't go any further - otherwise segemntation fault + } + if (theNodes[3] == 0) { + opserr << "WARNING SFI_MVLEM_3D::setDomain() - at SFI_MVLEM_3D " << this->getTag() << " node " << + Nd4 << " does not exist in domain\n"; + return; + } + + // Then ensure internal NodesX exist in Domain and set the node pointers + for (int i = 0; igetNode(NdX_temp1); + + if (theNodesX[i] == 0) { + opserr << "WARNING SFI_MVLEM_3D::setDomain() - at SFI_MVLEM_3D " << this->getTag() << " node " << + NdX_temp1 << " does not exist in domain\n"; + return; // Don't go any further - otherwise segemntation fault + } + } + + // Call the DomainComponent class method + this->DomainComponent::setDomain(theDomain); + + // Ensure conected nodes have correct number of dof's + int dofNd1 = theNodes[0]->getNumberDOF(); + int dofNd2 = theNodes[1]->getNumberDOF(); + int dofNd3 = theNodes[2]->getNumberDOF(); + int dofNd4 = theNodes[3]->getNumberDOF(); + + if ((dofNd1 != 6) || (dofNd2 != 6) || (dofNd3 != 6) || (dofNd4 != 6)) { + opserr << "SFI_MVLEM_3D::setDomain(): 6 dof required at all nodes. " << dofNd1 << " provided at node 1, " << dofNd2 << " provided at node 2, " + << dofNd3 << " provided at node 4, " << dofNd4 << " provided at node 3"; + } + + for (int i = 0; i < m; i++) { + int dofNdXi = theNodesX[i]->getNumberDOF(); + if (dofNdXi != 1) // 1 DOF at internal nodes + { + opserr << "SFI_MVLEM_3D::setDomain(): 1 dof required at internal nodes, " << dofNdXi << " provided\n"; + } + } + + // Calculate concrete areas in X and Y directions + double A = 0.0; + for (int i = 0; i < m; i++) { + AcX[i] = h * t[i]; + AcY[i] = b[i] * t[i]; + + A += AcY[i]; + } + + // Determine the nodal mass for lumped mass approach + A = 0; + for (int i = 0; i < m; i++) { + A += b[i] * t[i]; + } + + NodeMass = density * A * h / 4.0; + + // Get Concrete Young's Modulus + theResponses = new Response *[1]; + if (theResponses == 0) { + opserr << " SFI_MVLEM_3D::SFI_MVLEM_3D - failed allocate responses array\n"; + exit(-1); + } + + OPS_Stream *theDummyStream = new DummyStream(); + const char **argv = new const char *[1]; + + argv[0] = "getInputParameters"; // to get input parameters from concrete material + for (int i = 0; i < m; i++) + { + theResponses[0] = theMaterial[i]->setResponse(argv, 1, *theDummyStream); + + if (theResponses[0] == 0) { + opserr << " SFI_MVLEM_3D::SFI_MVLEM_3D - failed to get input parameters for FSAM material with tag: " << this->getTag() << "\n"; + exit(-1); + } + + // Get FSAM material input variables + theResponses[0]->getResponse(); + Information &theInfoInput = theResponses[0]->getInformation(); + const Vector InputNDMat = theInfoInput.getData(); + + Vector InputNDMaterial(InputNDMat.Size()); + + for (int j = 0; j < InputNDMat.Size(); j++) + InputNDMaterial[j] = InputNDMat[j]; + + // Calculate out-of-plane modulus of elasticity (average modulus) + Eave += AcY[i] * InputNDMaterial[9] / A; + + } + + // Internal beam parameters + Eib = Eave; + Hib = h; + Aib = Tave * Hib; + Iib = 0.5 * (Tave * Hib * Hib * Hib / 12.0); + + Tave *= Tfactor; // multiply Tave with the modification factor + + // Create a vector to hop applied loads - NOT used in the current model formulation (no element loads) + if (theLoad == 0) + theLoad = new Vector(24 + m); + if (theLoad == 0) { + opserr << "SFI_MVLEM_3D::setDomain() - element: " << this->getTag() + << " out of memory creating vector of size: " << 24 + m << endln; + return; + } + + // Calculate constant terms of stiffness matrix + K1 = -(Eave * (Tave * Tave * Tave) * (10.0 * (h * h * h * h) + 10.0 * (Lw * Lw * Lw * Lw) + 7.0 * (h * h) * (Lw * Lw) - 2.0 * (h * h) * NUelastic * (Lw * Lw))) / (30.0 * (h * h * h) * (Lw * Lw * Lw) * ((NUelastic * NUelastic) - 1.0)); + K2 = (Eave * (Tave * Tave * Tave) * (4.0 * (h * h) * NUelastic + (h * h) + 10.0 * (Lw * Lw))) / (60.0 * (h * h) * Lw * ((NUelastic * NUelastic) - 1.0)); + K3 = (Eave * (Tave * Tave * Tave) * (4.0 * NUelastic * (Lw * Lw) + 10.0 * (h * h) + (Lw * Lw))) / (60.0 * h * (Lw * Lw) * ((NUelastic * NUelastic) - 1.0)); + K4 = (Eave * (Tave * Tave * Tave) * (10.0 * (h * h * h * h) - 5.0 * (Lw * Lw * Lw * Lw) + 7.0 * (h * h) * (Lw * Lw) - 2.0 * (h * h) * NUelastic * (Lw * Lw))) / (30.0 * (h * h * h) * (Lw * Lw * Lw) * ((NUelastic * NUelastic) - 1.0)); + K5 = (Eave * (Tave * Tave * Tave) * (4.0 * (h * h) * NUelastic + (h * h) - 5.0 * (Lw * Lw))) / (60.0 * (h * h) * Lw * ((NUelastic * NUelastic) - 1.0)); + K6 = (Eave * (Tave * Tave * Tave) * (10.0 * (h * h) - NUelastic * (Lw * Lw) + (Lw * Lw))) / (60.0 * h * (Lw * Lw) * ((NUelastic * NUelastic) - 1.0)); + K7 = -(Eave * (Tave * Tave * Tave) * (5.0 * (h * h * h * h) - 10.0 * (Lw * Lw * Lw * Lw) - 7.0 * (h * h) * (Lw * Lw) + 2.0 * (h * h) * NUelastic * (Lw * Lw))) / (30.0 * (h * h * h) * (Lw * Lw * Lw) * ((NUelastic * NUelastic) - 1.0)); + K8 = (Eave * (Tave * Tave * Tave) * ((h * h) - (h * h) * NUelastic + 10.0 * (Lw * Lw))) / (60.0 * (h * h) * Lw * ((NUelastic * NUelastic) - 1.0)); + K9 = (Eave * (Tave * Tave * Tave) * (4.0 * NUelastic * (Lw * Lw) - 5.0 * (h * h) + (Lw * Lw))) / (60.0 * h * (Lw * Lw) * ((NUelastic * NUelastic) - 1.0)); + K10 = (Eave * (Tave * Tave * Tave) * (5.0 * (h * h * h * h) + 5.0 * (Lw * Lw * Lw * Lw) - 7.0 * (h * h) * (Lw * Lw) + 2.0 * (h * h) * NUelastic * (Lw * Lw))) / (30.0 * (h * h * h) * (Lw * Lw * Lw) * ((NUelastic * NUelastic) - 1.0)); + K11 = (Eave * (Tave * Tave * Tave) * ((h * h) * NUelastic - (h * h) + 5.0 * (Lw * Lw))) / (60.0 * (h * h) * Lw * ((NUelastic * NUelastic) - 1.0)); + K12 = (Eave * (Tave * Tave * Tave) * (NUelastic * (Lw * Lw) + 5.0 * (h * h) - (Lw * Lw))) / (60.0 * h * (Lw * Lw) * ((NUelastic * NUelastic) - 1.0)); + K13 = -(Eave * (Tave * Tave * Tave) * ((h * h) - (h * h) * NUelastic + 5.0 * (Lw * Lw))) / (45.0 * h * Lw * ((NUelastic * NUelastic) - 1.0)); + K14 = (Eave * NUelastic * (Tave * Tave * Tave)) / (12.0 * (NUelastic * NUelastic) - 12.0); + K15 = -(Eave * (Tave * Tave * Tave) * (2.0 * (h * h) * NUelastic - 2.0 * (h * h) + 5.0 * (Lw * Lw))) / (90.0 * h * Lw * ((NUelastic * NUelastic) - 1.0)); + K16 = -(Eave * (Tave * Tave * Tave) * ((h * h) * NUelastic - (h * h) + 10.0 * (Lw * Lw))) / (180.0 * h * Lw * ((NUelastic * NUelastic) - 1.0)); + K17 = -(Eave * (Tave * Tave * Tave) * ((h * h) - (h * h) * NUelastic + 5.0 * (Lw * Lw))) / (180.0 * h * Lw * ((NUelastic * NUelastic) - 1.0)); + K18 = (Eave * (Tave * Tave * Tave) * Lw * (NUelastic - 1.0)) / (45.0 * h * ((NUelastic * NUelastic) - 1.0)) - (Eave * h * (Tave * Tave * Tave)) / (9.0 * Lw * ((NUelastic * NUelastic) - 1.0)); + K19 = -(Eave * h * (Tave * Tave * Tave)) / (18.0 * Lw * ((NUelastic * NUelastic) - 1.0)) - (Eave * (Tave * Tave * Tave) * Lw * (NUelastic - 1.0)) / (180.0 * h * ((NUelastic * NUelastic) - 1.0)); + K20 = -(Eave * h * (Tave * Tave * Tave)) / (18.0 * Lw * ((NUelastic * NUelastic) - 1.0)) - (Eave * (Tave * Tave * Tave) * Lw * (2.0 * NUelastic - 2.0)) / (90.0 * h * ((NUelastic * NUelastic) - 1.0)); + K21 = (Eave * (Tave * Tave * Tave) * Lw * (NUelastic - 1.0)) / (180.0 * h * ((NUelastic * NUelastic) - 1.0)) - (Eave * h * (Tave * Tave * Tave)) / (36.0 * Lw * ((NUelastic * NUelastic) - 1.0)); + K22 = -(Eave * (Tave * Tave * Tave) * (5.0 * (h * h) - NUelastic * (Lw * Lw) + (Lw * Lw))) / (45.0 * h * Lw * ((NUelastic * NUelastic) - 1.0)); + +} + +// Commit state of the materials +int SFI_MVLEM_3D::commitState() +{ + int errCode = 0; + + // Commit material models + for (int i = 0; i < m; i++) { + errCode += theMaterial[i]->commitState(); + } + + return errCode; +} + +// Revert to last commited state (if convergence is not achieved) +int SFI_MVLEM_3D::revertToLastCommit() +{ + int errCode = 0; + + // Revert material models + for (int i = 0; i < m; i++) { + errCode += theMaterial[i]->revertToLastCommit(); + } + + return errCode; +} + +// Revert to start +int SFI_MVLEM_3D::revertToStart() +{ + int errCode = 0; + + // Revert material models + for (int i = 0; i < m; i++) + errCode += theMaterial[i]->revertToStart(); + + return errCode; + +} + +// Update state +int SFI_MVLEM_3D::update() +{ + // Get the current strain given trial displacements at nodes + //SFI_MVLEM_3DStrain = this->computeCurrentStrain(); + this->computeCurrentStrain(); + + // Set the strain in the materials + int errCode = 0; + + for (int i = 0; i < m; i++) { + + Vector strain(3); + + strain(0) = SFI_MVLEM_3DStrain[i]; + strain(1) = SFI_MVLEM_3DStrain[i + m]; + strain(2) = SFI_MVLEM_3DStrain[i + 2 * m]; + + // Set trial response for material models + errCode += theMaterial[i]->setTrialStrain(strain); + + } + + return errCode; +} + +// Get current strains at RC panels (macro-fibers) +double *SFI_MVLEM_3D::computeCurrentStrain(void) +{ + + const Vector &disp1 = theNodes[0]->getTrialDisp(); + const Vector &disp2 = theNodes[1]->getTrialDisp(); + const Vector &disp3 = theNodes[2]->getTrialDisp(); + const Vector &disp4 = theNodes[3]->getTrialDisp(); + + // obtain displacements in X direction from the internal nodes + for (int i = 0; i < m; i++) { + const Vector &dispXi = theNodesX[i]->getTrialDisp(); // 1 DOF at theNodesX - Vector of size 1 + Dx[i] = dispXi(0); // get displacements in X direction from the nodes + } + + Vector dispG(24 + m); // Vector of total 24+m displacemets in global coordinates + dispG.Zero(); + Vector dispL(24 + m); // Vector of total 24+m displacemets in local coordinates + dispL.Zero(); + Vector dispL_inPlan2N(6); // in-plane displacements of equlivalent 2D, 2N SFI model + dispL_inPlan2N.Zero(); + + // store nodal displacemnts in global vs + for (int i = 0; i < 6; i++) { + dispG(i) = disp1(i); + dispG(i + 6) = disp2(i); + dispG(i + 12) = disp3(i); + dispG(i + 18) = disp4(i); + } + + for (int i = 0; i < m; ++i) { + dispG(i + 24) = Dx[i]; + } + + // tranform nodal displacements from global to local cs + dispL.addMatrixVector(0.0, T, dispG, 1.0); + + dispL_inPlan2N(0) = dispL(0) / 2.0 + dispL(6) / 2.0; + dispL_inPlan2N(1) = dispL(1) / 2.0 + dispL(7) / 2.0; + dispL_inPlan2N(2) = dispL(5) / (2.0 * (d*d) + 2.0) + dispL(11) / (2.0 * (d*d) + 2.0) - (dispL(1)*d) / (2.0 * (d*d) + 2.0) + (dispL(7)*d) / (2.0 * (d*d) + 2.0); + dispL_inPlan2N(3) = dispL(12) / 2.0 + dispL(18) / 2.0; + dispL_inPlan2N(4) = dispL(13) / 2.0 + dispL(19) / 2.0; + dispL_inPlan2N(5) = dispL(17) / (2.0 * (d*d) + 2.0) + dispL(23) / (2.0 * (d*d) + 2.0) - (dispL(13)*d) / (2.0 * (d*d) + 2.0) + (dispL(19)*d) / (2.0 * (d*d) + 2.0); + + // Deformations at each RC panel (macro-fiber) - MVLEM formulation + for (int i = 0; i < m; i++) { + Dy[i] = -dispL_inPlan2N(1) - x[i] * dispL_inPlan2N(2) + dispL_inPlan2N(4) + x[i] * dispL_inPlan2N(5); + Dxy[i] = dispL_inPlan2N(0) - dispL_inPlan2N(3) - c * h*dispL_inPlan2N(2) - (1.0 - c)*h*dispL_inPlan2N(5); + } + + Dsh = -Dxy[0]; // Store shear deformations for the recorder + + // Strains at each RC panel (macro-fiber) + for (int i = 0; i < m; i++) { + SFI_MVLEM_3DStrainX[i] = Dx[i] / b[i]; + SFI_MVLEM_3DStrainY[i] = Dy[i] / h; + SFI_MVLEM_3DStrainXY[i] = -Dxy[i] / h; + } + + // Store strains into a single vector + for (int i = 0; i < m; i++) { + SFI_MVLEM_3DStrain[i] = SFI_MVLEM_3DStrainX[i]; + SFI_MVLEM_3DStrain[i + m] = SFI_MVLEM_3DStrainY[i]; + SFI_MVLEM_3DStrain[i + 2 * m] = SFI_MVLEM_3DStrainXY[i]; + } + + // Return strain vector + return SFI_MVLEM_3DStrain; + +} + +// Get the element intial element tangent matrix +const Matrix & SFI_MVLEM_3D::getInitialStiff(void) +{ + + SFI_MVLEM_3DK.Zero(); // Global stiffness matrix + SFI_MVLEM_3DKlocal.Zero(); // Local stiffness matrix + + Kh = 0.0; + + for (int i = 0; i < m; i++) + { + // Get material initial tangent + const Matrix &D = theMaterial[i]->getInitialTangent(); + + double D00 = D(0, 0); double D01 = D(0, 1); double D02 = D(0, 2); + double D10 = D(1, 0); double D11 = D(1, 1); double D12 = D(1, 2); + double D20 = D(2, 0); double D21 = D(2, 1); double D22 = D(2, 2); + + kx[i] = D00 * h*t[i] / b[i]; + ky[i] = D11 * b[i] * t[i] / h; + Kh += D22 * b[i] * t[i] / h; + + } + + // Build the initial stiffness matrix + double Kv = 0.0; double Km = 0.0; double e = 0.0; // double ex = 0.0; + + for (int i = 0; igetTangent(); + + double D00 = D(0, 0); double D01 = D(0, 1); double D02 = D(0, 2); + double D10 = D(1, 0); double D11 = D(1, 1); double D12 = D(1, 2); + double D20 = D(2, 0); double D21 = D(2, 1); double D22 = D(2, 2); + + kx[i] = D00 * h*t[i] / b[i]; + ky[i] = D11 * b[i] * t[i] / h; + Kh += D22 * b[i] * t[i] / h; + + } + + // Build the tangent stiffness matrix + double Kv = 0.0; double Km = 0.0; double e = 0.0; // double ex = 0.0; + + for (int i = 0; iElement::getDamp(); + + // Return element damping matrix + return SFI_MVLEM_3DD; +} + +// N/A to this model - no element loads +void SFI_MVLEM_3D::zeroLoad(void) +{ + // does nothing - no elemental loads +} + +// N/A to this model - no element loads +int SFI_MVLEM_3D::addLoad(ElementalLoad *theLoad, double loadFactor) +{ + return 0; +} + + +int SFI_MVLEM_3D::addInertiaLoadToUnbalance(const Vector &accel) +{ + if (density == 0.0) + return 0; + + // Get R * accel from the nodes + const Vector& Raccel1 = theNodes[0]->getRV(accel); + const Vector& Raccel2 = theNodes[1]->getRV(accel); + const Vector& Raccel3 = theNodes[2]->getRV(accel); + const Vector& Raccel4 = theNodes[3]->getRV(accel); + + if (6 != Raccel1.Size() || 6 != Raccel2.Size() || 6 != Raccel3.Size() || 6 != Raccel4.Size()) { + opserr << "FourNodeQuad::addInertiaLoadToUnbalance matrix and vector sizes are incompatible\n"; + return -1; + } + + Vector RaccelG(24); + RaccelG.Zero(); + Vector RaccelL(24); + RaccelL.Zero(); + + // Assign nodal accelerations in global cs into a vector + for (int i = 0; i < 6; i++) { + RaccelG(i) = Raccel1(i); + RaccelG(i + 6) = Raccel2(i); + RaccelG(i + 12) = Raccel3(i); + RaccelG(i + 18) = Raccel4(i); + } + + // Tranform accelerations from global to local cs + RaccelL.addMatrixVector(0.0, T, RaccelG, 1.0); + + // Compute mass matrix + this->getMass(); + + // Want to add ( - fact * M R * accel ) to unbalance + // Take advantage of lumped mass matrix + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + SFI_MVLEM_3DRlocal(6 * i + j) += - SFI_MVLEM_3DMlocal(6 * i + j, 6 * i + j) * RaccelL(6 * i + j); + } + } + + // Transform forces from local to global cs + SFI_MVLEM_3DR.addMatrixTransposeVector(1.0, T, SFI_MVLEM_3DRlocal, 1.0); + + return 0; +} + +// Get element force vector +const Vector & SFI_MVLEM_3D::getResistingForce() +{ + + SFI_MVLEM_3DR.Zero(); + SFI_MVLEM_3DRlocal.Zero(); + + // Get Trial Displacements + const Vector &disp1 = theNodes[0]->getTrialDisp(); + const Vector &disp2 = theNodes[1]->getTrialDisp(); + const Vector &disp3 = theNodes[2]->getTrialDisp(); + const Vector &disp4 = theNodes[3]->getTrialDisp(); + + Vector dispG(24 + m); // Vector of total 24+m displacemets in global coordinates + dispG.Zero(); + Vector dispL(24 + m); // Vector of total 24+m displacemets in local coordinates + dispL.Zero(); // 2020 + + // Assigning all displacements in global CS into one vector + for (int i = 0; i < 6; i++) { + dispG(i) = disp1(i); + dispG(i + 6) = disp2(i); + dispG(i + 12) = disp3(i); + dispG(i + 18) = disp4(i); + } + + // Convert nodal displacements from global to local cs + dispL.addMatrixVector(0.0, T, dispG, 1.0); + + // In-plane forces from 2-node 6DOF MVLEM formulation + double R1 = 0.0; + double R2 = 0.0; + double R3 = 0.0; + double R4 = 0.0; + double R5 = 0.0; + double R6 = 0.0; + + // Get the current force matrix from panel stresses + for (int i = 0; i < m; i++) + { + // Get the material stress + const Vector &Stress = theMaterial[i]->getStress(); + + double fx = Stress(0); + double fy = Stress(1); + double tauxy = Stress(2); + + Fx[i] = fx * AcX[i]; + Fy[i] = fy * AcY[i]; + Fxy[i] = tauxy * AcY[i]; + + } + + // Build force vector + double Fh = 0.0; // Force in horizontal spring (at location c*h) + double Fysum = 0.0; // Sum of vertical forces + + for (int i = 0; i < m; i++) + { + Fh += -1.0*Fxy[i]; + Fysum += Fy[i]; + SFI_MVLEM_3DRlocal[24 + i] = Fx[i]; // Force on internal (dummy) DOFs + } + + R1 = Fh; + R2 = -Fysum; + R3 = -Fh*c*h; + R4 = -Fh; + R5 = Fysum; + R6 = -Fh*(1.0 - c)*h; + + for (int i = 0; igetResistingForce(); + + // Add the damping forces if rayleigh damping + if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + SFI_MVLEM_3DR += this->getRayleighDampingForces(); + + return SFI_MVLEM_3DR; + } + + // Get nodal accelerations in global cs + const Vector& accel1 = theNodes[0]->getTrialAccel(); + const Vector& accel2 = theNodes[1]->getTrialAccel(); + const Vector& accel3 = theNodes[2]->getTrialAccel(); + const Vector& accel4 = theNodes[3]->getTrialAccel(); + + Vector accelG(24); + accelG.Zero(); + Vector accelL(24); + accelL.Zero(); + + // Assign nodal accelerations in global cs into a vector + for (int i = 0; i < 6; i++) { + accelG(i) = accel1(i); + accelG(i + 6) = accel2(i); + accelG(i + 12) = accel3(i); + accelG(i + 18) = accel4(i); + } + + // Tranform accelerations from global to local cs + accelL.addMatrixVector(0.0, T, accelG, 1.0); + + // Compute the current resisting force + this->getResistingForce(); + + // Compute the mass matrix + this->getMass(); + + // Add inertia forces to force vector in local cs + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + SFI_MVLEM_3DRlocal(6 * i + j) += SFI_MVLEM_3DMlocal(6 * i + j, 6 * i + j) * accelL(6 * i + j); + } + } + + // Transform forces from local to global cs + SFI_MVLEM_3DR.addMatrixTransposeVector(1.0, T, SFI_MVLEM_3DRlocal, 1.0); + + // Add the damping forces if rayleigh damping + if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + SFI_MVLEM_3DR += this->getRayleighDampingForces(); + + return SFI_MVLEM_3DR; +} + +// Send Self +int SFI_MVLEM_3D::sendSelf(int commitTag, Channel &theChannel) +{ + int res; + int dataTag = this->getDbTag(); + + static Vector data(6); + + data(0) = this->getTag(); + data(1) = density; + data(2) = m; + data(3) = c; + data(4) = NUelastic; + data(5) = Tfactor; + + // SFI_MVLEM_3D then sends the tags of it's nodes + res = theChannel.sendID(dataTag, commitTag, externalNodes); + if (res < 0) { + opserr << "WARNING SFI_MVLEM_3D::sendSelf() - failed to send ID\n"; + return -2; + } + + // Send the material class tags + ID matClassTags(m); + for (int i = 0; i < m; i++) + matClassTags(i) = theMaterial[i]->getClassTag(); + res = theChannel.sendID(0, commitTag, matClassTags); + + // Send the material models + for (int i = 0; i < m; i++) + theMaterial[i]->sendSelf(commitTag, theChannel); + + return 0; +} + +// Receive Self +int SFI_MVLEM_3D::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +{ + int res; + int dataTag = this->getDbTag(); + + // SFI_MVLEM_3D creates a Vector, receives the Vector and then sets the + // internal data with the data in the Vector + // delete dynamic memory + if (theMaterial != 0) { + for (int i = 0; i < m; i++) + if (theMaterial[i] != 0) + delete theMaterial[i]; + delete[] theMaterial; + } + + Vector data(6); + res = theChannel.recvVector(dataTag, commitTag, data); + if (res < 0) { + opserr << "WARNING SFI_MVLEM_3D::recvSelf() - failed to receive Vector\n"; + return -1; + } + + this->setTag((int)data(0)); + density = data(1); + m = data(2); + c = data(3); + NUelastic = data(4); + Tfactor = data(5); + + // SFI_MVLEM_3D now receives the tags of it's four external nodes + res = theChannel.recvID(dataTag, commitTag, externalNodes); + if (res < 0) { + opserr << "WARNING SFI_MVLEM_3D::recvSelf() - failed to receive ID\n"; + return -2; + } + + // Receive the material class tags + ID matClassTags(m); + res = theChannel.recvID(0, commitTag, matClassTags); + + // Allocate memory for the uniaxial materials + theMaterial = new NDMaterial*[m]; + if (theMaterial == 0) { + opserr << "SFI_MVLEM_3D::recvSelf() - " + << "failed to allocate pointers for uniaxial materials.\n"; + return -2; + } + + // Receive the material models + for (int i = 0; i < m; i++) { + theMaterial[i] = theBroker.getNewNDMaterial(matClassTags(i)); + if (theMaterial[i] == 0) { + opserr << "SFI_MVLEM_3D::recvSelf() - " + << "failed to get blank uniaxial material.\n"; + return -3; + } + theMaterial[i]->recvSelf(commitTag, theChannel, theBroker); + } + + return 0; +} + +// Display model +int SFI_MVLEM_3D::displaySelf(Renderer& theViewer, int displayMode, float fact, const char** modes, int numMode) +{ + // First get the end points of the beam based on + // the display factor (a measure of the distorted image) + // get location of nodes + + static Vector Gv1(3); + static Vector Gv2(3); + static Vector Gv3(3); + static Vector Gv4(3); + Gv1.Zero(); + Gv2.Zero(); + Gv3.Zero(); + Gv4.Zero(); + + // scalse the up based on thedisplay factor + if (displayMode >= 0) { + + const Vector &end1Disp = theNodes[0]->getDisp(); + const Vector &end2Disp = theNodes[1]->getDisp(); + const Vector &end3Disp = theNodes[2]->getDisp(); + const Vector &end4Disp = theNodes[3]->getDisp(); + + for (int i = 0; i < 3; i++) { // loop over coordinates (3 for 3D elements) + + // add displacement (multiplied with the displacement facotr) to the original node location to obtain current node location + Gv1(i) = nd1Crds(i) + end1Disp(i)*fact; + Gv2(i) = nd2Crds(i) + end2Disp(i)*fact; + Gv3(i) = nd3Crds(i) + end3Disp(i)*fact; + Gv4(i) = nd4Crds(i) + end4Disp(i)*fact; + + } + + } + else { + + int mode = displayMode * -1; + + const Matrix &eigen1 = theNodes[0]->getEigenvectors(); + const Matrix &eigen2 = theNodes[1]->getEigenvectors(); + const Matrix &eigen3 = theNodes[2]->getEigenvectors(); + const Matrix &eigen4 = theNodes[3]->getEigenvectors(); + + if (eigen1.noCols() >= mode) { + + for (int i = 0; i < 3; i++) { + + Gv1(i) = nd1Crds(i) + eigen1(i, mode - 1)*fact; + Gv2(i) = nd2Crds(i) + eigen2(i, mode - 1)*fact; + Gv3(i) = nd3Crds(i) + eigen3(i, mode - 1)*fact; + Gv4(i) = nd4Crds(i) + eigen4(i, mode - 1)*fact; + + } + + } + else { + + for (int i = 0; i < 3; i++) { + + Gv1(i) = nd1Crds(i); + Gv2(i) = nd2Crds(i); + Gv3(i) = nd3Crds(i); + Gv4(i) = nd4Crds(i); + + } + } + } + + int error = 0; + + Vector RGB(3); // setiing up the colors + RGB(0) = 0.0; + RGB(1) = 1.0; + RGB(2) = 1.0; + + // Add 2 vectors for top and bottom middle nodes + Vector Gv1_(3); // Centrline node at the bottom + Vector Gv2_(3); // Cetnrline node at the top + Gv1_.Zero(); + Gv2_.Zero(); + + // Calculate x, y and z coordinates of V1_1 and v1_2 based on x,y,z coordinates + Gv1_(0) = 0.5 * (Gv1(0) + Gv2(0)); + Gv1_(1) = 0.5 * (Gv1(1) + Gv2(1)); + Gv1_(2) = 0.5 * (Gv1(2) + Gv2(2)); + + Gv2_(0) = 0.5 * (Gv3(0) + Gv4(0)); + Gv2_(1) = 0.5 * (Gv3(1) + Gv4(1)); + Gv2_(2) = 0.5 * (Gv3(2) + Gv4(2)); + + Vector Lv1_(3); // Centrline node at the bottom + Vector Lv2_(3); // Cetnrline node at the top + Lv1_.Zero(); + Lv2_.Zero(); + Lv1_.addMatrixVector(0.0, Tt, Gv1_, 1.0); + Lv2_.addMatrixVector(0.0, Tt, Gv2_, 1.0); + + // Displaying Fibers + for (int panel = 0; panel < m; panel++) // loop over m panels + { + + Matrix NodePLotCrds(m, 13); // (panel id, x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4) + + // First set the quantity to be displayed at the nodes; + // if displayMode is 1 through 3 we will plot material stresses otherwise 0.0 + static Vector values(1); // values of epsX to be plotted + + values(0) = 0.0; + + if (displayMode < 4 && displayMode > 0) { + const Vector &stress = theMaterial[panel]->getStrain(); + values(0) = stress(displayMode - 1); + } + + // Determine the deformation - rotation - other is taken from v1, v2 + const Vector &end1Disp4G = theNodes[0]->getDisp(); + const Vector &end2Disp4G = theNodes[1]->getDisp(); + const Vector &end3Disp4G = theNodes[2]->getDisp(); + const Vector &end4Disp4G = theNodes[3]->getDisp(); + + static Vector end1Disp4(6); end1Disp4.Zero(); + static Vector end2Disp4(6); end2Disp4.Zero(); + static Vector end3Disp4(6); end3Disp4.Zero(); + static Vector end4Disp4(6); end4Disp4.Zero(); + + end1Disp4.addMatrixVector(0.0, T6, end1Disp4G, 1.0); + end2Disp4.addMatrixVector(0.0, T6, end2Disp4G, 1.0); + end3Disp4.addMatrixVector(0.0, T6, end3Disp4G, 1.0); + end4Disp4.addMatrixVector(0.0, T6, end4Disp4G, 1.0); + + static Vector end1Disp(6); + static Vector end2Disp(6); + end1Disp.Zero(); + end2Disp.Zero(); + + for (int i = 0; i < 4; i++) { + end1Disp(i) = 0.5 * (end1Disp4(i) + end2Disp4(i)); + end2Disp(i) = 0.5 * (end3Disp4(i) + end4Disp4(i)); + } + end1Disp(4) = end1Disp4(4) / (2.0 * (d*d) + 2.0) + end2Disp4(4) / (2.0 * (d*d) + 2.0) + (end1Disp4(2)*d) / (2.0 * (d*d) + 2.0) - (end2Disp4(2)*d) / (2.0 * (d*d) + 2.0); + end1Disp(5) = end1Disp4(5) / (2.0 * (d*d) + 2.0) + end2Disp4(5) / (2.0 * (d*d) + 2.0) - (end1Disp4(1)*d) / (2.0 * (d*d) + 2.0) + (end2Disp4(1)*d) / (2.0 * (d*d) + 2.0); + + end2Disp(4) = end3Disp4(4) / (2.0 * (d*d) + 2.0) + end4Disp4(4) / (2.0 * (d*d) + 2.0) + (end3Disp4(2)*d) / (2.0 * (d*d) + 2.0) - (end4Disp4(2)*d) / (2.0 * (d*d) + 2.0); + end2Disp(5) = end3Disp4(5) / (2.0 * (d*d) + 2.0) + end4Disp4(5) / (2.0 * (d*d) + 2.0) - (end3Disp4(1)*d) / (2.0 * (d*d) + 2.0) + (end4Disp4(1)*d) / (2.0 * (d*d) + 2.0); + + // Fiber nodes + NodePLotCrds(panel, 0) = panel + 1; // panel id + + Vector LocCoord(3); LocCoord.Zero(); + Vector GlCoord(3); GlCoord.Zero(); + // Local node 1 - bottom left + LocCoord(0) = Lv1_(0) + x[panel] - b[panel] / 2.0; // x + LocCoord(1) = Lv1_(1) + (x[panel] - b[panel] / 2.0)*end1Disp(5)*fact; // y + LocCoord(2) = Lv1_(2) - (x[panel] - b[panel] / 2.0)*end1Disp(4)*fact; // z + GlCoord.addMatrixTransposeVector(0.0, Tt, LocCoord, 1.0); + NodePLotCrds(panel, 1) = GlCoord(0); + NodePLotCrds(panel, 2) = GlCoord(1); + NodePLotCrds(panel, 3) = GlCoord(2); + LocCoord.Zero(); + GlCoord.Zero(); + // Local node 2 - bottom right + LocCoord(0) = Lv1_(0) + x[panel] + b[panel] / 2.0; // x + LocCoord(1) = Lv1_(1) + (x[panel] + b[panel] / 2.0)*end1Disp(5)*fact; // y + LocCoord(2) = Lv1_(2) - (x[panel] + b[panel] / 2.0)*end1Disp(4)*fact; // z + GlCoord.addMatrixTransposeVector(0.0, Tt, LocCoord, 1.0); + NodePLotCrds(panel, 4) = GlCoord(0); + NodePLotCrds(panel, 5) = GlCoord(1); + NodePLotCrds(panel, 6) = GlCoord(2); + LocCoord.Zero(); + GlCoord.Zero(); + // Local node 3 - top left + LocCoord(0) = Lv2_(0) + x[panel] + b[panel] / 2.0; // x + LocCoord(1) = Lv2_(1) + (x[panel] + b[panel] / 2.0)*end2Disp(5)*fact; // y + LocCoord(2) = Lv2_(2) - (x[panel] + b[panel] / 2.0)*end2Disp(4)*fact; // z + GlCoord.addMatrixTransposeVector(0.0, Tt, LocCoord, 1.0); + NodePLotCrds(panel, 7) = GlCoord(0); + NodePLotCrds(panel, 8) = GlCoord(1); + NodePLotCrds(panel, 9) = GlCoord(2); + LocCoord.Zero(); + GlCoord.Zero(); + // Local node 4 - top rigth + LocCoord(0) = Lv2_(0) + x[panel] - b[panel] / 2.0; // x + LocCoord(1) = Lv2_(1) + (x[panel] - b[panel] / 2.0)*end2Disp(5)*fact; // y + LocCoord(2) = Lv2_(2) - (x[panel] - b[panel] / 2.0)*end2Disp(4)*fact; // z + GlCoord.addMatrixTransposeVector(0.0, Tt, LocCoord, 1.0); + NodePLotCrds(panel, 10) = GlCoord(0); + NodePLotCrds(panel, 11) = GlCoord(1); + NodePLotCrds(panel, 12) = GlCoord(2); + + Matrix coords(4, 3); // Temporary coordinates for plotting + + coords(0, 0) = NodePLotCrds(panel, 1); // node 1 x + coords(1, 0) = NodePLotCrds(panel, 4); // node 2 x + coords(2, 0) = NodePLotCrds(panel, 7); // node 3 x + coords(3, 0) = NodePLotCrds(panel, 10);// node 4 x + + coords(0, 1) = NodePLotCrds(panel, 2); // node 1 y + coords(1, 1) = NodePLotCrds(panel, 5); // node 2 y + coords(2, 1) = NodePLotCrds(panel, 8); // node 3 y + coords(3, 1) = NodePLotCrds(panel, 11); // node 4 y + + coords(0, 2) = NodePLotCrds(panel, 3); // node 1 z + coords(1, 2) = NodePLotCrds(panel, 6); // node 2 z + coords(2, 2) = NodePLotCrds(panel, 9); // node 3 z + coords(3, 2) = NodePLotCrds(panel, 12); // node 4 z + + error += theViewer.drawPolygon(coords, values); + + } + + return error; + +} + +// Print Element Information +void SFI_MVLEM_3D::Print(OPS_Stream &s, int flag) +{ + if (flag == 0) { + s << "SFI_MVLEM_3D Element tag: " << this->getTag() << endln; + s << "iNode: " << externalNodes(0) << ", jNode: " << externalNodes(1) << "lNode: " << externalNodes(2) << ", kNode: " << externalNodes(3) << endln; + s << "Element height: " << h << endln; + s << "Number of RC panel elements: " << m << endln; + + // get resisting forces in global system + s << "Global resisting forces: " << this->getResistingForce_24DOF(); + + for (int i = 0; i < m; i++) { + s << "\nPanel #: " << i + 1 << endln; + theMaterial[i]->Print(s, flag); + } + + } + else if (flag == 1) { + // does nothing + } + +} + +// Set element responses +Response *SFI_MVLEM_3D::setResponse(const char **argv, int argc, OPS_Stream &s) +{ + + Response *theResponse = 0; + + s.tag("ElementOutput"); + s.attr("eleType", "SFI_MVLEM_3D"); + s.attr("eleTag", this->getTag()); + s.attr("node1", externalNodes[0]); + s.attr("node2", externalNodes[1]); + s.attr("node3", externalNodes[3]); + s.attr("node4", externalNodes[2]); + + // Nodal forces in global cs + if (strcmp(argv[0], "force") == 0 || strcmp(argv[0], "forces") == 0 || + strcmp(argv[0], "globalForce") == 0 || strcmp(argv[0], "globalForces") == 0) { + + s.tag("ResponseType", "Fx_i"); + s.tag("ResponseType", "Fy_i"); + s.tag("ResponseType", "Fz_i"); + s.tag("ResponseType", "Mx_i"); + s.tag("ResponseType", "My_i"); + s.tag("ResponseType", "Mz_i"); + s.tag("ResponseType", "Fx_j"); + s.tag("ResponseType", "Fy_j"); + s.tag("ResponseType", "Fz_j"); + s.tag("ResponseType", "Mx_j"); + s.tag("ResponseType", "My_j"); + s.tag("ResponseType", "Mz_j"); + s.tag("ResponseType", "Fx_k"); + s.tag("ResponseType", "Fy_k"); + s.tag("ResponseType", "Fz_k"); + s.tag("ResponseType", "Mx_k"); + s.tag("ResponseType", "My_k"); + s.tag("ResponseType", "Mz_k"); + s.tag("ResponseType", "Fx_l"); + s.tag("ResponseType", "Fy_l"); + s.tag("ResponseType", "Fz_l"); + s.tag("ResponseType", "Mx_l"); + s.tag("ResponseType", "My_l"); + s.tag("ResponseType", "Mz_l"); + + return theResponse = new ElementResponse(this, 1, Vector(24)); + + } + // Nodal forces in local cs + else if (strcmp(argv[0], "forceL") == 0 || strcmp(argv[0], "forcesL") == 0 || + strcmp(argv[0], "localForce") == 0 || strcmp(argv[0], "localForces") == 0) { + + s.tag("ResponseType", "Fx_i"); + s.tag("ResponseType", "Fy_i"); + s.tag("ResponseType", "Fz_i"); + s.tag("ResponseType", "Mx_i"); + s.tag("ResponseType", "My_i"); + s.tag("ResponseType", "Mz_i"); + s.tag("ResponseType", "Fx_j"); + s.tag("ResponseType", "Fy_j"); + s.tag("ResponseType", "Fz_j"); + s.tag("ResponseType", "Mx_j"); + s.tag("ResponseType", "My_j"); + s.tag("ResponseType", "Mz_j"); + s.tag("ResponseType", "Fx_k"); + s.tag("ResponseType", "Fy_k"); + s.tag("ResponseType", "Fz_k"); + s.tag("ResponseType", "Mx_k"); + s.tag("ResponseType", "My_k"); + s.tag("ResponseType", "Mz_k"); + s.tag("ResponseType", "Fx_l"); + s.tag("ResponseType", "Fy_l"); + s.tag("ResponseType", "Fz_l"); + s.tag("ResponseType", "Mx_l"); + s.tag("ResponseType", "My_l"); + s.tag("ResponseType", "Mz_l"); + + return theResponse = new ElementResponse(this, 2, Vector(24)); + + } + + // Shear deformation + else if (strcmp(argv[0], "ShearDef") == 0 || strcmp(argv[0], "sheardef") == 0) { + + s.tag("ResponseType", "Dsh"); + + return theResponse = new ElementResponse(this, 3, 0.0); + + } + + // Element curvature + else if (strcmp(argv[0], "Curvature") == 0 || strcmp(argv[0], "curvature") == 0) { + + s.tag("ResponseType", "fi"); + + return theResponse = new ElementResponse(this, 4, 0.0); + } + + // Material output + else if (strcmp(argv[0], "RCpanel") == 0 || strcmp(argv[0], "RCPanel") + || strcmp(argv[0], "RC_panel") || strcmp(argv[0], "RC_Panel") == 0) + { + + // Check if correct # of arguments passed + if (argc != 3) { + opserr << "WARNING: Number of recorder input for RC Panel is: " << argc - 1 << "; should be 2: panTag (one panel only: 1 to m) and $Response_Type.\n"; + return 0; + } + + int matNum = atoi(argv[1]); + + s.tag("Material"); + s.attr("number", matNum); + + return theResponse = theMaterial[matNum - 1]->setResponse(&argv[argc - 1], argc - 2, s); + + } + + s.endTag(); + + return 0; +} + +// Get shear deformation +double SFI_MVLEM_3D::getShearDef(void) +{ + return Dsh; +} + +// Get curvature (from vertical strains) +double SFI_MVLEM_3D::getCurvature(void) +{ + double Curv; + + Curv = (SFI_MVLEM_3DStrainY[0] - SFI_MVLEM_3DStrainY[m - 1]) / (x[0] - x[m - 1]); + + return Curv; +} + +// Get global forces at 24 DOFs (top and bottom node) +Vector SFI_MVLEM_3D::getResistingForce_24DOF(void) +{ + + for (int i = 0; i < 24; i++) { + P_24DOF(i) = SFI_MVLEM_3DR(i); + } + + return P_24DOF; +} + +// Obtain element responses +int SFI_MVLEM_3D::getResponse(int responseID, Information &eleInfo) +{ + + switch (responseID) + { + case 1: // Global forces + return eleInfo.setVector(this->getResistingForce_24DOF()); + + case 2: // Local forces + return eleInfo.setVector(this->getResistingForce_24DOF_local()); + + case 3: // Shear deformation + return eleInfo.setDouble(this->getShearDef()); + + case 4: // Curvature + return eleInfo.setDouble(this->getCurvature()); + + default: + + return 0; + + } + +} + +// Return element local forces +Vector SFI_MVLEM_3D::getResistingForce_24DOF_local(void) +{ + for (int i = 0; i < 24; i++) { + P_24DOF_local(i) = SFI_MVLEM_3DRlocal(i); + } + + return P_24DOF_local; +} + +// Compute element transformation matrix +void SFI_MVLEM_3D::setTransformationMatrix(void) { + + T.Zero(); // element transformation matrix + Tt.Zero(); // 3 x 3 - basic transformation matrix + T6.Zero(); // 6 x 6 - nodal transformation matrix + + // Define local axis: + // x: user input [x1, x2, x3] + // y: Nd1 -> Nd2 + // z: (x) x (y) + + // Vector components, magnitudes and iunit vectors + double Xx, Xy, Xz, X_, Xex, Xey, Xez; + double Yx, Yy, Yz, Y_, Yex, Yey, Yez; + double Zex, Zey, Zez; + + Xx = nd2Crds(0) - nd1Crds(0); + Xy = nd2Crds(1) - nd1Crds(1); + Xz = nd2Crds(2) - nd1Crds(2); + + // Magnitude + X_ = pow(pow(Xx, 2) + pow(Xy, 2) + pow(Xz, 2), 0.5); + + // unit x components + Xex = Xx / X_; + Xey = Xy / X_; + Xez = Xz / X_; + + // Components of local Y axis + Yx = nd3Crds(0) - nd1Crds(0); + Yy = nd3Crds(1) - nd1Crds(1); + Yz = nd3Crds(2) - nd1Crds(2); + + // Magnitude + Y_ = pow(pow(Yx, 2) + pow(Yy, 2) + pow(Yz, 2), 0.5); + + // unit y components + Yex = Yx / Y_; + Yey = Yy / Y_; + Yez = Yz / Y_; + + // (Ze) = (Xe) x (Ye) + Zex = Xey * Yez - Xez * Yey; + Zey = -(Xex*Yez - Xez * Yex); + Zez = Xex * Yey - Xey * Yex; + + // Fill in transformation matrices + // 3 x 3 - basic matrix + Tt(0, 0) = Xex; + Tt(1, 0) = Yex; + Tt(2, 0) = Zex; + Tt(0, 1) = Xey; + Tt(1, 1) = Yey; + Tt(2, 1) = Zey; + Tt(0, 2) = Xez; + Tt(1, 2) = Yez; + Tt(2, 2) = Zez; + + // 6 x 6 + for (int j = 0; j < 6; j += 3) { + + T6(j + 0, j + 0) = Xex; + T6(j + 1, j + 0) = Yex; + T6(j + 2, j + 0) = Zex; + T6(j + 0, j + 1) = Xey; + T6(j + 1, j + 1) = Yey; + T6(j + 2, j + 1) = Zey; + T6(j + 0, j + 2) = Xez; + T6(j + 1, j + 2) = Yez; + T6(j + 2, j + 2) = Zez; + } + + // 24 x 24 + for (int j = 0; j < 24; j += 3) { + + T(j + 0, j + 0) = Xex; + T(j + 1, j + 0) = Yex; + T(j + 2, j + 0) = Zex; + T(j + 0, j + 1) = Xey; + T(j + 1, j + 1) = Yey; + T(j + 2, j + 1) = Zey; + T(j + 0, j + 2) = Xez; + T(j + 1, j + 2) = Yez; + T(j + 2, j + 2) = Zez; + } + + for (int i = 0; i < m; ++i) + T(24 + i, 24 + i) = 1.0; // Diagonal terms accounting for horizontal stiffness + +}; \ No newline at end of file diff --git a/SRC/element/mvlem/SFI_MVLEM_3D.h b/SRC/element/mvlem/SFI_MVLEM_3D.h new file mode 100644 index 000000000..6c1b602d7 --- /dev/null +++ b/SRC/element/mvlem/SFI_MVLEM_3D.h @@ -0,0 +1,225 @@ +// Code written/implemented by: Kristijan Kolozvari (kkolozvari@fullerton.edu) +// Kamiar Kalbasi +// Kutay Orakcal +// John Wallace +// +// User documentation available at: https://kkolozvari.github.io/SFI-MVLEM-3D/ +// +// Created: 03/2021 +// +// Description: The MVLEM-3D model is a three-dimenaional four-node element with 24 DOFs for nonlinear analysis of +// flexure-controlled non-rectangular reinforced concrete walls subjected to multidirectional loading. The model is +// an extension of the two-dimensional, two-node Multiple-Vertical-Line-Element-Model (MVLEM). The baseline MVLEM, +// which is essentially a line element for rectangular walls subjected to in-plane loading, is extended to a +// three-dimensional model formulation by: 1) applying geometric transformation of the element in-plane degrees of +// freedom that convert it into a four-node element formulation and by 2) incorporating linear +// elastic out-of-plane behavior based on the Kirchhoff plate theory. The in-plane and the out-of-plane +// element behaviors are uncoupled in the present model formulation. +// +// Notes: +// Nodes should be assigned in counterclockwise direction. +// 4........3 +// . . +// . . +// . . ^ y +// 1........2 |-> x +// +// Reference: +// K. Kolozvari, K. Kalbasi, K. Orakcal & J. W. Wallace (2021), "Three-dimensional shear-flexure interaction model for analysis of non-planar reinforced concrete walls", Journal of Building Engineering. +// +// Source: /usr/local/cvs/OpenSees/SRC/element/mvlem/SFI_MVLEM_3D.cpp +// +// Rev: 1.0 + + +#ifndef SFI_MVLEM_3D_h +#define SFI_MVLEM_3D_h +#include +#include +#include +#include +class Node; +class Channel; +class NDMaterial; +class Response; + +class SFI_MVLEM_3D : public Element +{ +public: + + // Constructors + SFI_MVLEM_3D(int tag, // element tag + double Dens, // density + int Nd1, int Nd2, int Nd3, int Nd4, // end node tags + NDMaterial **Materials, // array of material tags + double *Thickness, // array of macro-fiber thickness + double *Width, // array of macro-fiber widths + int mm, // number of macro-fibers (RC panels) + double cc, // center of rotation + double nn, // poisson ratio (for out-of-plane behavior) + double tf); // thickness factor (for out-of-plane behavior) + + SFI_MVLEM_3D(); + + // Destructor + ~SFI_MVLEM_3D(); + + // Public methods to obtain inforrmation about dof & comectivity + int getNumExternalNodes(void) const; + const ID &getExternalNodes(void); + Node **getNodePtrs(void); + int getNumDOF(void); + void setDomain(Domain *theDomain); + + // Public methods to set the state of the element + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + int update(void); + + // Public methods to obtain stiffness, mass, damping and residual information + const Matrix &getTangentStiff(void); + const Matrix &getInitialStiff(void); + const Matrix &getDamp(void); + const Matrix &getMass(void); + + void zeroLoad(void); + int addLoad(ElementalLoad *theLoad, double loadFactor); + int addInertiaLoadToUnbalance(const Vector &accel); + const Vector &getResistingForce(void); + const Vector &getResistingForceIncInertia(void); + + // 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); + + Response **theResponses; // pointer to material responses needed for Concrete + +protected: + +private: + + void setTransformationMatrix(void); + + // Private member functions - only available to objects of the class + double *computeCurrentStrain(void); + double getShearDef(void); + double getCurvature(void); + Vector getResistingForce_24DOF(void); + Vector getResistingForce_24DOF_local(void); + + // Private attributes - a copy for each object of the class + ID externalNodes; // contains the id's of end nodes + + // Input variables + Node *theNodes[4]; // external node pointers +++ + Node **theNodesX; // array of internal node pointers + Node **theNodesALL; // array of ALL node pointers + Node *theNd1; // pointer to bottom node + Node *theNd2; // pointer to bottom node + Node *theNd3; // pointer to top node + Node *theNd4; // pointer to top node + double density; // material density + NDMaterial **theMaterial; // array of ND materials + Vector *theLoad; // pointer to element load + double c; // center of rotation + int m; // no. of RC panels + double NUelastic; // Poisson ratio + double Tfactor; // Thickness factor + + // Nodal coordinates + Vector nd1Crds; + Vector nd2Crds; + Vector nd3Crds; + Vector nd4Crds; + + // Out of plane parameters + double Eave; // Modulus of Elasticity + double Tave; // Thickness + double *modifiedT; // Modified Thickness + + // Imaginary Beam Parameters + double Eib; // Modulus of elasticity of imaginary beams + double Hib; // Height of imaginary beam + double Aib; // Area of imaginary beams cross-section + double Iib; // Moment of inertia of imaginary beam + + // Calculated element parameters + double h; // height of SFI_MVLEM_3D element (undeformed configuration) + double Lw; // lenght of SFI_MVLEM_3D elemtn, i.e. wall length + double TotalMass; // element mass - you dont need this !!! + double NodeMass; // nodal mass + double d; // distance of corner nodes from center axis + double K_drilling; // drilling Stiffness + + // Calculated element arrays + double *x; // macro-fiber locations + double *b; // macro-fiber widths + double *t; // macro-fiber thickness + double *AcX; // macro-fiber areas in X direction + double *AcY; // macro-fiber areas in Y direction + double *kx; // macro-fiber axial stiffness in X direction + double *ky; // macro-fiber axial stiffness in Y direction + double Kh; // macro-fiber shear stiffness + double *Fx; // macro-fiber axial force in X direction + double *Fy; // macro-fiber axial force in Y direction + double *Fxy; // macro-fiber shear force in (in horizontal plane) + double *Dx; // macro-fiber axial deformation in X direction + double *Dy; // macro-fiber axial deformation in Y direction + double *Dxy; // macro-fiber shear deformation (in horizontal plane) + double *SFI_MVLEM_3DStrainX; // macro-fiber axial strain in X direction (epsX) + double *SFI_MVLEM_3DStrainY; // macro-fiber axial strain in Y direction (epsY) + double *SFI_MVLEM_3DStrainXY; // macro-fiber shear strain (gammaXY) + double *SFI_MVLEM_3DStrain; // macro-fiber strains + double *Dens; // macro-fiber densities + + // For recorders + double Dsh; // recorded shear deformation + Vector P_24DOF; // recorded forces at end nodal 6DOFs + Vector P_24DOF_local; + + // Class-wide matrices/vectors/doubles + // Constant stiffnes terms + double K1; + double K2; + double K3; + double K4; + double K5; + double K6; + double K7; + double K8; + double K9; + double K10; + double K11; + double K12; + double K13; + double K14; + double K15; + double K16; + double K17; + double K18; + double K19; + double K20; + double K21; + double K22; + + Matrix SFI_MVLEM_3DK; // stiffness + Matrix SFI_MVLEM_3DD; // damping + Matrix SFI_MVLEM_3DM; // mass + Vector SFI_MVLEM_3DR; // force + + Matrix SFI_MVLEM_3DKlocal; // Local stiffness matrix + Vector SFI_MVLEM_3DRlocal; // Local force vector + Matrix SFI_MVLEM_3DMlocal; // Local mass matrix + Matrix SFI_MVLEM_3DDlocal; // Local damping matrix + + Matrix T; // Transform dofs + Matrix T6; // Transform Node DOFs + Matrix Tt; // Transform crds +}; +#endif +#pragma once \ No newline at end of file diff --git a/SRC/interpreter/OpenSeesElementCommands.cpp b/SRC/interpreter/OpenSeesElementCommands.cpp index 85ea06061..53aaa2864 100644 --- a/SRC/interpreter/OpenSeesElementCommands.cpp +++ b/SRC/interpreter/OpenSeesElementCommands.cpp @@ -99,6 +99,7 @@ void* OPS_ElastomericX(); void* OPS_MVLEM(); void* OPS_SFI_MVLEM(); void* OPS_MVLEM_3D(); +void* OPS_SFI_MVLEM_3D(); void* OPS_MultiFP2d(); void* OPS_ShellMITC4(); void* OPS_ShellMITC9(); @@ -618,6 +619,7 @@ namespace { functionMap.insert(std::make_pair("MVLEM", &OPS_MVLEM)); functionMap.insert(std::make_pair("SFI_MVLEM", &OPS_SFI_MVLEM)); functionMap.insert(std::make_pair("MVLEM_3D", &OPS_MVLEM_3D)); + functionMap.insert(std::make_pair("SFI_MVLEM_3D", &OPS_SFI_MVLEM_3D)); functionMap.insert(std::make_pair("MultiFP2d", &OPS_MultiFP2d)); functionMap.insert(std::make_pair("shell", &OPS_ShellMITC4)); functionMap.insert(std::make_pair("Shell", &OPS_ShellMITC4)); diff --git a/SRC/material/nD/FSAM.cpp b/SRC/material/nD/FSAM.cpp index 20f5bdabe..acdae7a92 100644 --- a/SRC/material/nD/FSAM.cpp +++ b/SRC/material/nD/FSAM.cpp @@ -241,6 +241,7 @@ FSAM::FSAM (int tag, E0y = 0.0; Ec = 0.0; + fpc = 0.0; epcc = 0.0; et = 0.0; @@ -408,7 +409,7 @@ FSAM::FSAM (int tag, theResponses[0] = theMaterial[5]->setResponse(argv, 1, *theDummyStream); if (theResponses[0] == 0) { - opserr << " FSAM::FSAM - failed to set appropriate materials tag: " << tag << "\n"; + opserr << " FSAM::FSAM - failed to get cracking strain for material with tag: " << tag << "\n"; exit(-1); } @@ -416,7 +417,7 @@ FSAM::FSAM (int tag, theResponses[1] = theMaterial[4]->setResponse(argv, 1, *theDummyStream); if (theResponses[1] == 0) { - opserr << " FSAM::FSAM - failed to set appropriate materials tag: " << tag << "\n"; + opserr << " FSAM::FSAM - failed to get input parameters for material with tag: " << tag << "\n"; exit(-1); } @@ -459,6 +460,9 @@ FSAM::FSAM (int tag, // Strain at peak compressive stress for concrete epcc = InputConc[2]; + + // Peak compressive stress for concrete + fpc = InputConc[1]; // Cracking strain for concrete et = InputConc[7]; @@ -2516,6 +2520,13 @@ Response* FSAM::setResponse(const char **argv, int argc, OPS_Stream &theOutput) theResponse = new MaterialResponse(this, 111, data11); + } + else if (strcmp(argv[0], "getInputParameters") == 0) { + + Vector data12(12); + data12.Zero(); + theResponse = new MaterialResponse(this, 112, data12); + } else return this->NDMaterial::setResponse(argv, argc, theOutput); @@ -2559,9 +2570,31 @@ int FSAM::getResponse(int responseID, Information &matInfo) } else if (responseID == 111){ return matInfo.setVector(this->getCrackingAngles()); + } else if (responseID == 112) { + return matInfo.setVector(this->getInputParameters()); + } else { return 0; } } + +// Function that returns input parameters - added for SFI_MVLEM_3D +Vector FSAM::getInputParameters(void) +{ + Vector input_par(12); // size = max number of parameters (assigned + default) + + input_par.Zero(); + + input_par(0) = this->getTag(); + input_par(1) = rho; + input_par(2) = fpc; + input_par(3) = roux; + input_par(4) = rouy; + input_par(5) = nu; + input_par(6) = alfadow; + input_par(9) = Ec; // added for quadWall element + + return input_par; +} \ No newline at end of file diff --git a/SRC/material/nD/FSAM.h b/SRC/material/nD/FSAM.h index f87628533..582482436 100644 --- a/SRC/material/nD/FSAM.h +++ b/SRC/material/nD/FSAM.h @@ -120,6 +120,7 @@ class FSAM : public NDMaterial void betaf4(double &eo, double &epc, double &fc, double &epscmax); // biaxial damage void InterLocker_improved(double &e_cr_normal, double &f_cr_normal, double &e_cr_parallel, double &e_cr_parallel_old, double &epc, double &Ec, double &Tau_Interlock_old); // shear aggregate interlock void dowel_action(double &gama, double &Es); // reinforcement dowel action + Vector getInputParameters(void); // return input parameters // Pointers to material arrays UniaxialMaterial **theMaterial; // pointer of the materials @@ -136,6 +137,7 @@ class FSAM : public NDMaterial double E0y; // steel Young's modulus - Y Direction double epcc; // concrete strain at compressive stress double et; // monotonic Cracking Strain (et = 0.00008) + double fpc; // concrete compressive strength double Ec; // concrete Young's modulus double nu; // friction Coefficient of Shear Aggregate Interlock double alfadow; // stiffness Coefficient of Dowel Action diff --git a/SRC/recorder/GmshRecorder.cpp b/SRC/recorder/GmshRecorder.cpp index 33bf38ec4..5cf063ba1 100644 --- a/SRC/recorder/GmshRecorder.cpp +++ b/SRC/recorder/GmshRecorder.cpp @@ -1423,6 +1423,7 @@ GmshRecorder::setGMSHType() gmshtypes[ELE_TAG_MVLEM] = GMSH_POLY_VERTEX; gmshtypes[ELE_TAG_SFI_MVLEM] = GMSH_POLY_VERTEX; gmshtypes[ELE_TAG_MVLEM_3D] = GMSH_POLY_VERTEX; + gmshtypes[ELE_TAG_SFI_MVLEM_3D] = GMSH_POLY_VERTEX; gmshtypes[ELE_TAG_PFEMElement2DFIC] = GMSH_TRIANGLE; gmshtypes[ELE_TAG_CatenaryCable] = GMSH_LINE; gmshtypes[ELE_TAG_FourNodeTetrahedron] = GMSH_TETRA; diff --git a/SRC/recorder/PVDRecorder.cpp b/SRC/recorder/PVDRecorder.cpp index 141fd4eb4..9a845fd0f 100644 --- a/SRC/recorder/PVDRecorder.cpp +++ b/SRC/recorder/PVDRecorder.cpp @@ -1964,6 +1964,7 @@ PVDRecorder::setVTKType() vtktypes[ELE_TAG_MVLEM] = VTK_POLY_VERTEX; vtktypes[ELE_TAG_SFI_MVLEM] = VTK_POLY_VERTEX; vtktypes[ELE_TAG_MVLEM_3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_SFI_MVLEM_3D] = VTK_POLY_VERTEX; vtktypes[ELE_TAG_PFEMElement2DFIC] = VTK_TRIANGLE; vtktypes[ELE_TAG_TaylorHood2D] = VTK_QUADRATIC_TRIANGLE; vtktypes[ELE_TAG_PFEMElement2DQuasi] = VTK_TRIANGLE; diff --git a/SRC/recorder/VTK_Recorder.cpp b/SRC/recorder/VTK_Recorder.cpp index dac068947..ccf17142f 100644 --- a/SRC/recorder/VTK_Recorder.cpp +++ b/SRC/recorder/VTK_Recorder.cpp @@ -1160,6 +1160,7 @@ VTK_Recorder::setVTKType() vtktypes[ELE_TAG_MVLEM] = VTK_POLY_VERTEX; vtktypes[ELE_TAG_SFI_MVLEM] = VTK_POLY_VERTEX; vtktypes[ELE_TAG_MVLEM_3D] = VTK_POLY_VERTEX; + vtktypes[ELE_TAG_SFI_MVLEM_3D] = VTK_POLY_VERTEX; vtktypes[ELE_TAG_PFEMElement2DFIC] = VTK_TRIANGLE; vtktypes[ELE_TAG_TaylorHood2D] = VTK_QUADRATIC_TRIANGLE; vtktypes[ELE_TAG_PFEMElement2DQuasi] = VTK_TRIANGLE; diff --git a/Win32/proj/element/element.vcxproj b/Win32/proj/element/element.vcxproj index 84242c40d..d9851f5d5 100644 --- a/Win32/proj/element/element.vcxproj +++ b/Win32/proj/element/element.vcxproj @@ -135,6 +135,7 @@ + @@ -401,6 +402,7 @@ + diff --git a/Win32/proj/element/element.vcxproj.filters b/Win32/proj/element/element.vcxproj.filters index 4c758ceef..da0c5c771 100644 --- a/Win32/proj/element/element.vcxproj.filters +++ b/Win32/proj/element/element.vcxproj.filters @@ -703,6 +703,9 @@ mvlem + + + mvlem componentElement @@ -1416,6 +1419,9 @@ mvlem + + + mvlem componentElement diff --git a/Win64/proj/element/element.vcxproj b/Win64/proj/element/element.vcxproj index 8e696ef37..0fa403955 100644 --- a/Win64/proj/element/element.vcxproj +++ b/Win64/proj/element/element.vcxproj @@ -222,6 +222,7 @@ + @@ -493,6 +494,7 @@ + diff --git a/Win64/proj/element/element.vcxproj.filters b/Win64/proj/element/element.vcxproj.filters index 7b99236d6..b9f0dab53 100644 --- a/Win64/proj/element/element.vcxproj.filters +++ b/Win64/proj/element/element.vcxproj.filters @@ -730,6 +730,9 @@ mvlem + + + mvlem componentElement @@ -1446,6 +1449,9 @@ mvlem + + + mvlem componentElement diff --git a/Win64/proj/openSees/OpenSees.vcxproj b/Win64/proj/openSees/OpenSees.vcxproj index a0334e64e..ad1c5d016 100644 --- a/Win64/proj/openSees/OpenSees.vcxproj +++ b/Win64/proj/openSees/OpenSees.vcxproj @@ -108,7 +108,7 @@ actor.lib;analysis.lib;arpack.lib;blas.lib;cblas.lib;convergence.lib;cssparse.lib;damage.lib;database.lib;DoddRestrepo.lib;domain.lib;drain.lib;element.lib;feap.lib;fedeas.lib;glu32.lib;graph.lib;handler.lib;ifconsol.lib;lapack.lib;libifcoremt.lib;libmmt.lib;material.lib;matrix.lib;modelbuilder.lib;opengl32.lib;optimization.lib;PML.lib;recorder.lib;reliability.lib;renderer.lib;sdmuc.lib;superLU.lib;system.lib;tagged.lib;tcl.lib;tcl86t.lib;tk86t.lib;umfpackC.lib;utility.lib;wsock32.lib;%(AdditionalDependencies) .\..\..\bin\OpenSees.exe true - c:\Program Files\tcl\lib;..\..\lib;..\..\lib\release;%(AdditionalLibraryDirectories) + C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\compiler\lib\intel64_win;c:\Program Files\tcl\lib;..\..\lib;..\..\lib\release;%(AdditionalLibraryDirectories) %(IgnoreSpecificDefaultLibraries) .\..\..\bin\OpenSees.pdb Console From 0e40b03954300cf35763c1373a89853f65ce12ad Mon Sep 17 00:00:00 2001 From: kkolozvari <53920372+kkolozvari@users.noreply.github.com> Date: Sun, 7 Mar 2021 17:34:28 -0800 Subject: [PATCH 012/207] Update OpenSees.vcxproj MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove Intel® Parallel Studio path before submitting PR --- Win64/proj/openSees/OpenSees.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Win64/proj/openSees/OpenSees.vcxproj b/Win64/proj/openSees/OpenSees.vcxproj index ad1c5d016..a0334e64e 100644 --- a/Win64/proj/openSees/OpenSees.vcxproj +++ b/Win64/proj/openSees/OpenSees.vcxproj @@ -108,7 +108,7 @@ actor.lib;analysis.lib;arpack.lib;blas.lib;cblas.lib;convergence.lib;cssparse.lib;damage.lib;database.lib;DoddRestrepo.lib;domain.lib;drain.lib;element.lib;feap.lib;fedeas.lib;glu32.lib;graph.lib;handler.lib;ifconsol.lib;lapack.lib;libifcoremt.lib;libmmt.lib;material.lib;matrix.lib;modelbuilder.lib;opengl32.lib;optimization.lib;PML.lib;recorder.lib;reliability.lib;renderer.lib;sdmuc.lib;superLU.lib;system.lib;tagged.lib;tcl.lib;tcl86t.lib;tk86t.lib;umfpackC.lib;utility.lib;wsock32.lib;%(AdditionalDependencies) .\..\..\bin\OpenSees.exe true - C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\compiler\lib\intel64_win;c:\Program Files\tcl\lib;..\..\lib;..\..\lib\release;%(AdditionalLibraryDirectories) + c:\Program Files\tcl\lib;..\..\lib;..\..\lib\release;%(AdditionalLibraryDirectories) %(IgnoreSpecificDefaultLibraries) .\..\..\bin\OpenSees.pdb Console From 7769dbd0492d7c9ea93e4db0cb98259c9c473b1e Mon Sep 17 00:00:00 2001 From: Anurag Upadhyay <35711550+u-anurag@users.noreply.github.com> Date: Mon, 8 Mar 2021 23:49:23 -0700 Subject: [PATCH 013/207] Adding ShellNLDKGQ to the Block2D command --- SRC/interpreter/OpenSeesElementCommands.cpp | 36 +++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/SRC/interpreter/OpenSeesElementCommands.cpp b/SRC/interpreter/OpenSeesElementCommands.cpp index 85ea06061..a8d02d338 100644 --- a/SRC/interpreter/OpenSeesElementCommands.cpp +++ b/SRC/interpreter/OpenSeesElementCommands.cpp @@ -789,6 +789,20 @@ int OPS_doBlock2D() } cArg = 7; + + } else if (strcmp(type, "ShellNLDKGQ") == 0 || strcmp(type, "shellNLDKGQ") == 0 { + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr<<"WARNING: want - secTag\n"; + return -1; + } + int numdata = 1; + if (OPS_GetIntInput(&numdata, &secTag) < 0) { + opserr << "WARNING invalid secTag\n"; + return -1; + } + cArg = 7; + + } else if (strcmp(type, "bbarQuad") == 0 || strcmp(type,"mixedQuad") == 0) { if (OPS_GetNumRemainingInputArgs() < 2) { opserr<<"WARNING: want - thick, matTag\n"; @@ -996,6 +1010,28 @@ int OPS_doBlock2D() theEle = new ShellMITC4(eleID,nd1,nd2,nd3,nd4,*sec); + + } else if (strcmp(type, "ShellNLDKGQ") == 0 || strcmp(type, "shellNLDKGQ") == 0 { + + if (numEleNodes != 4) { + opserr<<"WARNING ShellNLDKGQ element only needs four nodes\n"; + return -1; + } + SectionForceDeformation *sec = OPS_getSectionForceDeformation(secTag); + + if (sec == 0) { + opserr << "WARNING: section " << secTag << " not found\n"; + return -1; + } + + int nd1 = nodeTags(0) + idata[2]; + int nd2 = nodeTags(1) + idata[2]; + int nd3 = nodeTags(2) + idata[2]; + int nd4 = nodeTags(3) + idata[2]; + theEle = new ShellNLDKGQ(eleID,nd1,nd2,nd3,nd4,*sec); + + + } else if (strcmp(type, "bbarQuad") == 0 || strcmp(type,"mixedQuad") == 0) { if (numEleNodes != 4) { From 27dd5cc75d06ce1db7219c01e9cf8ddcf52e00d0 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 15 Mar 2021 16:51:13 -0700 Subject: [PATCH 014/207] Update commands.cpp --- SRC/tcl/commands.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index 894ad6237..3c5a1ca6f 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -2282,9 +2282,9 @@ printB(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) } if (theSOE != 0) { if (theStaticIntegrator != 0) - theStaticIntegrator->formTangent(); + theStaticIntegrator->formUnbalance(); else if (theTransientIntegrator != 0) - theTransientIntegrator->formTangent(0); + theTransientIntegrator->formUnbalance(); const Vector &b = theSOE->getB(); *output << b; From 852d9aa69a7b845c69b5c783694ea8bd00e8ab2b Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 15 Mar 2021 16:51:59 -0700 Subject: [PATCH 015/207] Update OpenSeesCommands.cpp --- SRC/interpreter/OpenSeesCommands.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SRC/interpreter/OpenSeesCommands.cpp b/SRC/interpreter/OpenSeesCommands.cpp index 160adf422..9c68df5a0 100644 --- a/SRC/interpreter/OpenSeesCommands.cpp +++ b/SRC/interpreter/OpenSeesCommands.cpp @@ -1961,9 +1961,9 @@ int OPS_printB() } if (theSOE != 0) { if (theStaticIntegrator != 0) { - theStaticIntegrator->formTangent(); + theStaticIntegrator->formUnbalance(); } else if (theTransientIntegrator != 0) { - theTransientIntegrator->formTangent(0); + theTransientIntegrator->formUnbalance(); } Vector &b = const_cast(theSOE->getB()); From 7c765a43a8c915bf7d808e052114ac387215f94b Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 15 Mar 2021 17:54:01 -0700 Subject: [PATCH 016/207] Update OpenSeesElementCommands.cpp --- SRC/interpreter/OpenSeesElementCommands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/interpreter/OpenSeesElementCommands.cpp b/SRC/interpreter/OpenSeesElementCommands.cpp index 8f10062ba..73e6d9833 100644 --- a/SRC/interpreter/OpenSeesElementCommands.cpp +++ b/SRC/interpreter/OpenSeesElementCommands.cpp @@ -792,7 +792,7 @@ int OPS_doBlock2D() cArg = 7; - } else if (strcmp(type, "ShellNLDKGQ") == 0 || strcmp(type, "shellNLDKGQ") == 0 { + } else if (strcmp(type, "ShellNLDKGQ") == 0 || strcmp(type, "shellNLDKGQ") == 0) { if (OPS_GetNumRemainingInputArgs() < 1) { opserr<<"WARNING: want - secTag\n"; return -1; From a91f72c75101d5adb11493d7e8459f12febf5128 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 15 Mar 2021 17:55:53 -0700 Subject: [PATCH 017/207] Update OpenSeesElementCommands.cpp --- SRC/interpreter/OpenSeesElementCommands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/interpreter/OpenSeesElementCommands.cpp b/SRC/interpreter/OpenSeesElementCommands.cpp index 73e6d9833..ed7113c1d 100644 --- a/SRC/interpreter/OpenSeesElementCommands.cpp +++ b/SRC/interpreter/OpenSeesElementCommands.cpp @@ -1013,7 +1013,7 @@ int OPS_doBlock2D() - } else if (strcmp(type, "ShellNLDKGQ") == 0 || strcmp(type, "shellNLDKGQ") == 0 { + } else if (strcmp(type, "ShellNLDKGQ") == 0 || strcmp(type, "shellNLDKGQ") == 0) { if (numEleNodes != 4) { opserr<<"WARNING ShellNLDKGQ element only needs four nodes\n"; From 952458a9417c2d7c9490715ad276af23cf8ea842 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 15 Mar 2021 17:57:45 -0700 Subject: [PATCH 018/207] Update OpenSeesElementCommands.cpp --- SRC/interpreter/OpenSeesElementCommands.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/SRC/interpreter/OpenSeesElementCommands.cpp b/SRC/interpreter/OpenSeesElementCommands.cpp index ed7113c1d..a8ae33a78 100644 --- a/SRC/interpreter/OpenSeesElementCommands.cpp +++ b/SRC/interpreter/OpenSeesElementCommands.cpp @@ -56,6 +56,7 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #include #include #include +#include #include #include From 25509bdaf6ec774770a885c39ea22d01d59ca715 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 15 Mar 2021 18:21:09 -0700 Subject: [PATCH 019/207] Update PlateRebarMaterial.cpp Fixing getTangent() method --- SRC/material/nD/PlateRebarMaterial.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/SRC/material/nD/PlateRebarMaterial.cpp b/SRC/material/nD/PlateRebarMaterial.cpp index 75001e4e1..53152d1f0 100644 --- a/SRC/material/nD/PlateRebarMaterial.cpp +++ b/SRC/material/nD/PlateRebarMaterial.cpp @@ -250,14 +250,14 @@ PlateRebarMaterial::getTangent( ) tangent(1,1) = tan; else { tangent(0,0) = tan * c * c * c * c ; - tangent(0,2) = tan * c * c * c * s ; - tangent(0,1) = tan * c * c * s * s ; - tangent(2,0) = tangent(0,1) ; - tangent(2,2) = tangent(0,2) ; - tangent(2,1) = tan * c * s * s * s ; - tangent(1,0) = tangent(0,2) ; - tangent(1,2) = tangent(1,2) ; - tangent(1,1) = tan * s * s * s * s ; + tangent(0,1) = tan * c * c * c * s ; + tangent(0,2) = tan * c * c * s * s ; + tangent(1,0) = tangent(0,1) ; + tangent(1,1) = tangent(0,2) ; + tangent(1,2) = tan * c * s * s * s ; + tangent(2,0) = tangent(0,2) ; + tangent(2,1) = tangent(1,2) ; + tangent(2,2) = tan * s * s * s * s ; } return tangent ; From 2037175db763194073907675fbd549804e62a7d5 Mon Sep 17 00:00:00 2001 From: mhscott Date: Sun, 28 Mar 2021 19:39:24 -0700 Subject: [PATCH 020/207] Adding new files for U.Sydney warping elements --- .../CorotCrdTransfWarping3d.cpp | 2182 +++++++++++++++++ .../CorotCrdTransfWarping3d.h | 142 ++ .../DispBeamColumnWarping3d.cpp | 1916 +++++++++++++++ .../dispBeamColumn/DispBeamColumnWarping3d.h | 140 ++ .../ElasticBeamWarping3d.cpp | 1093 +++++++++ .../elasticBeamColumn/ElasticBeamWarping3d.h | 117 + .../section/FiberSectionWarping3d.cpp | 1344 ++++++++++ SRC/material/section/FiberSectionWarping3d.h | 122 + 8 files changed, 7056 insertions(+) create mode 100755 SRC/coordTransformation/CorotCrdTransfWarping3d.cpp create mode 100755 SRC/coordTransformation/CorotCrdTransfWarping3d.h create mode 100755 SRC/element/dispBeamColumn/DispBeamColumnWarping3d.cpp create mode 100755 SRC/element/dispBeamColumn/DispBeamColumnWarping3d.h create mode 100755 SRC/element/elasticBeamColumn/ElasticBeamWarping3d.cpp create mode 100755 SRC/element/elasticBeamColumn/ElasticBeamWarping3d.h create mode 100755 SRC/material/section/FiberSectionWarping3d.cpp create mode 100755 SRC/material/section/FiberSectionWarping3d.h diff --git a/SRC/coordTransformation/CorotCrdTransfWarping3d.cpp b/SRC/coordTransformation/CorotCrdTransfWarping3d.cpp new file mode 100755 index 000000000..a6416ac0b --- /dev/null +++ b/SRC/coordTransformation/CorotCrdTransfWarping3d.cpp @@ -0,0 +1,2182 @@ +/* ****************************************************************** ** +** 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/08/07 16:52:17 $ +// $Source: /usr/local/cvs/OpenSees/SRC/coordTransformation/CorotCrdTransfWarping3d.cpp,v $ + +// Written: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) +// Created: 05/2000 +// Revision: rms 06/2000 (using Assemble, and AssembleTranspose) +// +// Modified: 04/2005 Andreas Schellenberg (getBasicTrialVel, getBasicTrialAccel) +// Purpose: This file contains the implementation for the +// CorotCrdTransfWarping3d class. CorotCrdTransfWarping3d is a Corot +// transformation for a spatial frame between the global +// and basic coordinate systems. +// Modified by Xi Zhang from University of Sydney, Australia (include warping degrees of freedom). Refer to +// Formulation and Implementation of Three-dimensional Doubly Symmetric Beam-Column Analyses with Warping Effects in OpenSees +// Research Report R917, School of Civil Engineering, University of Sydney. + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +using std::string; +using namespace std; + +// initialize static variables +Matrix CorotCrdTransfWarping3d::RI(3,3); +Matrix CorotCrdTransfWarping3d::RJ(3,3); +Matrix CorotCrdTransfWarping3d::Rbar(3,3); +Matrix CorotCrdTransfWarping3d::e(3,3); +Matrix CorotCrdTransfWarping3d::Tp(6,7); +Matrix CorotCrdTransfWarping3d::T(9,14); // chagne dimension of the matrix to suit for warping degrees +Matrix CorotCrdTransfWarping3d::Tlg(14,14); // chagne dimension of the matrix to suit for warping degrees +Matrix CorotCrdTransfWarping3d::TlgInv(14,14); // chagne dimension of the matrix to suit for warping degrees +Matrix CorotCrdTransfWarping3d::kg(14,14); +Matrix CorotCrdTransfWarping3d::Lr2(14,3); // chagne dimension of the matrix to suit for warping degrees +Matrix CorotCrdTransfWarping3d::Lr3(14,3); // chagne dimension of the matrix to suit for warping degrees +Matrix CorotCrdTransfWarping3d::A(3,3); + + +void* OPS_CorotCrdTransfWarping3d() +{ + if(OPS_GetNumRemainingInputArgs() < 4) { + opserr<<"insufficient arguments for CorotCrdTransfWarping3d\n"; + return 0; + } + + // get tag + int tag; + int numData = 1; + if(OPS_GetIntInput(&numData,&tag) < 0) return 0; + + // get vector + Vector vec(3); + double* vptr = &vec(0); + numData = 3; + if(OPS_GetDoubleInput(&numData,vptr) < 0) return 0; + + // get option + Vector jntOffsetI(3), jntOffsetJ(3); + double *iptr=&jntOffsetI(0), *jptr=&jntOffsetJ(0); + while(OPS_GetNumRemainingInputArgs() > 6) { + std::string type = OPS_GetString(); + if(type == "-jntOffset") { + if(OPS_GetDoubleInput(&numData,iptr) < 0) return 0; + if(OPS_GetDoubleInput(&numData,jptr) < 0) return 0; + } + } + + return new CorotCrdTransfWarping3d(tag,vec,jntOffsetI,jntOffsetJ); +} + +// constructor: +CorotCrdTransfWarping3d::CorotCrdTransfWarping3d(int tag, const Vector &vecInLocXZPlane, + const Vector &rigJntOffsetI, + const Vector &rigJntOffsetJ): +CrdTransf(tag, CRDTR_TAG_CorotCrdTransfWarping3d), +vAxis(3), nodeIOffset(3), nodeJOffset(3), xAxis(3), +nodeIPtr(0), nodeJPtr(0), R0(3,3), L(0), Ln(0), +alphaIq(4), alphaJq(4), +alphaIqcommit(4), alphaJqcommit(4), alphaI(3), alphaJ(3), +ulcommit(9), ul(9), ulpr(9), +nodeIInitialDisp(0), nodeJInitialDisp(0), initialDispChecked(false) +{ + // check vector that defines local xz plane + if (&vecInLocXZPlane == 0 || vecInLocXZPlane.Size() != 3 ) + { + opserr << "CorotCrdTransfWarping3d::CorotCrdTransfWarping3d: Vector that defines local xz plane is invalid\n"; + opserr << "Size must be 3\n. Using (0,0,1)"; + vAxis(0) = 0; vAxis(1) = 0; vAxis(2) = 1; + } + else + vAxis = vecInLocXZPlane; + // check rigid joint offset for node I + if (&rigJntOffsetI == 0 || rigJntOffsetI.Size() != 3 ) + { + opserr << "CorotCrdTransfWarping3d::CorotCrdTransfWarping3d: Invalid rigid joint offset vector for node I\n"; + opserr << "Size must be 3\n"; + nodeIOffset.Zero(); + } + else + nodeIOffset = rigJntOffsetI; + + // check rigid joint offset for node J + if (&rigJntOffsetJ == 0 || rigJntOffsetJ.Size() != 3 ) + { + opserr << "CorotCrdTransfWarping3d::CorotCrdTransfWarping3d: Invalid rigid joint offset vector for node J\n"; + opserr << "Size must be 3\n"; + nodeJOffset.Zero(); + } + else + nodeJOffset = rigJntOffsetJ; + + //opserr << "nodeIOffset:" << nodeIOffset; + //opserr << "nodeJOffset:" << nodeJOffset; + + // temporary + if (nodeIOffset.Norm() != 0 || nodeJOffset.Norm() != 0) + { + opserr << "CorotCrdTransfWarping3d::CorotCrdTransfWarping3d: rigid joint zones not implemented yet\n"; + opserr << "Using zero values\n"; + nodeIOffset.Zero(); + nodeJOffset.Zero(); + } + + // Permutation matrix (to renumber basic dof's) + + // 0 1 2 3 4 5 6 + // + // Tp= [0 0 0 0 0 0 1; 0 + // 0 1 0 0 0 0 0; 1 + // 0 0 0 0 1 0 0; 2 + // 0 0 -1 0 0 0 0; 3 + // 0 0 0 0 0 -1 0; 4 + // -1 0 0 1 0 0 0]; 5 + + // using static matrix (one constant matrix for all objects) + + if (Tp(0, 6) == 0) // initialize only once + { + Tp(0, 6) = 1; + Tp(1, 1) = 1; + Tp(2, 4) = 1; + Tp(3, 2) = -1; + Tp(4, 5) = -1; + Tp(5, 0) = -1; + Tp(5, 3) = 1; + } + + //opserr << "Tp: " << Tp; + +} + + +// constructor: +// invoked by a FEM_ObjectBroker, recvSelf() needs to be invoked on this object. +CorotCrdTransfWarping3d::CorotCrdTransfWarping3d(): +CrdTransf(0, CRDTR_TAG_CorotCrdTransfWarping3d), +vAxis(3), nodeIOffset(3), nodeJOffset(3), xAxis(3), +nodeIPtr(0), nodeJPtr(0), R0(3,3), L(0), Ln(0), +alphaIq(4), alphaJq(4), +alphaIqcommit(4), alphaJqcommit(4), alphaI(3), alphaJ(3), +ulcommit(9), ul(9), ulpr(9), +nodeIInitialDisp(0), nodeJInitialDisp(0), initialDispChecked(false) +{ + // Permutation matrix (to renumber basic dof's) + + // 0 1 2 3 4 5 6 + // + // Tp= [0 0 0 0 0 0 1; 0 + // 0 1 0 0 0 0 0; 1 + // 0 0 0 0 1 0 0; 2 + // 0 0 -1 0 0 0 0; 3 + // 0 0 0 0 0 -1 0; 4 + // -1 0 0 1 0 0 0]; 5 + + // using static matrix (one constant matrix for all objects) + + if (Tp(0, 6) == 0) // initialize only once + { + Tp(0, 6) = 1; + Tp(1, 1) = 1; + Tp(2, 4) = 1; + Tp(3, 2) = -1; + Tp(4, 5) = -1; + Tp(5, 0) = -1; + Tp(5, 3) = 1; + } +} + + +// destructor: +CorotCrdTransfWarping3d::~CorotCrdTransfWarping3d() +{ + if (nodeIInitialDisp != 0) + delete [] nodeIInitialDisp; + if (nodeJInitialDisp != 0) + delete [] nodeJInitialDisp; +} + + +int +CorotCrdTransfWarping3d::commitState(void) +{ + ulcommit = ul; + alphaIqcommit = alphaIq; + alphaJqcommit = alphaJq; + + return 0; +} + + +int +CorotCrdTransfWarping3d::revertToLastCommit(void) +{ + // determine global displacement increments from last iteration + const Vector &dispI = nodeIPtr->getTrialDisp(); + const Vector &dispJ = nodeJPtr->getTrialDisp(); + + for (int k = 0; k < 3; k++) { + alphaI(k) = dispI(k+3); + alphaJ(k) = dispJ(k+3); + } + + if (nodeIInitialDisp != 0) { + for (int j=0; j<3; j++) + alphaI(j) -= nodeIInitialDisp[j+3]; + } + + if (nodeJInitialDisp != 0) { + for (int j=0; j<3; j++) + alphaJ(j) -= nodeJInitialDisp[j+3]; + } + + ul = ulcommit; + alphaIq = alphaIqcommit; + alphaJq = alphaJqcommit; + + this->update(); + + return 0; +} + + +int +CorotCrdTransfWarping3d::revertToStart(void) +{ + ul.Zero(); + alphaIq = this->getQuaternionFromRotMatrix(R0); // pseudo-vector for node 1 + alphaJq = this->getQuaternionFromRotMatrix(R0); // pseudo-vector for node J + + alphaI.Zero(); + alphaJ.Zero(); + + this->update(); + return 0; +} + + +int +CorotCrdTransfWarping3d::initialize(Node *nodeIPointer, Node *nodeJPointer) +{ + int error; + + nodeIPtr = nodeIPointer; + nodeJPtr = nodeJPointer; + + if ((!nodeIPtr) || (!nodeJPtr)) + { + opserr << "\nCorotCrdTransfWarping3d::initialize"; + opserr << "\ninvalid pointers to the element nodes\n"; + return -1; + } + + // see if there is some initial displacements at nodes + if (initialDispChecked == false) { + const Vector &nodeIDisp = nodeIPtr->getDisp(); + const Vector &nodeJDisp = nodeJPtr->getDisp(); + for (int i=0; i<7; i++) + if (nodeIDisp(i) != 0.0) { + nodeIInitialDisp = new double [7]; + for (int j=0; j<7; j++) + nodeIInitialDisp[j] = nodeIDisp(j); + i = 7; + } + + for (int j=0; j<7; j++) + if (nodeJDisp(j) != 0.0) { + nodeJInitialDisp = new double [7]; + for (int i=0; i<7; i++) + nodeJInitialDisp[i] = nodeJDisp(i); + j = 7; + } + initialDispChecked = true; + } + + static Vector XAxis(3); + static Vector YAxis(3); + static Vector ZAxis(3); + + // get 3by3 rotation matrix + if ((error = this->getLocalAxes(XAxis, YAxis, ZAxis))) + return error; + alphaIq = this->getQuaternionFromRotMatrix(R0); // pseudo-vector for node I + alphaJq = this->getQuaternionFromRotMatrix(R0); // pseudo-vector for node J + return 0; +} + + +int +CorotCrdTransfWarping3d::update(void) +{ + int i, j, k; + + /********* OLD REMO - REPLACED BELOW TO FIX BUG *************** + // determine global displacement increments from last iteration + const Vector &dispIncrI = nodeIPtr->getIncrDeltaDisp(); + const Vector &dispIncrJ = nodeJPtr->getIncrDeltaDisp(); + + // get the iterative spins dAlphaI and dAlphaJ + // (rotational displacement increments at both nodes) + + static Vector dAlphaI(3); + static Vector dAlphaJ(3); + + + for (k = 0; k < 3; k++) + { + dAlphaI(k) = dispIncrI(k+3); + dAlphaJ(k) = dispIncrJ(k+3); + } + **************************************************************/ + + // determine global displacement increments from last iteration + static Vector dispI(7); + static Vector dispJ(7); + dispI = nodeIPtr->getTrialDisp(); + dispJ = nodeJPtr->getTrialDisp(); + + if (nodeIInitialDisp != 0) { + for (int j=0; j<7; j++) + dispI(j) -= nodeIInitialDisp[j]; + } + + if (nodeJInitialDisp != 0) { + for (int j=0; j<7; j++) + dispJ(j) -= nodeJInitialDisp[j]; + } + + // get the iterative spins dAlphaI and dAlphaJ + // (rotational displacement increments at both nodes) + + static Vector dAlphaI(3); + static Vector dAlphaJ(3); + + for (k = 0; k < 3; k++) { + dAlphaI(k) = dispI(k+3) - alphaI(k); + dAlphaJ(k) = dispJ(k+3) - alphaJ(k); + alphaI(k) = dispI(k+3); + alphaJ(k) = dispJ(k+3); + } + + /************** END OF REPLACEMENT **************************/ + + // update the nodal triads TI and RJ using quaternions + static Vector dAlphaIq(4); + static Vector dAlphaJq(4); + + dAlphaIq = this->getQuaternionFromPseudoRotVector (dAlphaI); + dAlphaJq = this->getQuaternionFromPseudoRotVector (dAlphaJ); + + alphaIq = this->quaternionProduct (alphaIq, dAlphaIq); + alphaJq = this->quaternionProduct (alphaJq, dAlphaJq); + + RI = this->getRotationMatrixFromQuaternion (alphaIq); + RJ = this->getRotationMatrixFromQuaternion (alphaJq); + + // compute the mean nodal triad + static Matrix dRgamma(3,3); + static Vector gammaq(4); + static Vector gammaw(3); + + dRgamma.Zero(); + + //dRgamma = RJ * RIt; + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + for (k = 0; k < 3; k++) + dRgamma(i,j) += RJ(i,k) * RI(j,k); + + gammaq = this->getQuaternionFromRotMatrix(dRgamma); // pseudo-vector for node J + gammaw = this->getTangScaledPseudoVectorFromQuaternion(gammaq); + + + dRgamma = this->getRotMatrixFromTangScaledPseudoVector(gammaw/2); + + Rbar.addMatrixProduct(0.0, dRgamma, RI, 1.0); + + // compute the base vectors e1, e2, e3 + static Vector e1(3); + static Vector e2(3); + static Vector e3(3); + + // relative translation displacements + static Vector dJI(3); + for (int kk = 0; kk < 3; kk++){ + dJI(kk) = dispJ(kk) - dispI(kk); + } + // element projection + static Vector xJI(3); + xJI = nodeJPtr->getCrds() - nodeIPtr->getCrds(); + + if (nodeIInitialDisp != 0) { + xJI(0) -= nodeIInitialDisp[0]; + xJI(1) -= nodeIInitialDisp[1]; + xJI(2) -= nodeIInitialDisp[2]; + } + + if (nodeJInitialDisp != 0) { + xJI(0) += nodeJInitialDisp[0]; + xJI(1) += nodeJInitialDisp[1]; + xJI(2) += nodeJInitialDisp[2]; + } + + static Vector dx(3); + // dx = xJI + dJI; + dx = xJI; + dx.addVector (1.0, dJI, 1.0); + + // calculate the deformed element length + Ln = dx.Norm(); + + + if (Ln == 0.0) + { + opserr << "\nCorotCrdTransfWarping3d::update: 0 deformed length\n"; + return -2; + } + + // compute the base vector e1 + e1 = dx/Ln; + + // 'rotate' the mean rotation matrix Rbar on to e1 to + // obtain e2 and e3 (using the 'mid-point' procedure) + static Vector r1(3); + static Vector r2(3); + static Vector r3(3); + + for (k = 0; k < 3; k ++) + { + r1(k) = Rbar(k,0); + r2(k) = Rbar(k,1); + r3(k) = Rbar(k,2); + } + + // e2 = r2 - (e1 + r1)*((r2^ e1)*0.5); + // e3 = r3 - (e1 + r1)*((r3^ e1)*0.5); + + static Vector tmp(3); + tmp = e1; + tmp += r1; + + e2=tmp; + e3=tmp; + + e2 *= (r2^e1)*0.5; + e2.addVector(-1.0, r2, 1.0); + + // e2 = r2 - (e1 + r1)*((r2^ e1)*0.5); + + e3 *= (r3^e1)*0.5; + e3.addVector(-1.0, r3, 1.0); + + // compute the basic rotations + static Vector rI1(3), rI2(3), rI3(3); + static Vector rJ1(3), rJ2(3), rJ3(3); + + for (k = 0; k < 3; k ++) + { + e(k,0) = e1(k); + e(k,1) = e2(k); + e(k,2) = e3(k); + + rI1(k) = RI(k,0); + rI2(k) = RI(k,1); + rI3(k) = RI(k,2); + + rJ1(k) = RJ(k,0); + rJ2(k) = RJ(k,1); + rJ3(k) = RJ(k,2); + } + + // compute the basic displacements + ulpr = ul; + ul(0) = asin (((rI2^ e3) - (rI3^ e2))*0.5); + ul(1) = asin (((rI1^ e2) - (rI2^ e1))*0.5); + ul(2) = asin (((rI1^ e3) - (rI3^ e1))*0.5); + ul(3) = dispI(6); // warping degree of freedom is constant during transformation + ul(4) = asin (((rJ2^ e3) - (rJ3^ e2))*0.5); + ul(5) = asin (((rJ1^ e2) - (rJ2^ e1))*0.5); + ul(6) = asin (((rJ1^ e3) - (rJ3^ e1))*0.5); + ul(7) = dispJ(6); + // ul = Ln - L; + // ul(6) = 2 * ((xJI + dJI/2)^ dJI) / (Ln + L); //mid-point formula + xJI.addVector(1.0, dJI, 0.5); + ul(8) = 2 * (xJI ^ dJI) / (Ln + L); //mid-point formula + // compute the transformation matrix + this->compTransfMatrixBasicGlobal(); + + return 0; +} + + +void +CorotCrdTransfWarping3d::compTransfMatrixBasicGlobal(void) +{ + // extract columns of rotation matrices + int i, j, k; + + //opserr << "comprTransfMatrixBasicGlobal: *****************************\n"; + static Vector r1(3), r2(3), r3(3); + static Vector e1(3), e2(3), e3(3); + static Vector rI1(3), rI2(3), rI3(3); + static Vector rJ1(3), rJ2(3), rJ3(3); + + + for (k = 0; k < 3; k ++) + { + r1(k) = Rbar(k,0); + r2(k) = Rbar(k,1); + r3(k) = Rbar(k,2); + + e1(k) = e(k,0); + e2(k) = e(k,1); + e3(k) = e(k,2); + + rI1(k) = RI(k,0); + rI2(k) = RI(k,1); + rI3(k) = RI(k,2); + + rJ1(k) = RJ(k,0); + rJ2(k) = RJ(k,1); + rJ3(k) = RJ(k,2); + } + + // compute the transformation matrix from the basic to the + // global system + static Matrix I(3,3); + + // A = (1/Ln)*(I - e1*e1'); + for (i = 0; i < 3; i++) + I(i,i) = 1; + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + A(i,j) = (I(i,j) - e1(i)*e1(j))/Ln; + + Lr2 = this->getLMatrix (r2); + Lr3 = this->getLMatrix (r3); + + static Matrix Sr1(3,3), Sr2(3,3), Sr3(3,3); + static Vector Se(3), At(3); + + // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', 0 O', O', 0]'; + // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', 0, -(A*rI2)', O', 0]'; + // T3 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', 0, -(A*rI3)', O', 0]'; + // T4 = [O', O', 1, O', O', 0]; + // T5 = [ O', O', 0 O', (-S(rJ3)*e2 + S(rJ2)*e3)', 0]'; + // T6 = [(A*rJ2)', O', 0, -(A*rJ2)', (-S(rJ2)*e1 + S(rJ1)*e2)', 0]'; + // T7 = [(A*rJ3)', O', 0, -(A*rJ3)', (-S(rJ3)*e1 + S(rJ1)*e3)', 0]'; + // T8 = [O', O', 0, O', O', 1]; + + T.Zero(); + + Sr1 = this->getSkewSymMatrix(rI1); + Sr2 = this->getSkewSymMatrix(rI2); + Sr3 = this->getSkewSymMatrix(rI3); + + // T1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', 0 O', O', 0]'; + + Se.addMatrixVector(0.0, Sr3, e2, -1.0); // (-S(rI3)*e2 + S(rI2)*e3) + Se.addMatrixVector(1.0, Sr2, e3, 1.0); + + for (i = 0; i < 3; i++) + T(0,i+3) = Se(i); + + // T2 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', 0, -(A*rI2)', O', 0]'; + + At.addMatrixVector(0.0, A, rI2, 1.0); + + Se.addMatrixVector(0.0, Sr2, e1, -1.0); // (-S(rI2)*e1 + S(rI1)*e2)' + Se.addMatrixVector(1.0, Sr1, e2, 1.0); + + for (i = 0; i < 3; i++) + { + T(1,i ) = At(i); + T(1,i+3) = Se(i); + T(1,i+7) = -At(i); + } + + // T3 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', 0, -(A*rI3)', O', 0]'; + + At.addMatrixVector(0.0, A, rI3, 1.0); + + Se.addMatrixVector(0.0, Sr3, e1, -1.0); // (-S(rI3)*e1 + S(rI1)*e3) + Se.addMatrixVector(1.0, Sr1, e3, 1.0); + + for (i = 0; i < 3; i++) + { + T(2,i ) = At(i); + T(2,i+3) = Se(i); + T(2,i+7) = -At(i); + } + + Sr1 = this->getSkewSymMatrix(rJ1); + Sr2 = this->getSkewSymMatrix(rJ2); + Sr3 = this->getSkewSymMatrix(rJ3); + + // T5 = [ O', O', 0 O', (-S(rJ3)*e2 + S(rJ2)*e3)', 0]'; + + Se.addMatrixVector(0.0, Sr3, e2, -1.0); // -S(rJ3)*e2 + S(rJ2)*e3 + Se.addMatrixVector(1.0, Sr2, e3, 1.0); + + for (i = 0; i < 3; i++) + T(4,i+10) = Se(i); + + // T6 = [(A*rJ2)', O', 0, -(A*rJ2)', (-S(rJ2)*e1 + S(rJ1)*e2)', 0]'; + + At.addMatrixVector(0.0, A, rJ2, 1.0); + + Se.addMatrixVector(0.0, Sr2, e1, -1.0); // (-S(rJ2)*e1 + S(rJ1)*e2) + Se.addMatrixVector(1.0, Sr1, e2, 1.0); + + for (i = 0; i < 3; i++) + { + T(5,i ) = At(i); + T(5,i+7) = -At(i); + T(5,i+10) = Se(i); + } + + // T7 = [(A*rJ3)', O', 0, -(A*rJ3)', (-S(rJ3)*e1 + S(rJ1)*e3)', 0]'; + + At.addMatrixVector(0.0, A, rJ3, 1.0); + + Se.addMatrixVector(0.0, Sr3, e1, -1.0); // (-S(rJ3)*e1 + S(rJ1)*e3) + Se.addMatrixVector(1.0, Sr1, e3, 1.0); + + for (i = 0; i < 3; i++) + { + T(6,i ) = At(i); + T(6,i+7) = -At(i); + T(6,i+10) = Se(i); + } + + // setup tranformation matrix + static Vector Lr(14); + + // T(:,1) += Lr3*rI2 - Lr2*rI3; + // T(:,2) += Lr2*rI1; + // T(:,3) += Lr3*rI1 ; + + // T(:,4) += Lr3*rJ2 - Lr2*rJ3; + // T(:,5) += Lr2*rJ1 ; // ?????? check sign + // T(:,6) += Lr3*rJ1 ; // ?????? check sign + + Lr.addMatrixVector(0.0, Lr3, rI2, 1.0); // T(:,1) += Lr3*rI2 - Lr2*rI3 + Lr.addMatrixVector(1.0, Lr2, rI3, -1.0); + + for (i = 0; i < 14; i++) + T(0,i) += Lr(i); + + Lr.addMatrixVector(0.0, Lr2, rI1, 1.0); // T(:,2) += Lr2*rI1 + + for (i = 0; i < 14; i++) + T(1,i) += Lr(i); + + Lr.addMatrixVector(0.0, Lr3, rI1, 1.0); // T(:,3) += Lr3*rI1 + + for (i = 0; i < 14; i++) + T(2,i) += Lr(i); + + Lr.addMatrixVector(0.0, Lr3, rJ2, 1.0); // T(:,5) += Lr3*rJ2 - Lr2*rJ3; + Lr.addMatrixVector(1.0, Lr2, rJ3, -1.0); + + T(3,6) = 1.0; + for (i = 0; i < 14; i++) + T(4,i) += Lr(i); + + Lr.addMatrixVector(0.0, Lr2, rJ1, 1.0); // T(:,6) += Lr2*rJ1 + + for (i = 0; i < 14; i++) + T(5,i) += Lr(i); + + Lr.addMatrixVector(0.0, Lr3, rJ1, 1.0); // T(:,7) += Lr3*rJ1 + + for (i = 0; i < 14; i++) + T(6,i) += Lr(i); + T(7,13) = 1.0; + + double c; + for (j = 0; j < 3; j++) + { + c = 2 * cos(ul(j)); + + for (i = 0; i < 14; i++) + T(j,i) /= c; + } + + for (j = 4; j < 7; j++) + { + c = 2 * cos(ul(j)); + + for (i = 0; i < 14; i++) + T(j,i) /= c; + } + // T(:,9) = [-e1' O' e1' O']'; + for (i = 0; i < 3; i++) + { + T(8,i ) = -e1(i); + T(8,i+7) = e1(i); + } + +} + + +void +CorotCrdTransfWarping3d::compTransfMatrixBasicGlobalNew(void) +{ + // extract columns of rotation matrices + int i, j, k; + + //opserr << "comprTransfMatrixBasicGlobal: *****************************\n"; + static Vector r1(3), r2(3), r3(3); + static Vector e1(3), e2(3), e3(3); + static Vector rI1(3), rI2(3), rI3(3); + static Vector rJ1(3), rJ2(3), rJ3(3); + + for (k = 0; k < 3; k ++) + { + r1(k) = Rbar(k,0); + r2(k) = Rbar(k,1); + r3(k) = Rbar(k,2); + + e1(k) = e(k,0); + e2(k) = e(k,1); + e3(k) = e(k,2); + + rI1(k) = RI(k,0); + rI2(k) = RI(k,1); + rI3(k) = RI(k,2); + + rJ1(k) = RJ(k,0); + rJ2(k) = RJ(k,1); + rJ3(k) = RJ(k,2); + } + + // compute the transformation matrix from the basic to the + // global system + static Matrix I(3,3); + + // A = (1/Ln)*(I - e1*e1'); + for (i = 0; i < 3; i++) + I(i,i) = 1; + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + A(i,j) = (I(i,j) - e1(i)*e1(j))/Ln; + + + /* + opserr << "r1: " << r1; + opserr << "r2: " << r2; + opserr << "r3: " << r3; + opserr << "e1: " << e1; + opserr << "e2: " << e2; + opserr << "e3: " << e3; + opserr << "rI1: " << rI1; + opserr << "rI2: " << rI2; + opserr << "rI3: " << rI3; + opserr << "rJ1: " << rJ1; + opserr << "rJ2: " << rJ2; + opserr << "rJ3: " << rJ3; + opserr << "A: " << A; + */ + + Lr2 = this->getLMatrix (r2); + Lr3 = this->getLMatrix (r3); + + // opserr << "Lr2: " << Lr2; + // opserr << "Lr3: " << Lr3; + + static Matrix Sr1(3,3), Sr2(3,3), Sr3(3,3); + static Vector Se(3), At(3); + + + // O = zeros(3,1); + // hI1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; + // hI2 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', -(A*rI3)', O']'; + // hI3 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; + // hJ1 = [ O', O', O', (-S(rJ3)*e2 + S(rJ2)*e3)']'; + // hJ2 = [(A*rJ3)', O', -(A*rJ3)', (-S(rJ3)*e1 + S(rJ1)*e3)']'; + // hJ3 = [(A*rJ2)', O', -(A*rJ2)', (-S(rJ2)*e1 + S(rJ1)*e2)']'; + + static Vector hI1(12); + static Vector hI2(12); + static Vector hI3(12); + static Vector hJ1(12); + static Vector hJ2(12); + static Vector hJ3(12); + + Sr1 = this->getSkewSymMatrix(rI1); + Sr2 = this->getSkewSymMatrix(rI2); + Sr3 = this->getSkewSymMatrix(rI3); + + // hI1 = [ O', (-S(rI3)*e2 + S(rI2)*e3)', O', O']'; + Se.addMatrixVector(0.0, Sr3, e2, -1.0); // (-S(rI3)*e2 + S(rI2)*e3) + Se.addMatrixVector(1.0, Sr2, e3, 1.0); + for (i=0; i<3; i++) + hI1(i+3) = Se(i); + + // hI2 = [(A*rI3)', (-S(rI3)*e1 + S(rI1)*e3)', -(A*rI3)', O']'; + At.addMatrixVector(0.0, A, rI3, 1.0); + Se.addMatrixVector(0.0, Sr3, e1, -1.0); // (-S(rI3)*e1 + S(rI1)*e3) + Se.addMatrixVector(1.0, Sr1, e3, 1.0); + + for (i = 0; i < 3; i++) { + hI2(i ) = At(i); + hI2(i+3) = Se(i); + hI2(i+6) = -At(i); + } + + // hI3 = [(A*rI2)', (-S(rI2)*e1 + S(rI1)*e2)', -(A*rI2)', O']'; + At.addMatrixVector(0.0, A, rI2, 1.0); + Se.addMatrixVector(0.0, Sr2, e1, -1.0); // (-S(rI2)*e1 + S(rI1)*e2)' + Se.addMatrixVector(1.0, Sr1, e2, 1.0); + + for (i = 0; i < 3; i++) { + hI3(i ) = At(i); + hI3(i+3) = Se(i); + hI3(i+6) = -At(i); + } + + Sr1 = this->getSkewSymMatrix(rJ1); + Sr2 = this->getSkewSymMatrix(rJ2); + Sr3 = this->getSkewSymMatrix(rJ3); + + // hJ1 = [ O', O', O', (-S(rJ3)*e2 + S(rJ2)*e3)']'; + Se.addMatrixVector(0.0, Sr3, e2, -1.0); // -S(rJ3)*e2 + S(rJ2)*e3 + Se.addMatrixVector(1.0, Sr2, e3, 1.0); + for (i = 0; i < 3; i++) + hJ1(i+9) = Se(i); + + + // hJ2 = [(A*rJ3)', O', -(A*rJ3)', (-S(rJ3)*e1 + S(rJ1)*e3)']'; + At.addMatrixVector(0.0, A, rJ3, 1.0); + Se.addMatrixVector(0.0, Sr3, e1, -1.0); // (-S(rJ3)*e1 + S(rJ1)*e3) + Se.addMatrixVector(1.0, Sr1, e3, 1.0); + + for (i = 0; i < 3; i++) { + hJ2(i ) = At(i); + hJ2(i+6) = -At(i); + hJ2(i+9) = Se(i); + } + + // hJ3 = [(A*rJ2)', O', -(A*rJ2)', (-S(rJ2)*e1 + S(rJ1)*e2)']'; + At.addMatrixVector(0.0, A, rJ2, 1.0); + Se.addMatrixVector(0.0, Sr2, e1, -1.0); // (-S(rJ2)*e1 + S(rJ1)*e2) + Se.addMatrixVector(1.0, Sr1, e2, 1.0); + + for (i = 0; i < 3; i++) { + hJ3(i ) = At(i); + hJ3(i+6) = -At(i); + hJ3(i+9) = Se(i); + } + + /* + opserr << "hI1: " << hI1; + opserr << "hI2: " << hI2; + opserr << "hI3: " << hI3; + opserr << "hj1: " << hJ1; + opserr << "hj2: " << hJ2; + opserr << "hj3: " << hJ3; + */ + + // f1 = [-e1' O' e1' O']; + // f2 = ( Lr2*rI1 + hI3)'./(2*(cos(thetalI(3)))); + // f3 = ( Lr2*rJ1 + hJ3)'./(2*(cos(thetalJ(3)))); + // f4 = (-Lr3*rI1 - hI2)'./(2*(cos(thetalI(2)))); + // f5 = (-Lr3*rJ1 - hJ2)'./(2*(cos(thetalJ(2)))); + // f6I = ( Lr3*rI2 - Lr2*rI3 + hI1)'./(2*(cos(thetalI(1)))); + // f6J = ( Lr3*rJ2 - Lr2*rJ3 + hJ1)'./(2*(cos(thetalJ(1)))); + + // F = [f1; + // f2; + // f3; + // f4; + // f5; + // f6J-f6I]; + + // T = F' + T.Zero(); + static Vector Lr(12); + + // f1 = [-e1' O' e1' O']; + for (i=0; i<3; i++) { + T(i ,0) = -e1(i); + T(i+3,0) = e1(i); + } + + static Vector thetaI(3); + static Vector thetaJ(3); + + + thetaI(0) = ul(0); + thetaI(1) = -ul(2); + thetaI(2) = ul(1); + + thetaJ(0) = ul(3); + thetaJ(1) = -ul(5); + thetaJ(2) = ul(4); + + + // opserr << "thetaI: " << thetaI; + //opserr << "thetaJ: " << thetaJ; + + double c; + + // f2 = ( Lr2*rI1 + hI3)'./(2*(cos(thetalI(3)))); + Lr.addMatrixVector(0.0, Lr2, rI1, 1.0); + Lr += hI3; + c = 1.0/(2.0*cos(thetaI(2))); + for (i=0; i<12; i++) + T(1,i) = Lr(i)*c; + + // f3 = ( Lr2*rJ1 + hJ3)'./(2*(cos(thetalJ(3)))); + Lr.addMatrixVector(0.0, Lr2, rJ1, 1.0); + Lr += hJ3; + c = 1.0/(2.0*cos(thetaJ(2))); + for (i=0; i<12; i++) + T(2,i) = Lr(i)*c; + + // f4 = (-Lr3*rI1 - hI2)'./(2*(cos(thetalI(2)))); + Lr.addMatrixVector(0.0, Lr3, rI1, -1.0); + Lr -= hI2; + c = 1.0/(2.0*cos(thetaI(1))); + for (i=0; i<12; i++) + T(3,i) = Lr(i)*c; + + // f5 = (-Lr3*rJ1 - hJ2)'./(2*(cos(thetalJ(2)))); + Lr.addMatrixVector(0.0, Lr3, rJ1, -1.0); + Lr -= hJ2; + c = 1.0/(2.0*cos(thetaJ(1))); + for (i=0; i<12; i++) + T(4,i) = Lr(i)*c; + + // f6I = ( Lr3*rI2 - Lr2*rI3 + hI1)'./(2*(cos(thetalI(1)))); + Lr.addMatrixVector(0.0, Lr3, rI2, 1.0); + Lr.addMatrixVector(1.0, Lr2, rI3, -1.0); + Lr += hI1; + c = 1.0/(2.0*cos(thetaI(0))); + for (i=0; i<12; i++) + T(5,i) = Lr(i)*c; + + // f6J = ( Lr3*rJ2 - Lr2*rJ3 + hJ1)'./(2*(cos(thetalJ(1)))); + Lr.addMatrixVector(0.0, Lr3, rJ2, 1.0); + Lr.addMatrixVector(1.0, Lr2, rJ3, -1.0); + Lr += hJ1; + c = 1.0/(2.0*cos(thetaI(0))); + for (i=0; i<12; i++) + T(6,i) -= Lr(i)*c; +} + + +void +CorotCrdTransfWarping3d::compTransfMatrixLocalGlobal(Matrix &Tlg) +{ + // setup transformation matrix from local to global + Tlg.Zero(); + + Tlg(0,0) = Tlg(3,3) = Tlg(6,6) = Tlg(9,9) = R0(0,0); + Tlg(0,1) = Tlg(3,4) = Tlg(6,7) = Tlg(9,10) = R0(1,0); + Tlg(0,2) = Tlg(3,5) = Tlg(6,8) = Tlg(9,11) = R0(2,0); + Tlg(1,0) = Tlg(4,3) = Tlg(7,6) = Tlg(10,9) = R0(0,1); + Tlg(1,1) = Tlg(4,4) = Tlg(7,7) = Tlg(10,10) = R0(1,1); + Tlg(1,2) = Tlg(4,5) = Tlg(7,8) = Tlg(10,11) = R0(2,1); + Tlg(2,0) = Tlg(5,3) = Tlg(8,6) = Tlg(11,9) = R0(0,2); + Tlg(2,1) = Tlg(5,4) = Tlg(8,7) = Tlg(11,10) = R0(1,2); + Tlg(2,2) = Tlg(5,5) = Tlg(8,8) = Tlg(11,11) = R0(2,2); +} + + +void +CorotCrdTransfWarping3d::compTransfMatrixBasicLocal(Matrix &Tbl) +{ + // setup transformation matrix from basic to local + Tbl.Zero(); + + // first get transformation matrix from basic to global + static Matrix Tbg(6, 12); + Tbg.addMatrixProduct(0.0, Tp, T, 1.0); + + // get inverse of transformation matrix from local to global + this->compTransfMatrixLocalGlobal(Tlg); + // Tlg.Invert(TlgInv); + TlgInv.addMatrixTranspose(0.0, Tlg, 1.0); // for square rot-matrix: Tlg^-1 = Tlg' + + // finally get transformation matrix from basic to local + Tbl.addMatrixProduct(0.0, Tbg, TlgInv, 1.0); +} + + +const Vector & +CorotCrdTransfWarping3d::getBasicTrialDisp (void) +{ + static Vector ub(9); + //basic system equals to local system + ub=ul; + return ub; +} + + +const Vector & +CorotCrdTransfWarping3d::getBasicIncrDeltaDisp (void) +{ + static Vector dub(9); + static Vector dul(9); + + dul = ul; + dul.addVector (1.0, ulpr, -1.0); + + dub=dul; + + return dub; +} + + +const Vector & +CorotCrdTransfWarping3d::getBasicIncrDisp(void) +{ + static Vector Dub(9); + static Vector Dul(9); + + // Dul = ul - ulcommit; + Dul = ul; + Dul.addVector (1.0, ulcommit, -1.0); + + Dub=Dul; + return Dub; +} + + +const Vector & +CorotCrdTransfWarping3d::getBasicTrialVel(void) +{ + opserr << "ERROR CorotCrdTransfWarping3d::getBasicTrialVel()" + << " - has not been implemented yet." << endln; + + static Vector dummy(1); + return dummy; +} + + +const Vector & +CorotCrdTransfWarping3d::getBasicTrialAccel(void) +{ + opserr << "ERROR CorotCrdTransfWarping3d::getBasicTrialAccel()" + << " - has not been implemented yet." << endln; + + static Vector dummy(1); + return dummy; +} + + +const Vector & +CorotCrdTransfWarping3d::getGlobalResistingForce(const Vector &pb, const Vector &unifLoad) +{ + this->update(); + static Vector pl(9); + // do not transform, basic equals to local + pl=pb; + + // check distributed load is zero (not implemented yet) + + // transform resisting forces from local to global coordinates + static Vector pg(14); + pg.addMatrixTransposeVector(0.0, T, pl, 1.0); // pg = T ^ pl; residua + + return pg; +} + + +const Matrix & +CorotCrdTransfWarping3d::getGlobalStiffMatrix (const Matrix &kb, const Vector &pb) +{ + + this->update(); + + int i, j, k; + // transform tangent stiffness matrix from the basic system to local coordinates + static Matrix kl(9,9); + // do not transform, basic equals to local + kl=kb; + // transform resisting forces from the basic system to local coordinates + static Vector pl(9); + pl=pb; + + // transform tangent stiffness matrix from local to global coordinates + static Matrix kg(14,14); + kg.Zero(); + static Matrix kgConvert(12,12); + kgConvert.Zero(); + // compute the tangent stiffness matrix in global coordinates + // first compute Kt1 + kg.addMatrixTripleProduct(0.0, T, kl, 1.0); + // second compute ktsigma + static Vector m(6); + for (i = 0; i < 3; i++) + m(i) = pl(i)/(2*cos(ul(i))); + + for (i = 3; i < 6; i++) + m(i) = pl(i+1)/(2*cos(ul(i+1))); + // compute the basic rotations + + static Vector e1(3), e2(3), e3(3); + static Vector r1(3), r2(3), r3(3); + static Vector rI1(3), rI2(3), rI3(3); + static Vector rJ1(3), rJ2(3), rJ3(3); + + for (k = 0; k < 3; k ++) + { + e1(k) = e(k,0); + e2(k) = e(k,1); + e3(k) = e(k,2); + + r1(k) = Rbar(k,0); + r2(k) = Rbar(k,1); + r3(k) = Rbar(k,2); + + rI1(k) = RI(k,0); + rI2(k) = RI(k,1); + rI3(k) = RI(k,2); + + rJ1(k) = RJ(k,0); + rJ2(k) = RJ(k,1); + rJ3(k) = RJ(k,2); + } + + // ks = t'*kl*t + ks1 + t * diag (m .* tan(thetal))*t' + ... + // m(4)*(ks2r2t3_u3 + ks2r3u2_t2) + ... + // m(2)*ks2r2t1 + m(3)*ks2r3t1 + ... + // m(5)*ks2r2u1 + m(6)*ks2r3u1 + ... + // ks3 + ks3' + ks4 + ks5; + + static Matrix Se1(3,3), Se2(3,3), Se3(3,3); + static Matrix SrI1(3,3), SrI2(3,3), SrI3(3,3); + static Matrix SrJ1(3,3), SrJ2(3,3), SrJ3(3,3); + static Matrix LLr2(12,3),LLr3(12,3); + LLr2.Zero(); + LLr3.Zero(); + for (i=0; i<6; i++) + { + for (j=0; j<3; j++) + { + LLr2(i,j)=Lr2(i,j); + LLr3(i,j)=Lr3(i,j); + } + } + for (i=6; i<12; i++) + { + for (j=0; j<3; j++) + { + LLr2(i,j)=Lr2(i+1,j); + LLr3(i,j)=Lr3(i+1,j); + } + } + + + Se1 = this->getSkewSymMatrix(e1); + Se2 = this->getSkewSymMatrix(e2); + Se3 = this->getSkewSymMatrix(e3); + + SrJ1 = this->getSkewSymMatrix(rJ1); + SrJ2 = this->getSkewSymMatrix(rJ2); + SrJ3 = this->getSkewSymMatrix(rJ3); + + SrI1 = this->getSkewSymMatrix(rI1); + SrI2 = this->getSkewSymMatrix(rI2); + SrI3 = this->getSkewSymMatrix(rI3); + + // ksigma1 ------------------------------- + // ks1_11 = a*pl(6); + // ks1 = [ ks1_11 o -ks1_11 o; + // o o o o; + // -ks1_11 o ks1_11 o; + // o o o o]; + + double factor; + + kgConvert.Assemble(A, 0, 0, pl(8)); + kgConvert.Assemble(A, 0, 6, -pl(8)); + kgConvert.Assemble(A, 6, 0, -pl(8)); + kgConvert.Assemble(A, 6, 6, pl(8)); + + + // ksigma3 ------------------------------- + // kbar2 = -Lr2*(m(3)*S(rI3) + m(1)*S(rI1)) + ... + // Lr3*(m(3)*S(rI2) - m(2)*S(rI1)) ; + + // kbar4 = Lr2*(m(3)*S(rJ3) - m(4)*S(rJ1)) - ... + // Lr3*(m(3)*S(rJ2) + m(5)*S(rJ1)); + + // ks3 = [o kbar2 o kbar4]; + + + static Matrix Sm(3,3); + static Matrix kbar(12,3); + + Sm.addMatrix(0.0, SrI3, m(3)); + Sm.addMatrix(1.0, SrI1, m(1)); + + kbar.addMatrixProduct(0.0, LLr2, Sm, -1.0); + + Sm.addMatrix(0.0, SrI2, m(3)); + Sm.addMatrix(1.0, SrI1, -m(2)); + + kbar.addMatrixProduct(1.0, LLr3, Sm, 1.0); + + kgConvert.Assemble(kbar, 0, 3, 1.0); + kgConvert.AssembleTranspose(kbar, 3, 0, 1.0); + + Sm.addMatrix(0.0, SrJ3, m(3)); + Sm.addMatrix(1.0, SrJ1, -m(4)); + + kbar.addMatrixProduct(0.0, LLr2, Sm, 1.0); + + Sm.addMatrix(0.0, SrJ2, m(3)); + Sm.addMatrix(1.0, SrJ1, m(5)); + + kbar.addMatrixProduct(1.0, LLr3, Sm, -1.0); + kgConvert.Assemble(kbar, 0, 9, 1.0); + kgConvert.AssembleTranspose(kbar, 9, 0, 1.0); + + + // Ksigma4 ------------------------------- + // Ks4_22 = m(3)*( S(e2)*S(rI3) - S(e3)*S(rI2)) + ... + // m(1)*(-S(e1)*S(rI2) + S(e2)*S(rI1)) + ... + // m(2)*(-S(e1)*S(rI3) + S(e3)*S(rI1)); + + // Ks4_44 = -m(3)*( S(e2)*S(rJ3) - S(e3)*S(rJ2)) + ... + // m(4)*(-S(e1)*S(rJ2) + S(e2)*S(rJ1)) + ... + // m(5)*(-S(e1)*S(rJ3) + S(e3)*S(rJ1)); + + // Ks4 = [ O O O O; + // O Ks4_22 O O; + // O O O O; + // O O O Ks4_44]; + + static Matrix ks33(3,3); + + ks33.addMatrixProduct(0.0, Se2, SrI3, m(3)); + ks33.addMatrixProduct(1.0, Se3, SrI2, -m(3)); + + ks33.addMatrixProduct(1.0, Se2, SrI1, m(1)); + ks33.addMatrixProduct(1.0, Se1, SrI2, -m(1)); + + ks33.addMatrixProduct(1.0, Se3, SrI1, m(2)); + ks33.addMatrixProduct(1.0, Se1, SrI3, -m(2)); + + kgConvert.Assemble(ks33, 3, 3, 1.0); + + ks33.addMatrixProduct(0.0, Se2, SrJ3, -m(3)); + ks33.addMatrixProduct(1.0, Se3, SrJ2, m(3)); + + ks33.addMatrixProduct(1.0, Se2, SrJ1, m(4)); + ks33.addMatrixProduct(1.0, Se1, SrJ2, -m(4)); + + ks33.addMatrixProduct(1.0, Se3, SrJ1, m(5)); + ks33.addMatrixProduct(1.0, Se1, SrJ3, -m(5)); + + kgConvert.Assemble(ks33, 9, 9, 1.0); + + + //opserr << "kg += ksigma4: " << kg; + + // Ksigma5 ------------------------------- + // + // Ks5 = [ Ks5_11 Ks5_12 -Ks5_11 Ks5_14; + // Ks5_12t O -Ks5_12t O; + // -Ks5_11 -Ks5_12 Ks5_11 -Ks5_14; + // Ks5_14t O -Ks5_14t O]; + + // v = (1/Ln)*(m(2)*rI2 + m(3)*rI3 + m(5)*rJ2 + m(6)*rJ3); + static Vector v(3); + v.addVector (0.0, rI2, m(1)); + v.addVector (1.0, rI3, m(2)); + v.addVector (1.0, rJ2, m(4)); + v.addVector (1.0, rJ3, m(5)); + + v /= Ln; + + //Ks5_11 = A*v*e1' + e1*v'*A + (e1'*v)*A; + static Matrix m33(3,3); + double e1tv = 0; // dot product e1. v + + for (i = 0; i < 3; i++) + e1tv += e1(i) * v(i); + + ks33.addMatrix (0.0, A, e1tv); + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + m33(i,j) = v(i)*e1(j); + + ks33.addMatrixProduct (1.0, A, m33, 1.0); + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + m33(i,j) = e1(i)*v(j); + + ks33.addMatrixProduct (1.0, m33, A, 1.0); + + kgConvert.Assemble(ks33, 0, 0, 1.0); + kgConvert.Assemble(ks33, 0, 6, -1.0); + kgConvert.Assemble(ks33, 6, 0, -1.0); + kgConvert.Assemble(ks33, 6, 6, 1.0); + + //Ks5_12 = -(m(2)*A*S(rI2) + m(3)*A*S(rI3)); + + ks33.addMatrixProduct(0.0, A, SrI2, -m(1)); + ks33.addMatrixProduct(1.0, A, SrI3, -m(2)); + + kgConvert.Assemble(ks33, 0, 3, 1.0); + kgConvert.Assemble(ks33, 6, 3, -1.0); + + kgConvert.AssembleTranspose(ks33, 3, 0, 1.0); + kgConvert.AssembleTranspose(ks33, 3, 6, -1.0); + + // Ks5_14 = -(m(5)*A*S(rJ2) + m(6)*A*S(rJ3)); + + ks33.addMatrixProduct(0.0, A, SrJ2, -m(4)); + ks33.addMatrixProduct(1.0, A, SrJ3, -m(5)); + + kgConvert.Assemble(ks33, 0, 9, 1.0); + kgConvert.Assemble(ks33, 6, 9, -1.0); + + kgConvert.AssembleTranspose(ks33, 9, 0, 1.0); + kgConvert.AssembleTranspose(ks33, 9, 6, -1.0); + + + //opserr << "kg += ksigma5: " << kg; + + // Ksigma ------------------------------- + static Vector rm(3); + + rm = rI3; + rm.addVector (1.0, rJ3, -1.0); + + kgConvert.addMatrix (1.0, this->getKs2Matrix(r2, rm), m(3)); + + rm = rJ2; + rm.addVector (1.0, rI2, -1.0); + kgConvert.addMatrix (1.0, this->getKs2Matrix(r3, rm), m(3)); + kgConvert.addMatrix (1.0, this->getKs2Matrix(r2, rI1), m(1)); + kgConvert.addMatrix (1.0, this->getKs2Matrix(r3, rI1), m(2)); + kgConvert.addMatrix (1.0, this->getKs2Matrix(r2, rJ1), m(4)); + kgConvert.addMatrix (1.0, this->getKs2Matrix(r3, rJ1), m(5)); + // T * diag (M .* tan(thetal))*T' + + static Vector ulg(6); + //ul(0),ul(1),ul(2),ul(4),ul(5),ul(6) + static Vector plg(6); + static Matrix Tg(7,12); + //transformed from T(9,12) + for (i=0; i<3; i++) + ulg(i)=ul(i); + for (i=3; i<6; i++) + ulg(i)=ul(i+1); + for (i=0; i<3; i++) + plg(i)=pl(i); + for (i=3; i<6; i++) + plg(i)=pl(i+1); + + for (i=0; i<3; i++) + { + for (j=0; j<6; j++) + { + Tg(i,j)=T(i,j); + } + } + for (i=0; i<3; i++) + { + for (j=6; j<12; j++) + { + Tg(i,j)=T(i,j+1); + } + } + for (i=3; i<6; i++) + { + for (j=0; j<6; j++) + { + Tg(i,j)=T(i+1,j); + } + } + for (i=3; i<6; i++) + { + for (j=6; j<12; j++) + { + Tg(i,j)=T(i+1,j+1); + } + } + for (j=6; j<12; j++) + { + Tg(6,j)=T(8,j); + } + + for (k = 0; k < 6; k++) + { + factor = plg(k) * tan(ulg(k)); + for (i = 0; i < 12; i++) + for (j = 0; j < 12; j++) + kgConvert(i,j) += Tg(k,i) * factor * Tg(k,j); + } + // [kgConvert(6,6), 0, kgConvert(6,6), 0 + // kg+= o[6,6], 0, 0(6,6), 0 + // kgConvert(6,6), 0, kgConvert(6,6), 0 + // o[6,6], 0, 0(6,6), 0] + for (i=0; i<6; i++){ + for (j=0; j<6; j++) + kg(i,j) += kgConvert(i,j); + } + for (i=0; i<6; i++){ + for (j=7; j<13; j++) + kg(i,j) += kgConvert(i,j-1); + } + for (i=7; i<13; i++){ + for (j=0; j<6; j++) + kg(i,j) += kgConvert(i-1,j); + } + for (i=7; i<13; i++){ + for (j=7; j<13; j++) + kg(i,j) += kgConvert(i-1,j-1); + } + + return kg; +} + + +const Matrix & +CorotCrdTransfWarping3d::getInitialGlobalStiffMatrix (const Matrix &kb) +{ + // transform tangent stiffness matrix from the basic system to local coordinates + static Matrix kl(9,9); + kl=kb; + //kl.addMatrixTripleProduct(0.0, Tp, kb, 1.0); // kl = Tp ^ kb * Tp; + + // transform tangent stiffness matrix from local to global coordinates + static Matrix kg(14,14); + + // compute the tangent stiffness matrix in global coordinates + kg.addMatrixTripleProduct(0.0, T, kl, 1.0); + + return kg; +} + + +int +CorotCrdTransfWarping3d::getLocalAxes(Vector &XAxis, Vector &YAxis, Vector &ZAxis) +{ + // element projection + + static Vector dx(3); + + dx = (nodeJPtr->getCrds() + nodeJOffset) - (nodeIPtr->getCrds() + nodeIOffset); + if (nodeIInitialDisp != 0) { + dx(0) -= nodeIInitialDisp[0]; + dx(1) -= nodeIInitialDisp[1]; + dx(2) -= nodeIInitialDisp[2]; + } + + if (nodeJInitialDisp != 0) { + dx(0) += nodeJInitialDisp[0]; + dx(1) += nodeJInitialDisp[1]; + dx(2) += nodeJInitialDisp[2]; + } + + // calculate the element length + + L = dx.Norm(); + + if (L == 0.0) + { + opserr << "\nCorotCrdTransfWarping3d::computeElemtLengthAndOrien: 0 length\n"; + return -2; + } + + // calculate the element local x axis components (direction cossines) + // wrt to the global coordinates + xAxis = dx/L; + + XAxis(0) = xAxis(0); XAxis(1) = xAxis(1); XAxis(2) = xAxis(2); + + // calculate the cross-product y = v * x + static Vector yAxis(3), zAxis(3); + + yAxis(0) = vAxis(1)*xAxis(2) - vAxis(2)*xAxis(1); + yAxis(1) = vAxis(2)*xAxis(0) - vAxis(0)*xAxis(2); + yAxis(2) = vAxis(0)*xAxis(1) - vAxis(1)*xAxis(0); + + double ynorm = yAxis.Norm(); + + if (ynorm == 0) + { + opserr << "\nCorotCrdTransfWarping3d::getElementLengthAndOrientation"; + opserr << "\nvector v that defines plane xz is parallel to x axis\n"; + return -3; + } + + yAxis /= ynorm; + YAxis(0) = yAxis(0); YAxis(1) = yAxis(1); YAxis(2) = yAxis(2); + + // calculate the cross-product z = x * y + + zAxis(0) = xAxis(1)*yAxis(2) - xAxis(2)*yAxis(1); + zAxis(1) = xAxis(2)*yAxis(0) - xAxis(0)*yAxis(2); + zAxis(2) = xAxis(0)*yAxis(1) - xAxis(1)*yAxis(0); + ZAxis(0) = zAxis(0); ZAxis(1) = zAxis(1); ZAxis(2) = zAxis(2); + + for (int i=0; i < 3; i++) { + R0(i,0) = xAxis(i); + R0(i,1) = yAxis(i); + R0(i,2) = zAxis(i); + } + + return 0; +} + + +double +CorotCrdTransfWarping3d::getInitialLength(void) +{ + return L; +} + + +double +CorotCrdTransfWarping3d::getDeformedLength(void) +{ + return Ln; +} + + +const Vector & +CorotCrdTransfWarping3d::getQuaternionFromRotMatrix(const Matrix &R) const +{ + // obtains the normalised quaternion from the rotation matrix + int i, j, k; + double trR; // trace of R + double a ; + static Vector q(4); // normalized quaternion + + trR = R(0,0) + R(1,1) + R(2,2); + + // a = max ([trR R(0,0) R(1,1) R(2,2)]); + a = trR; + for (i = 0; i < 3; i++) + if (R(i,i) > a) + a = R(i,i); + + if (a == trR) + { + q(3) = sqrt(1+a)*0.5; + + for (i = 0; i < 3; i++) + { + j = (i+1)%3; + k = (i+2)%3; + q(i) = (R(k,j) - R(j,k))/(4*q(3)); + } + } + else + { + for (i = 0; i < 3; i++) + if (a == R(i,i)) + { + j = (i+1)%3; + k = (i+2)%3; + + q(i) = sqrt(a*0.5 + (1 - trR)/4.0); + q(3) = (R(k,j) - R(j,k))/(4*q(i)); + q(j) = (R(j,i) + R(i,j))/(4*q(i)); + q(k) = (R(k,i) + R(i,k))/(4*q(i)); + } + } + + return q; +} + + +const Vector & +CorotCrdTransfWarping3d::getQuaternionFromPseudoRotVector(const Vector &theta) const +{ + double t; // norm of the pseudo rotation vector + double factor; + static Vector q(4); // normalized quaternion + + t = theta.Norm(); + + if (t == 0) + q.Zero(); + else + { + factor = sin(t*0.5)/ t; + for (int i = 0; i < 3; i++) + q(i) = theta(i) * factor; + } + + q(3) = cos(t*0.5); + + return q; +} + + +const Vector & +CorotCrdTransfWarping3d::quaternionProduct(const Vector &q1, const Vector &q2) const +{ + + static Vector q12(4); + int i; + double q1Tq2= 0; // dot product + static Vector q1xq2(3); // cross product + + // calculate the dot product q1.q2 + for (i = 0; i < 3; i++) // NOTE i <3, not i<4 + q1Tq2 += q1(i)* q2(i); + + // calculate the cross-product q1 x q2 + q1xq2(0) = q1(1)*q2(2) - q1(2)*q2(1); + q1xq2(1) = q1(2)*q2(0) - q1(0)*q2(2); + q1xq2(2) = q1(0)*q2(1) - q1(1)*q2(0); + + // calculate the quaternion product + for (i = 0; i < 3; i++) + q12(i) = q1(3)*q2(i) + q2(3)*q1(i) - q1xq2(i); + + q12(3) = q1(3)*q2(3) - q1Tq2; + + return q12; +} + + +const Matrix & +CorotCrdTransfWarping3d::getRotationMatrixFromQuaternion(const Vector &q) const +{ + int i, j; + double factor; + static Matrix I(3,3); // identity matrix + static Matrix qqT(3,3); + static Matrix S(3,3); + static Matrix R(3,3); + + // R = (q0^2 - q' * q) * I + 2 * q * q' + 2*q0*S(q); + + factor = q(3)*q(3) - (q(0)*q(0) + q(1)*q(1) + q(2)*q(2)); + + // opserr << "q rotationMatrix" <getSkewSymMatrix (q); + + R.Zero(); + + for (i = 0; i < 3; i++) + R(i,i) = factor; + + R.addMatrix (1.0, qqT, 2.0); + R.addMatrix (1.0, S, 2.0*q(3)); + + return R; +} + + +const Vector & +CorotCrdTransfWarping3d::getTangScaledPseudoVectorFromQuaternion(const Vector &q) const +{ + static Vector w(3); + + for (int i = 0; i < 3; i++) + w(i) = 2.0 * q(i)/q(3); + + return w; +} + + +const Matrix & +CorotCrdTransfWarping3d::getRotMatrixFromTangScaledPseudoVector(const Vector &w) const +{ + // Rotation matrix in terms of the tangent-scaled pseudo-vector + static Matrix S(3,3); + static Matrix S2(3,3); + static Matrix R(3,3); + double normw2; + + S = this->getSkewSymMatrix(w); + + // R = I + (S + S*S/2)/(1 + w' * w / 4); + + R.Zero(); + + for (int i = 0; i < 3; i++) + R(i,i) = 1; + + S2 = S; + S2.addMatrixProduct(1.0, S, S, 0.5); + + normw2 = w^ w; + + R.addMatrix(1.0, S2, 1.0/(1 + normw2/4.0)); + + return R; +} + + +const Matrix & +CorotCrdTransfWarping3d::getSkewSymMatrix (const Vector &theta) const +{ + static Matrix S(3,3); + + // St = [ 0 -theta(2) theta(1); + // theta(2) 0 -theta(0); + // -theta(1) theta(0) 0 ]; + + S(0,0) = 0.0; + S(0,1) = -theta(2); + S(0,2) = theta(1); + + S(1,0) = theta(2); + S(1,1) = 0.0; + S(1,2) = -theta(0); + + S(2,0) = -theta(1); + S(2,1) = theta(0); + S(2,2) = 0.0; + + //opserr << "getSkew theta: " << theta; + //opserr << "getSkew S: " << S; + + return S; +} + + +const Matrix & +CorotCrdTransfWarping3d::getLMatrix (const Vector &ri) const +{ + static Matrix L1(3,3), L2(3,3); + static Vector r1(3), e1(3); + double rie1, e1r1k; + static Matrix rie1r1(3,3); + static Matrix e1e1r1(3,3); + static Matrix Sri(3,3); + static Matrix Sr1(3,3); + static Matrix L(14,3); + + int j, k; + + for (j = 0; j < 3; j++) + { + e1(j) = e(j,0); + r1(j) = Rbar(j,0); + } + + rie1 = ri^ e1; + + //opserr << "rie1: " << rie1 << endln; + + for (k = 0; k < 3; k++) + { + e1r1k = (e1(k) + r1(k)); + for (j = 0; j < 3; j++) + { + rie1r1(j,k) = ri(j)*e1r1k; + e1e1r1(j,k) = e1(j)*e1r1k; + } + } + + + //L1 = ri'*e1 * A/2 + A*ri*(e1 + r1)'/2; + + L1.addMatrix (0.0, A, rie1*0.5); + L1.addMatrixProduct (1.0, A, rie1r1, 0.5); + + //opserr << "L1: " << L1; + + Sri = this->getSkewSymMatrix(ri); // Change ?????????????????????? + Sr1 = this->getSkewSymMatrix(r1); // Change ?????????????????????? + + // L2 = Sri/2 - ri'*e1*S(r1)/4 - Sri*e1*(e1 + r1)'/4; + L2.addMatrix (0.0, Sri, 0.5); + L2.addMatrix (1.0, Sr1, -rie1/4.0); + L2.addMatrixProduct (1.0, Sri, e1e1r1, -0.25); + + // L = [L1 + // L2 + // 0 + // -L1 + // L2 + // 0; + + L.Zero(); + L.Assemble(L1, 0, 0, 1.0); + L.Assemble(L2, 3, 0, 1.0); + L.Assemble(L1, 7, 0, -1.0); + L.Assemble(L2, 10, 0, 1.0); + + + return L; +} + + +const Matrix & +CorotCrdTransfWarping3d::getKs2Matrix (const Vector &ri, const Vector &z) const +{ + static Matrix ks2(12,12); + static Vector e1(3), r1(3); + + + // Ksigma2 = [ K11 K12 -K11 K12; + // K12t K22 -K12t K22; + // -K11 -K12 K11 -K12; + // K12t K22 -K12t K22]; + + // U = (-1/2)*A*z*ri'*A + ri'*e1*A*z*e1'/(2*Ln)+... + // z'*(e1+r1)*A*ri*e1'/(2*Ln); + + int i, j; + double rite1 = 0; // dot product ri . e1 + double zte1 = 0; // dot product z . e1 + double ztr1 = 0; // dot product z . r1 + + for (i = 0; i < 3; i++) + { + e1(i) = e(i,0); + r1(i) = Rbar(i,0); + rite1 += ri(i)*e1(i); + zte1 += z(i)*e1(i); + ztr1 += z(i)*r1(i); + } + + static Matrix zrit(3,3), ze1t(3,3); + static Matrix rizt(3,3), r1e1t(3,3), rie1t(3,3); + static Matrix e1zt(3,3); + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + { + zrit(i,j) = z(i)*ri(j); + rizt(i,j) = ri(i)*z(j); + ze1t(i,j) = z(i)*e1(j); + e1zt(i,j) = e1(i)*z(j); + r1e1t(i,j) = r1(i)*e1(j); + rie1t(i,j) = ri(i)*e1(j); + } + + static Matrix U(3,3); + + U.addMatrixTripleProduct(0.0, A, zrit, -0.5); + + U.addMatrixProduct (1.0, A, ze1t, rite1/(2*Ln)); + //opserr << "U: A*ze1t*rite1/(2*Ln) " << U; + U.addMatrixProduct (1.0, A, rie1t, (zte1 + ztr1)/(2*Ln)); + + //opserr << "U: " << U; + static Matrix ks(3,3); + + //K11 = U + U' + ri'*e1*(2*(e1'*z)+z'*r1)*A/(2*Ln); + + ks.addMatrix (0.0, U, 1.0); + + // add matrix U transpose + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + ks(i,j) += U(j,i); + + ks.addMatrix(1.0, A, rite1*(2*zte1 + ztr1)/(2*Ln)); + + //opserr << "Ks211: " << ks; + + ks2.Zero(); + + ks2.Assemble(ks, 0, 0, 1.0); + ks2.Assemble(ks, 0, 6, -1.0); + ks2.Assemble(ks, 6, 0, -1.0); + ks2.Assemble(ks, 6, 6, 1.0); + + static Matrix Sri(3,3), Sr1(3,3), Sz(3,3), Se1(3,3); + + Sri = this->getSkewSymMatrix(ri); + Sr1 = this->getSkewSymMatrix(r1); + Sz = this->getSkewSymMatrix(z); + Se1 = this->getSkewSymMatrix(e1); + + //K12 = (1/4)*(-A*z*e1'*Sri - A*ri*z'*Sr1 - z'*(e1+r1)*A*Sri); + + static Matrix m1(3,3); + + m1.addMatrixProduct(0.0, A, ze1t, -1.0); + ks.addMatrixProduct(0.0, m1, Sri, 0.25); + + m1.addMatrixProduct(0.0, A, rizt, -1.0); + ks.addMatrixProduct(1.0, m1, Sr1, 0.25); + + ks.addMatrixProduct(1.0, A, Sri, -0.25*(zte1+ztr1)); + + //opserr << "Ks2_12: " << ks; + + ks2.Assemble(ks, 0, 3, 1.0); + ks2.Assemble(ks, 0, 9, 1.0); + ks2.Assemble(ks, 6, 3, -1.0); + ks2.Assemble(ks, 6, 9, -1.0); + + ks2.AssembleTranspose(ks, 3, 0, 1.0); + ks2.AssembleTranspose(ks, 3, 6, -1.0); + ks2.AssembleTranspose(ks, 9, 0, 1.0); + ks2.AssembleTranspose(ks, 9, 6, -1.0); + + //K22 = (1/8)*((-ri'*e1)*Sz*Sr1 + Sr1*z*e1'*Sri + ... + // Sri*e1*z'*Sr1 - (e1+r1)'*z*S(e1)*Sri + 2*Sz*Sri); + + ks.addMatrixProduct (0.0, Sz, Sr1, -0.125*(rite1)); + + m1.addMatrixProduct (0.0, Sr1, ze1t, 1.0); + ks.addMatrixProduct (1.0, m1, Sri, 0.125); + + m1.addMatrixProduct (0.0, Sri, e1zt, 1.0); + ks.addMatrixProduct (1.0, m1, Sr1, 0.125); + + ks.addMatrixProduct (1.0, Se1, Sri, -0.125*(zte1 + ztr1)); + ks.addMatrixProduct (1.0, Sz, Sri, 0.25); + + //opserr << "Ks2_22: " << ks; + + // Ksigma2 = [ K11 K12 -K11 K12; + // K12t K22 -K12t K22; + // -K11 -K12 K11 -K12; + // K12t K22 -K12t K22]; + + ks2.Assemble(ks, 3, 3, 1.0); + ks2.Assemble(ks, 3, 9, 1.0); + ks2.Assemble(ks, 9, 3, 1.0); + ks2.Assemble(ks, 9, 9, 1.0); + + return ks2; +} + + +CrdTransf * +CorotCrdTransfWarping3d::getCopy3d(void) +{ + // create a new instance of CorotCrdTransfWarping3d + + CorotCrdTransfWarping3d *theCopy = new CorotCrdTransfWarping3d (this->getTag(), vAxis, nodeIOffset, nodeJOffset); + + if (!theCopy) + { + opserr << "CorotCrdTransfWarping3d::getCopy() - out of memory creating copy\n"; + exit(-1); + return 0; + } + + theCopy->nodeIPtr = nodeIPtr; + theCopy->nodeJPtr = nodeJPtr; + theCopy->xAxis = xAxis; + theCopy->L = L; + theCopy->Ln = Ln; + theCopy->R0 = R0; + theCopy->alphaIq = alphaIq; + theCopy->alphaJq = alphaJq; + theCopy->alphaIqcommit = alphaIqcommit; + theCopy->alphaJqcommit = alphaJqcommit; + theCopy->ul = ul; + theCopy->ulcommit = ulcommit; + + + return theCopy; +} + + +int +CorotCrdTransfWarping3d::sendSelf(int cTag, Channel &theChannel) +{ + Vector data(46); + for (int i=0; i<7; i++) + data(i) = ulcommit(i); + for (int j=0; j<4; j++) { + data(7+j) = alphaIqcommit(j); + data(11+j) = alphaJqcommit(j); + } + + for (int k=0; k<3; k++) { + data(15+k) = xAxis(k); + data(18+k) = vAxis(k); + data(21+k) = nodeIOffset(k); + data(24+k) = nodeJOffset(k); + data(27+k) = alphaI(k); + data(30+k) = alphaJ(k); + } + + if (nodeIInitialDisp != 0) { + data(34) = nodeIInitialDisp[0]; + data(35) = nodeIInitialDisp[1]; + data(36) = nodeIInitialDisp[2]; + data(37) = nodeIInitialDisp[3]; + data(38) = nodeIInitialDisp[4]; + data(39) = nodeIInitialDisp[5]; + } else { + data(34) = 0.0; + data(35) = 0.0; + data(36) = 0.0; + data(37) = 0.0; + data(38) = 0.0; + data(39) = 0.0; + } + + if (nodeJInitialDisp != 0) { + data(40) = nodeJInitialDisp[0]; + data(41) = nodeJInitialDisp[1]; + data(42) = nodeJInitialDisp[2]; + data(43) = nodeJInitialDisp[3]; + data(44) = nodeJInitialDisp[4]; + data(45) = nodeJInitialDisp[5]; + } else { + data(40) = 0.0; + data(41) = 0.0; + data(42) = 0.0; + data(43) = 0.0; + data(44) = 0.0; + data(45) = 0.0; + } + + + if (theChannel.sendVector(this->getTag(), cTag, data) < 0) { + opserr << " CorotCrdTransf2d::sendSelf() - data could not be sent\n" ; + return -1; + } + return 0; +} + + +int +CorotCrdTransfWarping3d::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +{ + Vector data(46); + if (theChannel.recvVector(this->getTag(), cTag, data) < 0) { + opserr << " CorotCrdTransf2d::recvSelf() - data could not be received\n" ; + return -1; + } + int i,j; + for (i=0; i<7; i++) + ulcommit(i) = data(i); + for (j=0; j<4; j++) { + alphaIqcommit(j) = data(7+j); + alphaJqcommit(j) = data(11+j); + } + + for (int k=0; k<3; k++) { + xAxis(k) = data(15+k); + vAxis(k) = data(18+k); + nodeIOffset(k) = data(21+k); + nodeJOffset(k) = data(24+k); + alphaI(k) = data(27+k); + alphaJ(k) = data(30+k); + } + + int flag; + flag = 0; + for (i=34; i<=39; i++) + if (data(i) != 0.0) + flag = 1; + if (flag == 1) { + if (nodeIInitialDisp == 0) + nodeIInitialDisp = new double[6]; + for (i=34, j=0; i<=39; i++, j++) + nodeIInitialDisp[j] = data(i); + } + + flag = 0; + for (i=40; i<=45; i++) + if (data(i) != 0.0) + flag = 1; + if (flag == 1) { + if (nodeJInitialDisp == 0) + nodeJInitialDisp = new double [6]; + for (i=40, j=0; i<=45; i++, j++) + nodeJInitialDisp[j] = data(i); + } + + ul = ulcommit; + alphaIq = alphaIqcommit; + alphaJq = alphaJqcommit; + + initialDispChecked = true; + return 0; + +} + +const Matrix & +CorotCrdTransfWarping3d::getGlobalMatrixFromLocal(const Matrix &local) +{ + this->compTransfMatrixLocalGlobal(Tlg); // OPTIMIZE LATER + kg.addMatrixTripleProduct(0.0, Tlg, local, 1.0); // OPTIMIZE LATER + + return kg; +} + +const Vector & +CorotCrdTransfWarping3d::getPointGlobalCoordFromLocal(const Vector &xl) +{ + static Vector xg(3); + opserr << " CorotCrdTransfWarping3d::getPointGlobalCoordFromLocal: not implemented yet" ; + + return xg; +} + + +const Vector & +CorotCrdTransfWarping3d::getPointGlobalDisplFromBasic (double xi, const Vector &uxb) +{ + static Vector uxg(3); + opserr << " CorotCrdTransfWarping3d::getPointGlobalDisplFromBasic: not implemented yet" ; + + + return uxg; +} + +const Vector & +CorotCrdTransfWarping3d::getPointLocalDisplFromBasic(double xi, const Vector &uxb) +{ + static Vector uxg(3); + opserr << " CorotCrdTransfWarping3d::getPointLocalDisplFromBasic: not implemented yet" ; + + + return uxg; +} + +void +CorotCrdTransfWarping3d::Print(OPS_Stream &s, int flag) +{ + s << "\nCrdTransf: " << this->getTag() << " Type: CorotCrdTransfWarping3d"; + s << "\tvAxis: " << vAxis; + s << "\tnodeI Offset: " << nodeIOffset; + s << "\tnodeJ Offset: " << nodeJOffset; +} diff --git a/SRC/coordTransformation/CorotCrdTransfWarping3d.h b/SRC/coordTransformation/CorotCrdTransfWarping3d.h new file mode 100755 index 000000000..0d0afae43 --- /dev/null +++ b/SRC/coordTransformation/CorotCrdTransfWarping3d.h @@ -0,0 +1,142 @@ +/* ****************************************************************** ** +** 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.9 $ +// $Date: 2006/01/13 01:07:48 $ +// $Source: /usr/local/cvs/OpenSees/SRC/coordTransformation/CorotCrdTransfWarping3d.h,v $ + + +// Written: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu) +// Created: 04/2000 +// Revision: A +// +// Description: This file contains the class definition for +// CorotCrdTransfWarping3d.h. CorotCrdTransfWarping3d provides the +// abstraction of a corotation transformation for a spatial frame element + +// What: "@(#) CorotCrdTransfWarping3d.h, revA" + +#ifndef CorotCrdTransfWarping3d_h +#define CorotCrdTransfWarping3d_h + +#include +#include +#include + +class CorotCrdTransfWarping3d: public CrdTransf +{ +public: + CorotCrdTransfWarping3d(int tag, const Vector &vecInLocXZPlane, + const Vector &rigJntOffsetI, const Vector &rigJntOffsetJ); + + CorotCrdTransfWarping3d(); + ~CorotCrdTransfWarping3d(); + + int initialize(Node *nodeIPointer, Node *nodeJPointer); + int update(void); + double getInitialLength(void); + double getDeformedLength(void); + + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + const Vector &getBasicTrialDisp(void); + const Vector &getBasicIncrDisp(void); + const Vector &getBasicIncrDeltaDisp(void); + const Vector &getBasicTrialVel(void); + const Vector &getBasicTrialAccel(void); + + const Vector &getGlobalResistingForce(const Vector &basicForce, const Vector &uniformLoad); + const Matrix &getGlobalStiffMatrix(const Matrix &basicStiff, const Vector &basicForce); + const Matrix &getInitialGlobalStiffMatrix(const Matrix &basicStiff); + + CrdTransf *getCopy3d(void); + + int sendSelf(int cTag, Channel &theChannel); + int recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + + void Print(OPS_Stream &s, int flag = 0); + + // method used to rotate consistent mass matrix + const Matrix &getGlobalMatrixFromLocal(const Matrix &local); + + // functions used in post-processing only + const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords); + const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps); + const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps); + + int getLocalAxes(Vector &xAxis, Vector &yAxis, Vector &zAxis); + +private: + void compTransfMatrixBasicGlobal(void); + void compTransfMatrixBasicGlobalNew(void); + void compTransfMatrixLocalGlobal(Matrix &Tlg); + void compTransfMatrixBasicLocal(Matrix &Tbl); + const Vector &getQuaternionFromRotMatrix(const Matrix &RotMatrix) const; + const Vector &getQuaternionFromPseudoRotVector(const Vector &theta) const; + const Vector &getTangScaledPseudoVectorFromQuaternion(const Vector &theta) const; + const Vector &quaternionProduct(const Vector &q1, const Vector &q2) const; + const Matrix &getRotationMatrixFromQuaternion(const Vector &q) const; + const Matrix &getRotMatrixFromTangScaledPseudoVector(const Vector &w) const; + const Matrix &getSkewSymMatrix(const Vector &theta) const; + const Matrix &getLMatrix(const Vector &ri) const; + const Matrix &getKs2Matrix(const Vector &ri, const Vector &z) const; + + // internal data + Node *nodeIPtr, *nodeJPtr; // pointers to the element two endnodes + + Vector vAxis; // Vector that lies in local plane xz + Vector nodeIOffset, nodeJOffset; // rigid joint offsets + + Vector xAxis; // local x axis + double L; // undeformed element length + double Ln; // deformed element length + + Matrix R0; // rotation matrix from local to global coordinates + // (the columns of which are the element local axes) + Vector alphaIq; // quaternion for node I + Vector alphaJq; // quaternion for node I + + Vector alphaIqcommit; // commited quaternion for node I + Vector alphaJqcommit; // commited quaternion for node J + Vector alphaI; // last trial rotations end i + Vector alphaJ; // last trial rotatations end j + + Vector ul; // local displacements + Vector ulcommit; // commited local displacements + Vector ulpr; // previous local displacements + + static Matrix RI; // nodal triad for node 1 + static Matrix RJ; // nodal triad for node 2 + static Matrix Rbar; // mean nodal triad + static Matrix e; // base vectors + static Matrix Tp; // transformation matrix to renumber dofs + static Matrix T; // transformation matrix from basic to global system + static Matrix TlgInv; // inverse of transformation matrix from global to local system + //static Matrix Tbl; // transformation matrix from local to basic system + static Matrix Tlg; // transformation matrix from global to local system + static Matrix kg; // global stiffness matrix + static Matrix Lr2, Lr3, A; // auxiliary matrices + + double *nodeIInitialDisp, *nodeJInitialDisp; + bool initialDispChecked; +}; +#endif diff --git a/SRC/element/dispBeamColumn/DispBeamColumnWarping3d.cpp b/SRC/element/dispBeamColumn/DispBeamColumnWarping3d.cpp new file mode 100755 index 000000000..fdbf88b5f --- /dev/null +++ b/SRC/element/dispBeamColumn/DispBeamColumnWarping3d.cpp @@ -0,0 +1,1916 @@ +/* ****************************************************************** ** +** 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.25 $ +// $Date: 2008/11/04 21:32:05 $ +// $Source: /usr/local/cvs/OpenSees/SRC/element/dispBeamColumn/DispBeamColumnWarping3d.cpp,v $ + +// Modified by Xi Zhang from University of Sydney, Australia (include warping degrees of freedom). Refer to +// Formulation and Implementation of Three-dimensional Doubly Symmetric Beam-Column Analyses with Warping Effects in OpenSees +// Research Report R917, School of Civil Engineering, University of Sydney. +// Description: This file contains the class definition for DispBeamColumnWarping3d which include warping degrees of freedom. +// Modified by Xi Zhang from University of Sydney, Australia (include warping degrees of freedom). Refer to +// Formulation and Implementation of Three-dimensional Doubly Symmetric Beam-Column Analyses with Warping Effects in OpenSees +// Research Report R917, School of Civil Engineering, University of Sydney. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using std::string; +using namespace std; + + +Matrix DispBeamColumnWarping3d::K(14,14); +Vector DispBeamColumnWarping3d::P(14); +double DispBeamColumnWarping3d::workArea[200]; + +void* OPS_DispBeamColumnWarping3d() +{ + if(OPS_GetNumRemainingInputArgs() < 5) { + opserr<<"insufficient arguments:eleTag,iNode,jNode,transfTag,integrationTag <-mass mass> <-cmass>\n"; + return 0; + } + + // inputs: + int iData[5]; + int numData = 5; + if(OPS_GetIntInput(&numData,&iData[0]) < 0) { + opserr<<"WARNING: invalid integer inputs\n"; + return 0; + } + + // options + double mass = 0.0; + int cmass = 0; + numData = 1; + while(OPS_GetNumRemainingInputArgs() > 0) { + const char* type = OPS_GetString(); + if(strcmp(type,"-cMass") == 0) { + cmass = 1; + } else if(strcmp(type,"-mass") == 0) { + if(OPS_GetNumRemainingInputArgs() > 0) { + if(OPS_GetDoubleInput(&numData,&mass) < 0) { + opserr<<"WARNING: invalid mass\n"; + return 0; + } + } + } + } + + // check transf + CrdTransf* theTransf = OPS_getCrdTransf(iData[3]); + if(theTransf == 0) { + opserr<<"coord transfomration not found\n"; + return 0; + } + + // check beam integrataion + BeamIntegrationRule* theRule = OPS_getBeamIntegrationRule(iData[4]); + if(theRule == 0) { + opserr<<"beam integration not found\n"; + return 0; + } + BeamIntegration* bi = theRule->getBeamIntegration(); + if(bi == 0) { + opserr<<"beam integration is null\n"; + return 0; + } + + // check sections + const ID& secTags = theRule->getSectionTags(); + SectionForceDeformation** sections = new SectionForceDeformation *[secTags.Size()]; + for(int i=0; igetCopy(); + + // Check allocation + if (theSections[i] == 0) { + opserr << "DispBeamColumnWarping3d::DispBeamColumnWarping3d -- failed to get a copy of section model\n"; + exit(-1); + } + } + + beamInt = bi.getCopy(); + + if (beamInt == 0) { + opserr << "DispBeamColumnWarping3d::DispBeamColumnWarping3d - failed to copy beam integration\n"; + exit(-1); + } + + crdTransf = coordTransf.getCopy3d(); + + if (crdTransf == 0) { + opserr << "DispBeamColumnWarping3d::DispBeamColumnWarping3d - failed to copy coordinate transformation\n"; + exit(-1); + } + + // Set connected external node IDs + connectedExternalNodes(0) = nd1; + connectedExternalNodes(1) = nd2; + + + theNodes[0] = 0; + theNodes[1] = 0; + + q0[0] = 0.0; + q0[1] = 0.0; + q0[2] = 0.0; + q0[3] = 0.0; + q0[4] = 0.0; + q0[5] = 0.0; + q0[6] = 0.0; + q0[7] = 0.0; + q0[8] = 0.0; + + p0[0] = 0.0; + p0[1] = 0.0; + p0[2] = 0.0; + p0[3] = 0.0; + p0[4] = 0.0; +} + +DispBeamColumnWarping3d::DispBeamColumnWarping3d() +:Element (0, ELE_TAG_DispBeamColumnWarping3d), +numSections(0), theSections(0), crdTransf(0), beamInt(0), +connectedExternalNodes(2), +Q(14), q(9), rho(0.0), parameterID(0) +{ + q0[0] = 0.0; + q0[1] = 0.0; + q0[2] = 0.0; + q0[3] = 0.0; + q0[4] = 0.0; + q0[5] = 0.0; + q0[6] = 0.0; + q0[7] = 0.0; + q0[8] = 0.0; + + + p0[0] = 0.0; + p0[1] = 0.0; + p0[2] = 0.0; + p0[3] = 0.0; + p0[4] = 0.0; + + theNodes[0] = 0; + theNodes[1] = 0; +} + +DispBeamColumnWarping3d::~DispBeamColumnWarping3d() +{ + for (int i = 0; i < numSections; i++) { + if (theSections[i]) + delete theSections[i]; + } + + // Delete the array of pointers to SectionForceDeformation pointer arrays + if (theSections) + delete [] theSections; + + if (crdTransf) + delete crdTransf; + + if (beamInt != 0) + delete beamInt; +} + +int +DispBeamColumnWarping3d::getNumExternalNodes() const +{ + return 2; +} + +const ID& +DispBeamColumnWarping3d::getExternalNodes() +{ + return connectedExternalNodes; +} + +Node ** +DispBeamColumnWarping3d::getNodePtrs() +{ + + return theNodes; +} + +int +DispBeamColumnWarping3d::getNumDOF() +{ + return 14; +} + +void +DispBeamColumnWarping3d::setDomain(Domain *theDomain) +{ + // Check Domain is not null - invoked when object removed from a domain + if (theDomain == 0) { + theNodes[0] = 0; + theNodes[1] = 0; + return; + } + + int Nd1 = connectedExternalNodes(0); + int Nd2 = connectedExternalNodes(1); + + theNodes[0] = theDomain->getNode(Nd1); + theNodes[1] = theDomain->getNode(Nd2); + + if (theNodes[0] == 0 || theNodes[1] == 0) { + opserr << "FATAL ERROR DispBeamColumnWarping3d (tag: %d), node not found in domain", + this->getTag(); + + return; + } + + int dofNd1 = theNodes[0]->getNumberDOF(); + int dofNd2 = theNodes[1]->getNumberDOF(); + + // release this restriction + /*if (dofNd1 != 6 || dofNd2 != 6) { + //opserr << "FATAL ERROR DispBeamColumnWarping3d (tag: %d), has differing number of DOFs at its nodes", + // this->getTag()); + + return; + }*/ + + if (crdTransf->initialize(theNodes[0], theNodes[1])) { + // Add some error check + } + + double L = crdTransf->getInitialLength(); + + if (L == 0.0) { + // Add some error check + } + + this->DomainComponent::setDomain(theDomain); + + this->update(); +} + +int +DispBeamColumnWarping3d::commitState() +{ + int retVal = 0; + + // call element commitState to do any base class stuff + if ((retVal = this->Element::commitState()) != 0) { + opserr << "DispBeamColumnWarping3d::commitState () - failed in base class"; + } + + // Loop over the integration points and commit the material states + for (int i = 0; i < numSections; i++) + retVal += theSections[i]->commitState(); + + retVal += crdTransf->commitState(); + + return retVal; +} + +int +DispBeamColumnWarping3d::revertToLastCommit() +{ + int retVal = 0; + + // Loop over the integration points and revert to last committed state + for (int i = 0; i < numSections; i++) + retVal += theSections[i]->revertToLastCommit(); + + retVal += crdTransf->revertToLastCommit(); + + return retVal; +} + +int +DispBeamColumnWarping3d::revertToStart() +{ + int retVal = 0; + + // Loop over the integration points and revert states to start + for (int i = 0; i < numSections; i++) + retVal += theSections[i]->revertToStart(); + + retVal += crdTransf->revertToStart(); + + return retVal; +} + +int +DispBeamColumnWarping3d::update(void) +{ + int err = 0; + + // Update the transformation + crdTransf->update(); + + // Get basic deformations + const Vector &v = crdTransf->getBasicTrialDisp(); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + double oneOverLsquare = oneOverL*oneOverL; + + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + Vector e(workArea, 8); + + double xi6 = 6.0*xi[i]; + double xi12 = 12.0*xi[i]; + double xi1 = xi[i]; + + int j; + + // here total strain (not incremental) is used + e(0) = oneOverL*v(8); + e(1) = oneOverL*((xi6-4.0)*v(1) + (xi6-2.0)*v(5)); + e(2) = oneOverL*((xi6-4.0)*v(2) + (xi6-2.0)*v(6)); + e(4) =oneOverL*(6.0*xi1*xi1-6.0*xi1)*v(0)+(1.0-4.0*xi1+3*xi1*xi1)*v(3)+oneOverL*(6.0*xi1-6.0*xi1*xi1)*v(4)+(3.0*xi1*xi1-2.0*xi1)*v(7); + e(3) = -oneOverLsquare*(xi12-6.0)*v(0)-oneOverL*(xi6-4.0)*v(3)-oneOverLsquare*(6.0-xi12)*v(4)-oneOverL*(xi6-2.0)*v(7); + e(5) = (1.0+3.0*xi1*xi1-4.0*xi1)*v(1)+(3.0*xi1*xi1-2.0*xi1)*v(5); + e(6) = (1.0+3.0*xi1*xi1-4.0*xi1)*v(2)+(3.0*xi1*xi1-2.0*xi1)*v(6); + e(7) = (1.0-3.0*xi1*xi1+2.0*xi1*xi1*xi1)*v(0)+L*xi1*(1.0-xi1)*(1.0-xi1)*v(3)+(3.0*xi1*xi1-2.0*xi1*xi1*xi1)*v(4)+L*xi1*xi1*(xi1-1.0)*v(7); + + // Set the section deformations + err += theSections[i]->setTrialSectionDeformation(e); + } + + if (err != 0) { + opserr << "DispBeamColumnWarping3d::update() - failed setTrialSectionDeformations()\n"; + return err; + } + + return 0; +} + +const Matrix& +DispBeamColumnWarping3d::getTangentStiff() +{ + static Matrix kb(9,9); + static Matrix N1(6,8); + static Matrix N2(8,9); + static Matrix N3(8,8); + static Matrix kbPart1(9,9); + static Matrix Gmax(8,8); + static Matrix kbPart2(9,9); + const Vector &v = crdTransf->getBasicTrialDisp(); + + // Zero for integral + kb.Zero(); + + q.Zero(); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + double oneOverLsquare = oneOverL*oneOverL; + double oneOverLcube = oneOverLsquare*oneOverL; + + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + //const Vector &wts = quadRule.getIntegrPointWeights(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + double wt[maxNumSections]; + beamInt->getSectionWeights(numSections, L, wt); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + N1.Zero(); + N2.Zero(); + N3.Zero(); + kbPart1.Zero(); + Gmax.Zero(); + kbPart2.Zero(); + + double xi6 = 6.0*xi[i]; + double xi12 = 12.0*xi[i]; + double xi1 = xi[i]; + double dNv1 = 1.0+3.0*xi1*xi1-4.0*xi1; + double dNv2 = 3.0*xi1*xi1-2.0*xi1; + double dNw1 = dNv1; + double dNw2 = dNv2; + double ddNv1 = 6.0*xi1*oneOverL-4.0*oneOverL; + double ddNv2 = 6.0*xi1*oneOverL-2.0*oneOverL; + double ddNw1 = ddNv1; + double ddNw2 = ddNv2; + double Nf1 = 1.0-3.0*xi1*xi1+2.0*xi1*xi1*xi1; + double Nf2 = xi1*L*(1.0-xi1)*(1.0-xi1); + double Nf3 = 3.0*xi1*xi1-2.0*xi1*xi1*xi1; + double Nf4 = xi1*xi1*L*(xi1-1.0); + double dNf1 = 6.0*xi1*xi1*oneOverL-6.0*xi1*oneOverL; + double dNf2 = dNv1; + double dNf3 = 6.0*xi1*oneOverL-6.0*xi1*xi1*oneOverL; + double dNf4 = dNv2; + double ddNf1 = 12.0*xi1*oneOverLsquare-6.0*oneOverLsquare; + double ddNf2 = ddNv1; + double ddNf3 = 6.0*oneOverLsquare-12.0*xi1*oneOverLsquare; + double ddNf4 = ddNv2; + N1(0,0) = 1.0; + N1(0,1) = dNv1*v(1)+dNv2*v(5); + N1(0,2) = dNw1*v(2)+dNw2*v(6); + N1(1,3) = 1.0; + N1(1,4) = Nf1*v(0)+Nf2*v(3)+Nf3*v(4)+Nf4*v(7); + N1(1,5) = ddNw1*v(2)+ddNw2*v(6); + N1(2,3) = -N1(1,4); + N1(2,4) = 1.0; + N1(2,5) = -ddNv1*v(1)-ddNv2*v(5); + N1(3,6) = dNf1*v(0)+dNf2*v(3)+dNf3*v(4)+dNf4*v(7); + N1(4,7) = -1.0; + N1(5,6) = 1.0; + N2(0,8) = oneOverL; + N2(1,1) = dNv1; + N2(1,5) = dNv2; + N2(2,2) = dNw1; + N2(2,6) = dNw2; + N2(3,1) = ddNv1; + N2(3,5) = ddNv2; + N2(4,2) = ddNw1; + N2(4,6) = ddNw2; + N2(5,0) = Nf1; + N2(5,3) = Nf2; + N2(5,4) = Nf3; + N2(5,7) = Nf4; + N2(6,0) = dNf1; + N2(6,3) = dNf2; + N2(6,4) = dNf3; + N2(6,7) = dNf4; + N2(7,0) = ddNf1; + N2(7,3) = ddNf2; + N2(7,4) = ddNf3; + N2(7,7) = ddNf4; + + // Get the section tangent stiffness and stress resultant + const Matrix &ks = theSections[i]->getSectionTangent(); + + //calculate kb, refer to Alemdar + + N3.addMatrixTripleProduct(0.0, N1, ks, 1.0); + kbPart1.addMatrixTripleProduct(0.0, N2, N3, 1.0); + const Vector &s = theSections[i]->getStressResultant(); + + Gmax(1,1) = s(0); + Gmax(2,2) = s(0); + Gmax(3,5) = s(1); + Gmax(4,5) = s(2); + Gmax(5,3) = s(2); + Gmax(5,4) = s(1); + Gmax(6,6) = s(3); + kbPart2.addMatrixTripleProduct(0.0, N2, Gmax, 1.0); + + // Perform numerical integration + //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L); + double wti = wt[i]; + + for (int j=0; j<9; j++) + { + for (int k=0; k<9; k++) + { + kb(j,k) +=kbPart1(j,k)*L*wti + kbPart2(j,k)*L*wti; + } + } + + static Vector qProduct1(8); + static Vector qProduct2(9); + qProduct1.Zero(); + qProduct2.Zero(); + qProduct1.addMatrixTransposeVector(0.0, N1, s, 1.0); + qProduct2.addMatrixTransposeVector(0.0, N2, qProduct1, 1.0); + + for (int j=0; j<9; j++) + { + q(j) += qProduct2(j)*L*wti; + } + } + + q(0) += q0[0]; + q(1) += q0[1]; + q(2) += q0[2]; + q(3) += q0[3]; + q(4) += q0[4]; + + // Transform to global stiffness + K = crdTransf->getGlobalStiffMatrix(kb, q); + + return K; +} + +const Matrix& +DispBeamColumnWarping3d::getInitialBasicStiff() +{ + static Matrix kb(9,9); + static Matrix N1(6,8); + static Matrix N2(8,9); + static Matrix N3(8,8); + static Matrix kbPart1(9,9); + static Matrix Gmax(8,8); + static Matrix kbPart2(9,9); + + // Zero for integral + kb.Zero(); + const Vector &v = crdTransf->getBasicTrialDisp(); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + double oneOverLsquare = oneOverL*oneOverL; + double oneOverLcube = oneOverLsquare*oneOverL; + + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + //const Vector &wts = quadRule.getIntegrPointWeights(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + double wt[maxNumSections]; + beamInt->getSectionWeights(numSections, L, wt); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + N1.Zero(); + N2.Zero(); + N3.Zero(); + kbPart1.Zero(); + Gmax.Zero(); + kbPart2.Zero(); + + + double xi6 = 6.0*xi[i]; + double xi12=12*xi[i]; + double xi1=xi[i]; + double dNv1 = 1.0+3.0*xi1*xi1-4.0*xi1; + double dNv2 = 3.0*xi1*xi1-2.0*xi1; + double dNw1 = dNv1; + double dNw2 = dNv2; + double ddNv1 = 6.0*xi1*oneOverL-4.0*oneOverL; + double ddNv2 = 6.0*xi1*oneOverL-2.0*oneOverL; + double ddNw1 = ddNv1; + double ddNw2 = ddNv2; + double Nf1 = 1.0-3.0*xi1*xi1+2.0*xi1*xi1*xi1; + double Nf2 = xi1*L*(1.0-xi1)*(1.0-xi1); + double Nf3 = 3.0*xi1*xi1-2.0*xi1*xi1*xi1; + double Nf4 = xi1*xi1*L*(xi1-1.0); + double dNf1 = 6.0*xi1*xi1*oneOverL-6.0*xi1*oneOverL; + double dNf2 = dNv1; + double dNf3 = 6.0*xi1*oneOverL-6.0*xi1*xi1*oneOverL; + double dNf4 = dNv2; + double ddNf1 = 12.0*xi1*oneOverLsquare-6.0*oneOverLsquare; + double ddNf2 = ddNv1; + double ddNf3 = 6.0*oneOverLsquare-12.0*xi1*oneOverLsquare; + double ddNf4 = ddNv2; + N1(0,0) = 1.0; + N1(0,1) = dNv1*v(1)+dNv2*v(5); + N1(0,2) = dNw1*v(2)+dNw2*v(6); + N1(1,3) = 1.0; + N1(1,4) = Nf1*v(0)+Nf2*v(3)+Nf3*v(4)+Nf4*v(7); + N1(1,5) = ddNw1*v(2)+ddNw2*v(6); + N1(2,3) = -N1(1,4); + N1(2,4) = 1.0; + N1(2,5) = -ddNv1*v(1)-ddNv2*v(5); + N1(3,6) = dNf1*v(0)+dNf2*v(3)+dNf3*v(4)+dNf4*v(7); + N1(4,7) = -1.0; + N1(5,6) = 1.0; + N2(0,8) = oneOverL; + N2(1,1) = dNv1; + N2(1,5) = dNv2; + N2(2,2) = dNw1; + N2(2,6) = dNw2; + N2(3,1) = ddNv1; + N2(3,5) = ddNv2; + N2(4,2) = ddNw1; + N2(4,6) = ddNw2; + N2(5,0) = Nf1; + N2(5,3) = Nf2; + N2(5,4) = Nf3; + N2(5,7) = Nf4; + N2(6,0) = dNf1; + N2(6,3) = dNf2; + N2(6,4) = dNf3; + N2(6,7) = dNf4; + N2(7,0) = ddNf1; + N2(7,3) = ddNf2; + N2(7,4) = ddNf3; + N2(7,7) = ddNf4; + + + // Get the section tangent stiffness and stress resultant + const Matrix &ks = theSections[i]->getInitialTangent(); + N3.addMatrixTripleProduct(0.0, N1, ks, 1.0); + kbPart1.addMatrixTripleProduct(0.0, N2, N3, 1.0); + const Vector &s = theSections[i]->getStressResultant(); + Gmax(1,1) = s(0); + Gmax(2,2) = s(0); + Gmax(3,5) = s(1); + Gmax(4,5) = s(2); + Gmax(5,3) = s(2); + Gmax(5,4) = s(1); + Gmax(6,6) = s(3); + kbPart2.addMatrixTripleProduct(0.0, N2, Gmax, 1.0); + //opserr<<"s"<getInitialBasicStiff(); + + // Transform to global stiffness + K = crdTransf->getInitialGlobalStiffMatrix(kb); + + return K; +} + +const Matrix& +DispBeamColumnWarping3d::getMass() +{ + K.Zero(); + + if (rho == 0.0) + return K; + + double L = crdTransf->getInitialLength(); + double m = 0.5*rho*L; + + K(0,0) = K(1,1) = K(2,2) = K(7,7) = K(8,8) = K(9,9) = m; + + return K; +} + +void +DispBeamColumnWarping3d::zeroLoad(void) +{ + Q.Zero(); + + q0[0] = 0.0; + q0[1] = 0.0; + q0[2] = 0.0; + q0[3] = 0.0; + q0[4] = 0.0; + + p0[0] = 0.0; + p0[1] = 0.0; + p0[2] = 0.0; + p0[3] = 0.0; + p0[4] = 0.0; + + return; +} + +int +DispBeamColumnWarping3d::addLoad(ElementalLoad *theLoad, double loadFactor) +{ + int type; + const Vector &data = theLoad->getData(type, loadFactor); + double L = crdTransf->getInitialLength(); + + if (type == LOAD_TAG_Beam3dUniformLoad) { + double wy = data(0)*loadFactor; // Transverse + double wz = data(1)*loadFactor; // Transverse + double wx = data(2)*loadFactor; // Axial (+ve from node I to J) + + double Vy = 0.5*wy*L; + double Mz = Vy*L/6.0; // wy*L*L/12 + double Vz = 0.5*wz*L; + double My = Vz*L/6.0; // wz*L*L/12 + double P = wx*L; + + // Reactions in basic system + p0[0] -= P; + p0[1] -= Vy; + p0[2] -= Vy; + p0[3] -= Vz; + p0[4] -= Vz; + + // Fixed end forces in basic system + q0[0] -= 0.5*P; + q0[1] -= Mz; + q0[2] += Mz; + q0[3] += My; + q0[4] -= My; + } + else if (type == LOAD_TAG_Beam3dPointLoad) { + double Py = data(0)*loadFactor; + double Pz = data(1)*loadFactor; + double N = data(2)*loadFactor; + double aOverL = data(3); + + if (aOverL < 0.0 || aOverL > 1.0) + return 0; + + double a = aOverL*L; + double b = L-a; + + // Reactions in basic system + p0[0] -= N; + double V1, V2; + V1 = Py*(1.0-aOverL); + V2 = Py*aOverL; + p0[1] -= V1; + p0[2] -= V2; + V1 = Pz*(1.0-aOverL); + V2 = Pz*aOverL; + p0[3] -= V1; + p0[4] -= V2; + + double L2 = 1.0/(L*L); + double a2 = a*a; + double b2 = b*b; + + // Fixed end forces in basic system + q0[0] -= N*aOverL; + double M1, M2; + M1 = -a * b2 * Py * L2; + M2 = a2 * b * Py * L2; + q0[1] += M1; + q0[2] += M2; + M1 = -a * b2 * Pz * L2; + M2 = a2 * b * Pz * L2; + q0[3] -= M1; + q0[4] -= M2; + } + else { + opserr << "DispBeamColumnWarping3d::addLoad() -- load type unknown for element with tag: " << + this->getTag() << endln; + return -1; + } + + return 0; +} + +int +DispBeamColumnWarping3d::addInertiaLoadToUnbalance(const Vector &accel) +{ + // Check for a quick return + if (rho == 0.0) + return 0; + + // Get R * accel from the nodes + const Vector &Raccel1 = theNodes[0]->getRV(accel); + const Vector &Raccel2 = theNodes[1]->getRV(accel); + + if (7 != Raccel1.Size() || 7 != Raccel2.Size()) { + opserr << "DispBeamColumnWarping3d::addInertiaLoadToUnbalance matrix and vector sizes are incompatable\n"; + return -1; + } + + double L = crdTransf->getInitialLength(); + double m = 0.5*rho*L; + + // Want to add ( - fact * M R * accel ) to unbalance + // Take advantage of lumped mass matrix + Q(0) -= m*Raccel1(0); + Q(1) -= m*Raccel1(1); + Q(2) -= m*Raccel1(2); + Q(7) -= m*Raccel2(0); + Q(8) -= m*Raccel2(1); + Q(9) -= m*Raccel2(2); + + return 0; +} + +const Vector& +DispBeamColumnWarping3d::getResistingForce() +{ + double L = crdTransf->getInitialLength(); + double oneOverL=1.0/L; + double oneOverLsquare = oneOverL*oneOverL; + double oneOverLcube = oneOverLsquare*oneOverL; + static Matrix N1(6,8); + static Matrix N2(8,9); + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + //const Vector &wts = quadRule.getIntegrPointWeights(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + double wt[maxNumSections]; + beamInt->getSectionWeights(numSections, L, wt); + const Vector &v = crdTransf->getBasicTrialDisp(); + // Zero for integration + q.Zero(); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + N1.Zero(); + N2.Zero(); + + double xi6 = 6.0*xi[i]; + double xi12=12*xi[i]; + double xi1=xi[i]; + double dNv1 = 1.0+3.0*xi1*xi1-4.0*xi1; + double dNv2 = 3.0*xi1*xi1-2.0*xi1; + double dNw1 = dNv1; + double dNw2 = dNv2; + double ddNv1 = 6.0*xi1*oneOverL-4.0*oneOverL; + double ddNv2 = 6.0*xi1*oneOverL-2.0*oneOverL; + double ddNw1 = ddNv1; + double ddNw2 = ddNv2; + double Nf1 = 1.0-3.0*xi1*xi1+2.0*xi1*xi1*xi1; + double Nf2 = xi1*L*(1.0-xi1)*(1.0-xi1); + double Nf3 = 3.0*xi1*xi1-2.0*xi1*xi1*xi1; + double Nf4 = xi1*xi1*L*(xi1-1.0); + double dNf1 = 6.0*xi1*xi1*oneOverL-6.0*xi1*oneOverL; + double dNf2 = dNv1; + double dNf3 = 6.0*xi1*oneOverL-6.0*xi1*xi1*oneOverL; + double dNf4 = dNv2; + double ddNf1 = 12.0*xi1*oneOverLsquare-6.0*oneOverLsquare; + double ddNf2 = ddNv1; + double ddNf3 = 6.0*oneOverLsquare-12.0*xi1*oneOverLsquare; + double ddNf4 = ddNv2; + N1(0,0) = 1.0; + N1(0,1) = dNv1*v(1)+dNv2*v(5); + N1(0,2) = dNw1*v(2)+dNw2*v(6); + N1(1,3) = 1.0; + N1(1,4) = Nf1*v(0)+Nf2*v(3)+Nf3*v(4)+Nf4*v(7); + N1(1,5) = ddNw1*v(2)+ddNw2*v(6); + N1(2,3) = -N1(1,4); + N1(2,4) = 1.0; + N1(2,5) = -ddNv1*v(1)-ddNv2*v(5); + N1(3,6) = dNf1*v(0)+dNf2*v(3)+dNf3*v(4)+dNf4*v(7); + N1(4,7) = -1.0; + N1(5,6) = 1.0; + N2(0,8) = oneOverL; + N2(1,1) = dNv1; + N2(1,5) = dNv2; + N2(2,2) = dNw1; + N2(2,6) = dNw2; + N2(3,1) = ddNv1; + N2(3,5) = ddNv2; + N2(4,2) = ddNw1; + N2(4,6) = ddNw2; + N2(5,0) = Nf1; + N2(5,3) = Nf2; + N2(5,4) = Nf3; + N2(5,7) = Nf4; + N2(6,0) = dNf1; + N2(6,3) = dNf2; + N2(6,4) = dNf3; + N2(6,7) = dNf4; + N2(7,0) = ddNf1; + N2(7,3) = ddNf2; + N2(7,4) = ddNf3; + N2(7,7) = ddNf4; + + // Get section stress resultant + const Vector &s = theSections[i]->getStressResultant(); + + double wti=wt[i]; + /*q(0) += ((6.0-xi12)*oneOverL*s(3)+(6.0*xi1*xi1-xi6)*s(4))*wti; + q(1) += (xi6-4.0)*s(1)*wti; + q(2) += (xi6-4.0)*s(2)*wti; + q(3) += ((4.0-xi6)*s(3)+L*(1.0-4.0*xi1+3.0*xi1*xi1)*s(4))*wti; + q(4) += ((xi12-6.0)*oneOverL*s(3)+(xi6-6.0*xi1*xi1)*s(4))*wti; + q(5) += (xi6-2.0)*s(1)*wti; + q(6) += (xi6-2.0)*s(2)*wti; + q(7) += ((2.0-xi6)*s(3)+(3.0*xi1*xi1-2.0*xi1)*L*s(4))*wti; + q(8) += s(0)*wti;*/ + + + static Vector qProduct1(8); + static Vector qProduct2(9); + qProduct1.Zero(); + qProduct2.Zero(); + qProduct1.addMatrixTransposeVector(0.0, N1, s, 1.0); + qProduct2.addMatrixTransposeVector(0.0, N2, qProduct1, 1.0); + + for (int j=0; j<9; j++) + { + q(j) += qProduct2(j)*L*wti; + } + } + + q(0) += q0[0]; + q(1) += q0[1]; + q(2) += q0[2]; + q(3) += q0[3]; + q(4) += q0[4]; + + // Transform forces + Vector p0Vec(p0, 5); + P = crdTransf->getGlobalResistingForce(q, p0Vec); + + // Subtract other external nodal loads ... P_res = P_int - P_ext + P.addVector(1.0, Q, -1.0); + + return P; +} + +const Vector& +DispBeamColumnWarping3d::getResistingForceIncInertia() +{ + this->getResistingForce(); + + if (rho != 0.0) { + const Vector &accel1 = theNodes[0]->getTrialAccel(); + const Vector &accel2 = theNodes[1]->getTrialAccel(); + + // Compute the current resisting force + this->getResistingForce(); + + double L = crdTransf->getInitialLength(); + double m = 0.5*rho*L; + + P(0) += m*accel1(0); + P(1) += m*accel1(1); + P(2) += m*accel1(2); + P(7) += m*accel2(0); + P(8) += m*accel2(1); + P(9) += m*accel2(2); + + // add the damping forces if rayleigh damping + if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P += this->getRayleighDampingForces(); + + } else { + + // add the damping forces if rayleigh damping + if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P += this->getRayleighDampingForces(); + } + + return P; +} + +int +DispBeamColumnWarping3d::sendSelf(int commitTag, Channel &theChannel) +{ + // place the integer data into an ID + + int dbTag = this->getDbTag(); + int i, j; + int loc = 0; + + static ID idData(7); // one bigger than needed so no clash later + idData(0) = this->getTag(); + idData(1) = connectedExternalNodes(0); + idData(2) = connectedExternalNodes(1); + idData(3) = numSections; + idData(4) = crdTransf->getClassTag(); + int crdTransfDbTag = crdTransf->getDbTag(); + if (crdTransfDbTag == 0) { + crdTransfDbTag = theChannel.getDbTag(); + if (crdTransfDbTag != 0) + crdTransf->setDbTag(crdTransfDbTag); + } + idData(5) = crdTransfDbTag; + + if (alphaM != 0 || betaK != 0 || betaK0 != 0 || betaKc != 0) + idData(6) = 1; + else + idData(6) = 0; + + + if (theChannel.sendID(dbTag, commitTag, idData) < 0) { + opserr << "DispBeamColumnWarping3d::sendSelf() - failed to send ID data\n"; + return -1; + } + + if (idData(6) == 1) { + // send damping coefficients + static Vector dData(4); + dData(0) = alphaM; + dData(1) = betaK; + dData(2) = betaK0; + dData(3) = betaKc; + if (theChannel.sendVector(dbTag, commitTag, dData) < 0) { + opserr << "DispBeamColumnWarping3d::sendSelf() - failed to send double data\n"; + return -1; + } + } + + // send the coordinate transformation + if (crdTransf->sendSelf(commitTag, theChannel) < 0) { + opserr << "DispBeamColumnWarping3d::sendSelf() - failed to send crdTranf\n"; + return -1; + } + + + // + // send an ID for the sections containing each sections dbTag and classTag + // if section ha no dbTag get one and assign it + // + + ID idSections(2*numSections); + loc = 0; + for (i = 0; igetClassTag(); + int sectDbTag = theSections[i]->getDbTag(); + if (sectDbTag == 0) { + sectDbTag = theChannel.getDbTag(); + theSections[i]->setDbTag(sectDbTag); + } + + idSections(loc) = sectClassTag; + idSections(loc+1) = sectDbTag; + loc += 2; + } + + if (theChannel.sendID(dbTag, commitTag, idSections) < 0) { + opserr << "DispBeamColumnWarping3d::sendSelf() - failed to send ID data\n"; + return -1; + } + + // + // send the sections + // + + for (j = 0; jsendSelf(commitTag, theChannel) < 0) { + opserr << "DispBeamColumnWarping3d::sendSelf() - section " << j << "failed to send itself\n"; + return -1; + } + } + + return 0; +} + +int +DispBeamColumnWarping3d::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + // + // receive the integer data containing tag, numSections and coord transformation info + // + int dbTag = this->getDbTag(); + int i; + + static ID idData(7); // one bigger than needed so no clash with section ID + + if (theChannel.recvID(dbTag, commitTag, idData) < 0) { + opserr << "DispBeamColumnWarping3d::recvSelf() - failed to recv ID data\n"; + return -1; + } + + this->setTag(idData(0)); + connectedExternalNodes(0) = idData(1); + connectedExternalNodes(1) = idData(2); + + int crdTransfClassTag = idData(4); + int crdTransfDbTag = idData(5); + + if (idData(6) == 1) { + // recv damping coefficients + static Vector dData(4); + if (theChannel.recvVector(dbTag, commitTag, dData) < 0) { + opserr << "DispBeamColumnWarping3d::sendSelf() - failed to recv double data\n"; + return -1; + } + alphaM = dData(0); + betaK = dData(1); + betaK0 = dData(2); + betaKc = dData(3); + } + + // create a new crdTransf object if one needed + if (crdTransf == 0 || crdTransf->getClassTag() != crdTransfClassTag) { + if (crdTransf != 0) + delete crdTransf; + + crdTransf = theBroker.getNewCrdTransf(crdTransfClassTag); + + if (crdTransf == 0) { + opserr << "DispBeamColumnWarping3d::recvSelf() - " << + "failed to obtain a CrdTrans object with classTag" << + crdTransfClassTag << endln; + return -2; + } + } + + crdTransf->setDbTag(crdTransfDbTag); + + // invoke recvSelf on the crdTransf object + if (crdTransf->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "DispBeamColumnWarping3d::sendSelf() - failed to recv crdTranf\n"; + return -3; + } + + // + // recv an ID for the sections containing each sections dbTag and classTag + // + + ID idSections(2*idData(3)); + int loc = 0; + + if (theChannel.recvID(dbTag, commitTag, idSections) < 0) { + opserr << "DispBeamColumnWarping3d::recvSelf() - failed to recv ID data\n"; + return -1; + } + + // + // now receive the sections + // + + if (numSections != idData(3)) { + + // + // we do not have correct number of sections, must delete the old and create + // new ones before can recvSelf on the sections + // + + // delete the old + if (numSections != 0) { + for (int i=0; isetDbTag(sectDbTag); + if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "DispBeamColumnWarping3d::recvSelf() - section " << + i << "failed to recv itself\n"; + return -1; + } + } + + } else { + + // + // for each existing section, check it is of correct type + // (if not delete old & create a new one) then recvSelf on it + // + + loc = 0; + for (i=0; igetClassTag() != sectClassTag) { + // delete the old section[i] and create a new one + delete theSections[i]; + theSections[i] = theBroker.getNewSection(sectClassTag); + if (theSections[i] == 0) { + opserr << "DispBeamColumnWarping3d::recvSelf() - Broker could not create Section of class type" << + sectClassTag << endln; + exit(-1); + } + } + + // recvSelf on it + theSections[i]->setDbTag(sectDbTag); + if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "DispBeamColumnWarping3d::recvSelf() - section " << + i << "failed to recv itself\n"; + return -1; + } + } + } + + return 0; +} + +void +DispBeamColumnWarping3d::Print(OPS_Stream &s, int flag) +{ + s << "\nDispBeamColumnWarping3d, element id: " << this->getTag() << endln; + s << "\tConnected external nodes: " << connectedExternalNodes; + s << "\tmass density: " << rho << endln; + + double N, Mz1, Mz2, Vy, My1, My2, Vz, T; + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + N = q(0); + Mz1 = q(1); + Mz2 = q(2); + Vy = (Mz1+Mz2)*oneOverL; + My1 = q(3); + My2 = q(4); + Vz = -(My1+My2)*oneOverL; + T = q(5); + + s << "\tEnd 1 Forces (P Mz Vy My Vz T): " + << -N+p0[0] << ' ' << Mz1 << ' ' << Vy+p0[1] << ' ' << My1 << ' ' << Vz+p0[3] << ' ' << -T << endln; + s << "\tEnd 2 Forces (P Mz Vy My Vz T): " + << N << ' ' << Mz2 << ' ' << -Vy+p0[2] << ' ' << My2 << ' ' << -Vz+p0[4] << ' ' << T << endln; + + //for (int i = 0; i < numSections; i++) + //theSections[i]->Print(s,flag); +} + + +int +DispBeamColumnWarping3d::displaySelf(Renderer &theViewer, int displayMode, float fact) +{ + // first determine the end points of the quad based on + // the display factor (a measure of the distorted image) + const Vector &end1Crd = theNodes[0]->getCrds(); + const Vector &end2Crd = theNodes[1]->getCrds(); + + static Vector v1(3); + static Vector v2(3); + + if (displayMode >= 0) { + const Vector &end1Disp = theNodes[0]->getDisp(); + const Vector &end2Disp = theNodes[1]->getDisp(); + + for (int i = 0; i < 3; i++) { + v1(i) = end1Crd(i) + end1Disp(i)*fact; + v2(i) = end2Crd(i) + end2Disp(i)*fact; + } + } else { + int mode = displayMode * -1; + const Matrix &eigen1 = theNodes[0]->getEigenvectors(); + const Matrix &eigen2 = theNodes[1]->getEigenvectors(); + if (eigen1.noCols() >= mode) { + for (int i = 0; i < 3; i++) { + v1(i) = end1Crd(i) + eigen1(i,mode-1)*fact; + v2(i) = end2Crd(i) + eigen2(i,mode-1)*fact; + } + + } else { + for (int i = 0; i < 3; i++) { + v1(i) = end1Crd(i); + v2(i) = end2Crd(i); + } + } + } + return theViewer.drawLine (v1, v2, 1.0, 1.0); +} + +Response* +DispBeamColumnWarping3d::setResponse(const char **argv, int argc, OPS_Stream &output) +{ + + Response *theResponse = 0; + + output.tag("ElementOutput"); + output.attr("eleType","DispBeamColumnWarping3d"); + output.attr("eleTag",this->getTag()); + output.attr("node1",connectedExternalNodes[0]); + output.attr("node2",connectedExternalNodes[1]); + + // + // we compare argv[0] for known response types + // + + // global force - + if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0 + || strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0) { + + output.tag("ResponseType","Px_1"); + output.tag("ResponseType","Py_1"); + output.tag("ResponseType","Pz_1"); + output.tag("ResponseType","Mx_1"); + output.tag("ResponseType","My_1"); + output.tag("ResponseType","Mz_1"); + output.tag("ResponseType","Px_2"); + output.tag("ResponseType","Py_2"); + output.tag("ResponseType","Pz_2"); + output.tag("ResponseType","Mx_2"); + output.tag("ResponseType","My_2"); + output.tag("ResponseType","Mz_2"); + + + theResponse = new ElementResponse(this, 1, P); + + // local force - + } else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0) { + + output.tag("ResponseType","N_ 1"); + output.tag("ResponseType","Vy_1"); + output.tag("ResponseType","Vz_1"); + output.tag("ResponseType","T_1"); + output.tag("ResponseType","My_1"); + output.tag("ResponseType","Tz_1"); + output.tag("ResponseType","N_2"); + output.tag("ResponseType","Py_2"); + output.tag("ResponseType","Pz_2"); + output.tag("ResponseType","T_2"); + output.tag("ResponseType","My_2"); + output.tag("ResponseType","Mz_2"); + + theResponse = new ElementResponse(this, 2, P); + + // chord rotation - + } else if (strcmp(argv[0],"chordRotation") == 0 || strcmp(argv[0],"chordDeformation") == 0 + || strcmp(argv[0],"basicDeformation") == 0) { + + output.tag("ResponseType","eps"); + output.tag("ResponseType","thetaZ_1"); + output.tag("ResponseType","thetaZ_2"); + output.tag("ResponseType","thetaY_1"); + output.tag("ResponseType","thetaY_2"); + output.tag("ResponseType","thetaX"); + + theResponse = new ElementResponse(this, 3, Vector(6)); + + // plastic rotation - + } else if (strcmp(argv[0],"plasticRotation") == 0 || strcmp(argv[0],"plasticDeformation") == 0) { + + output.tag("ResponseType","epsP"); + output.tag("ResponseType","thetaZP_1"); + output.tag("ResponseType","thetaZP_2"); + output.tag("ResponseType","thetaYP_1"); + output.tag("ResponseType","thetaYP_2"); + output.tag("ResponseType","thetaXP"); + + theResponse = new ElementResponse(this, 4, Vector(6)); + + // section response - + } + else if (strstr(argv[0],"sectionX") != 0) { + if (argc > 2) { + float sectionLoc = atof(argv[1]); + + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamInt->getSectionLocations(numSections, L, xi); + + sectionLoc /= L; + + float minDistance = fabs(xi[0]-sectionLoc); + int sectionNum = 0; + for (int i = 1; i < numSections; i++) { + if (fabs(xi[i]-sectionLoc) < minDistance) { + minDistance = fabs(xi[i]-sectionLoc); + sectionNum = i; + } + } + + output.tag("GaussPointOutput"); + output.attr("number",sectionNum+1); + output.attr("eta",xi[sectionNum]*L); + + theResponse = theSections[sectionNum]->setResponse(&argv[2], argc-2, output); + } + } + else if (strcmp(argv[0],"section") ==0) { + if (argc > 2) { + + int sectionNum = atoi(argv[1]); + if (sectionNum > 0 && sectionNum <= numSections) { + + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamInt->getSectionLocations(numSections, L, xi); + + output.tag("GaussPointOutput"); + output.attr("number",sectionNum); + output.attr("eta",xi[sectionNum-1]*L); + + theResponse = theSections[sectionNum-1]->setResponse(&argv[2], argc-2, output); + + output.endTag(); + } + } + } + + output.endTag(); + return theResponse; +} + +int +DispBeamColumnWarping3d::getResponse(int responseID, Information &eleInfo) +{ + double N, V, M1, M2, T; + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + if (responseID == 1) + return eleInfo.setVector(this->getResistingForce()); + + else if (responseID == 2) { + // Axial + N = q(0); + P(6) = N; + P(0) = -N+p0[0]; + + // Torsion + T = q(5); + P(9) = T; + P(3) = -T; + + // Moments about z and shears along y + M1 = q(1); + M2 = q(2); + P(5) = M1; + P(11) = M2; + V = (M1+M2)*oneOverL; + P(1) = V+p0[1]; + P(7) = -V+p0[2]; + + // Moments about y and shears along z + M1 = q(3); + M2 = q(4); + P(4) = M1; + P(10) = M2; + V = -(M1+M2)*oneOverL; + P(2) = -V+p0[3]; + P(8) = V+p0[4]; + + return eleInfo.setVector(P); + } + + // Chord rotation + else if (responseID == 3) + return eleInfo.setVector(crdTransf->getBasicTrialDisp()); + + // Plastic rotation + else if (responseID == 4) { + static Vector vp(6); + static Vector ve(6); + const Matrix &kb = this->getInitialBasicStiff(); + kb.Solve(q, ve); + vp = crdTransf->getBasicTrialDisp(); + vp -= ve; + return eleInfo.setVector(vp); + } + + else + return -1; +} + +// AddingSensitivity:BEGIN /////////////////////////////////// +int +DispBeamColumnWarping3d::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc < 1) + return -1; + + // If the parameter belongs to the element itself + if (strcmp(argv[0],"rho") == 0) + return param.addObject(1, this); + + if (strstr(argv[0],"sectionX") != 0) { + if (argc < 3) + return -1; + + float sectionLoc = atof(argv[1]); + + double xi[maxNumSections]; + double L = crdTransf->getInitialLength(); + beamInt->getSectionLocations(numSections, L, xi); + + sectionLoc /= L; + + float minDistance = fabs(xi[0]-sectionLoc); + int sectionNum = 0; + for (int i = 1; i < numSections; i++) { + if (fabs(xi[i]-sectionLoc) < minDistance) { + minDistance = fabs(xi[i]-sectionLoc); + sectionNum = i; + } + } + return theSections[sectionNum]->setParameter(&argv[2], argc-2, param); + } + // If the parameter belongs to a section or lower + if (strstr(argv[0],"section") != 0) { + + if (argc < 3) + return -1; + + // Get section and material tag numbers from user input + int paramSectionTag = atoi(argv[1]); + + // Find the right section and call its setParameter method + int ok = 0; + for (int i = 0; i < numSections; i++) + if (paramSectionTag == theSections[i]->getTag()) + ok += theSections[i]->setParameter(&argv[2], argc-2, param); + + return ok; + } + + else if (strstr(argv[0],"integration") != 0) { + + if (argc < 2) + return -1; + + return beamInt->setParameter(&argv[1], argc-1, param); + } + + // Default, send to every object + int ok = 0; + for (int i = 0; i < numSections; i++) + ok += theSections[i]->setParameter(argv, argc, param); + ok += beamInt->setParameter(argv, argc, param); + return ok; +} + +int +DispBeamColumnWarping3d::updateParameter (int parameterID, Information &info) +{ + if (parameterID == 1) { + rho = info.theDouble; + return 0; + } + else + return -1; +} + + + + +int +DispBeamColumnWarping3d::activateParameter(int passedParameterID) +{ + parameterID = passedParameterID; + + return 0; +} + +const Matrix & +DispBeamColumnWarping3d::getKiSensitivity(int gradNumber) +{ + K.Zero(); + return K; +} + +const Matrix & +DispBeamColumnWarping3d::getMassSensitivity(int gradNumber) +{ + K.Zero(); + return K; +} + + + +const Vector & +DispBeamColumnWarping3d::getResistingForceSensitivity(int gradNumber) +{ + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + //const Vector &wts = quadRule.getIntegrPointWeights(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + double wt[maxNumSections]; + beamInt->getSectionWeights(numSections, L, wt); + + // Zero for integration + static Vector dqdh(6); + dqdh.Zero(); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + //double xi6 = 6.0*pts(i,0); + double xi6 = 6.0*xi[i]; + //double wti = wts(i); + double wti = wt[i]; + + // Get section stress resultant gradient + const Vector &dsdh = theSections[i]->getStressResultantSensitivity(gradNumber,true); + + // Perform numerical integration on internal force gradient + double sensi; + for (int j = 0; j < order; j++) { + sensi = dsdh(j)*wti; + switch(code(j)) { + case SECTION_RESPONSE_P: + dqdh(0) += sensi; + break; + case SECTION_RESPONSE_MZ: + dqdh(1) += (xi6-4.0)*sensi; + dqdh(2) += (xi6-2.0)*sensi; + break; + case SECTION_RESPONSE_MY: + dqdh(3) += (xi6-4.0)*sensi; + dqdh(4) += (xi6-2.0)*sensi; + break; + case SECTION_RESPONSE_T: + dqdh(5) += sensi; + break; + default: + break; + } + } + } + + // Transform forces + static Vector dp0dh(6); // No distributed loads + + P.Zero(); + + ////////////////////////////////////////////////////////////// + + if (crdTransf->isShapeSensitivity()) { + + // Perform numerical integration to obtain basic stiffness matrix + // Some extra declarations + static Matrix kbmine(6,6); + kbmine.Zero(); + q.Zero(); + + double tmp; + + int j, k; + + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + //double xi6 = 6.0*pts(i,0); + double xi6 = 6.0*xi[i]; + //double wti = wts(i); + double wti = wt[i]; + + const Vector &s = theSections[i]->getStressResultant(); + const Matrix &ks = theSections[i]->getSectionTangent(); + + Matrix ka(workArea, order, 6); + ka.Zero(); + + double si; + for (j = 0; j < order; j++) { + si = s(j)*wti; + switch(code(j)) { + case SECTION_RESPONSE_P: + q(0) += si; + for (k = 0; k < order; k++) { + ka(k,0) += ks(k,j)*wti; + } + break; + case SECTION_RESPONSE_MZ: + q(1) += (xi6-4.0)*si; + q(2) += (xi6-2.0)*si; + for (k = 0; k < order; k++) { + tmp = ks(k,j)*wti; + ka(k,1) += (xi6-4.0)*tmp; + ka(k,2) += (xi6-2.0)*tmp; + } + break; + case SECTION_RESPONSE_MY: + q(3) += (xi6-4.0)*si; + q(4) += (xi6-2.0)*si; + for (k = 0; k < order; k++) { + tmp = ks(k,j)*wti; + ka(k,3) += (xi6-4.0)*tmp; + ka(k,4) += (xi6-2.0)*tmp; + } + break; + case SECTION_RESPONSE_T: + q(5) += si; + for (k = 0; k < order; k++) { + ka(k,5) += ks(k,j)*wti; + } + break; + default: + break; + } + } + for (j = 0; j < order; j++) { + switch (code(j)) { + case SECTION_RESPONSE_P: + for (k = 0; k < 6; k++) { + kbmine(0,k) += ka(j,k); + } + break; + case SECTION_RESPONSE_MZ: + for (k = 0; k < 6; k++) { + tmp = ka(j,k); + kbmine(1,k) += (xi6-4.0)*tmp; + kbmine(2,k) += (xi6-2.0)*tmp; + } + break; + case SECTION_RESPONSE_MY: + for (k = 0; k < 6; k++) { + tmp = ka(j,k); + kbmine(3,k) += (xi6-4.0)*tmp; + kbmine(4,k) += (xi6-2.0)*tmp; + } + break; + case SECTION_RESPONSE_T: + for (k = 0; k < 6; k++) { + kbmine(5,k) += ka(j,k); + } + break; + default: + break; + } + } + } + + const Vector &A_u = crdTransf->getBasicTrialDisp(); + double dLdh = crdTransf->getdLdh(); + double d1overLdh = -dLdh/(L*L); + // a^T k_s dadh v + dqdh.addMatrixVector(1.0, kbmine, A_u, d1overLdh); + + // k dAdh u + const Vector &dAdh_u = crdTransf->getBasicTrialDispShapeSensitivity(); + dqdh.addMatrixVector(1.0, kbmine, dAdh_u, oneOverL); + + // dAdh^T q + P += crdTransf->getGlobalResistingForceShapeSensitivity(q, dp0dh, gradNumber); + } + + // A^T (dqdh + k dAdh u) + P += crdTransf->getGlobalResistingForce(dqdh, dp0dh); + + return P; +} + + + +// NEW METHOD +int +DispBeamColumnWarping3d::commitSensitivity(int gradNumber, int numGrads) +{ + // Get basic deformation and sensitivities + const Vector &v = crdTransf->getBasicTrialDisp(); + + static Vector dvdh(6); + dvdh = crdTransf->getBasicDisplSensitivity(gradNumber); + + double L = crdTransf->getInitialLength(); + double oneOverL = 1.0/L; + //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); + double xi[maxNumSections]; + beamInt->getSectionLocations(numSections, L, xi); + + // Some extra declarations + double d1oLdh = crdTransf->getd1overLdh(); + + // Loop over the integration points + for (int i = 0; i < numSections; i++) { + + int order = theSections[i]->getOrder(); + const ID &code = theSections[i]->getType(); + + Vector e(workArea, order); + + //double xi6 = 6.0*pts(i,0); + double xi6 = 6.0*xi[i]; + + for (int j = 0; j < order; j++) { + switch(code(j)) { + case SECTION_RESPONSE_P: + e(j) = oneOverL*dvdh(0) + + d1oLdh*v(0); + break; + case SECTION_RESPONSE_MZ: + e(j) = oneOverL*((xi6-4.0)*dvdh(1) + (xi6-2.0)*dvdh(2)) + + d1oLdh*((xi6-4.0)*v(1) + (xi6-2.0)*v(2)); + break; + case SECTION_RESPONSE_MY: + e(j) = oneOverL*((xi6-4.0)*dvdh(3) + (xi6-2.0)*dvdh(4)) + + d1oLdh*((xi6-4.0)*v(3) + (xi6-2.0)*v(4)); + break; + case SECTION_RESPONSE_T: + e(j) = oneOverL*dvdh(5) + + d1oLdh*v(5); + break; + default: + e(j) = 0.0; + break; + } + } + + // Set the section deformations + theSections[i]->commitSensitivity(e,gradNumber,numGrads); + } + + return 0; +} + + +// AddingSensitivity:END ///////////////////////////////////////////// + diff --git a/SRC/element/dispBeamColumn/DispBeamColumnWarping3d.h b/SRC/element/dispBeamColumn/DispBeamColumnWarping3d.h new file mode 100755 index 000000000..70c29964c --- /dev/null +++ b/SRC/element/dispBeamColumn/DispBeamColumnWarping3d.h @@ -0,0 +1,140 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.14 $ +// $Date: 2007/10/13 00:03:31 $ +// $Source: /usr/local/cvs/OpenSees/SRC/element/dispBeamColumn/DispBeamColumnWarping3d.h,v $ + +// Written: MHS +// Created: Feb 2001 +// +// Description: This file contains the class definition for DispBeamColumnWarping3d. +// The element displacement field gives rise to constant axial strain, +// linear curvature, and constant twist angle. + +#ifndef DispBeamColumnWarping3d_h +#define DispBeamColumnWarping3d_h + +#ifndef _bool_h +#include "bool.h" +#endif + +#include +#include +#include +#include + +class Node; +class SectionForceDeformation; +class CrdTransf; +class BeamIntegration; +class Response; + +class DispBeamColumnWarping3d : public Element +{ + public: + DispBeamColumnWarping3d(int tag, int nd1, int nd2, + int numSections, SectionForceDeformation **s, + BeamIntegration &bi, + CrdTransf &coordTransf, double rho = 0.0); + DispBeamColumnWarping3d(); + ~DispBeamColumnWarping3d(); + + const char *getClassType(void) const {return "DispBeamColumnWarping3d";}; + + int getNumExternalNodes(void) const; + const ID &getExternalNodes(void); + Node **getNodePtrs(void); + + int getNumDOF(void); + void setDomain(Domain *theDomain); + + // public methods to set the state of the element + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + // public methods to obtain stiffness, mass, damping and residual information + int update(void); + const Matrix &getTangentStiff(void); + const Matrix &getInitialStiff(void); + const Matrix &getMass(void); + + void zeroLoad(); + int addLoad(ElementalLoad *theLoad, double loadFactor); + int addInertiaLoadToUnbalance(const Vector &accel); + + const Vector &getResistingForce(void); + const Vector &getResistingForceIncInertia(void); + + // public methods for element output + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker + &theBroker); + int displaySelf(Renderer &theViewer, int displayMode, float fact); + void Print(OPS_Stream &s, int flag =0); + + Response *setResponse(const char **argv, int argc, OPS_Stream &s); + int getResponse(int responseID, Information &eleInfo); + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int setParameter(const char **argv, int argc, Parameter ¶m); + int updateParameter(int parameterID, Information &info); + int activateParameter(int parameterID); + const Vector & getResistingForceSensitivity(int gradNumber); + const Matrix & getKiSensitivity(int gradNumber); + const Matrix & getMassSensitivity(int gradNumber); + int commitSensitivity(int gradNumber, int numGrads); + // AddingSensitivity:END /////////////////////////////////////////// + + protected: + + private: + const Matrix &getInitialBasicStiff(void); + + int numSections; + SectionForceDeformation **theSections; // pointer to the ND material objects + CrdTransf *crdTransf; // pointer to coordinate tranformation object + + BeamIntegration *beamInt; + + ID connectedExternalNodes; // Tags of quad nodes + + Node *theNodes[2]; + + static Matrix K; // Element stiffness, damping, and mass Matrix + static Vector P; // Element resisting force vector + + Vector Q; // Applied nodal loads + Vector q; // Basic force + double q0[9]; // Fixed end forces in basic system (no torsion)//with torsion + double p0[5]; // Reactions in basic system (no torsion)//with torsion + + double rho; // Mass density per unit length + + int parameterID; + + enum {maxNumSections = 20}; + + static double workArea[]; +}; + +#endif + diff --git a/SRC/element/elasticBeamColumn/ElasticBeamWarping3d.cpp b/SRC/element/elasticBeamColumn/ElasticBeamWarping3d.cpp new file mode 100755 index 000000000..7ffe9f9f9 --- /dev/null +++ b/SRC/element/elasticBeamColumn/ElasticBeamWarping3d.cpp @@ -0,0 +1,1093 @@ +/* ****************************************************************** ** +** 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.20 $ +// $Date: 2008/09/23 22:50:33 $ +// $Source: /usr/local/cvs/OpenSees/SRC/element/elasticBeamColumn/ElasticBeamWarping3d.cpp,v $ + + +// File: ~/model/ElasticBeamWarping3d.C +// +// Written: fmk 11/95 +// Revised: +// +// Purpose: This file contains the class definition for ElasticBeamWarping3d. +// ElasticBeamWarping3d is a 3d beam element. As such it can only +// connect to a node with 6-dof. +// Modified by Xi Zhang from University of Sydney, Australia (include warping degrees of freedom). Refer to +// Formulation and Implementation of Three-dimensional Doubly Symmetric Beam-Column Analyses with Warping Effects in OpenSees +// Research Report R917, School of Civil Engineering, University of Sydney. + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Matrix ElasticBeamWarping3d::K(14,14); +Vector ElasticBeamWarping3d::P(14); +Matrix ElasticBeamWarping3d::kb(9,9); +using std::string; +using namespace std; + +void* OPS_ElasticBeamWarping3d(void) +{ + int numArgs = OPS_GetNumRemainingInputArgs(); + if(numArgs < 11 && numArgs != 6) { + opserr<<"insufficient arguments:eleTag,iNode,jNode,or,transfTag,Cw\n"; + return 0; + } + + int ndm = OPS_GetNDM(); + int ndf = OPS_GetNDF(); + if(ndm != 3 || ndf != 7) { + opserr<<"ndm must be 3 and ndf must be 7\n"; + return 0; + } + + // inputs: + int iData[3]; + int numData = 3; + if(OPS_GetIntInput(&numData,&iData[0]) < 0) return 0; + + SectionForceDeformation* theSection = 0; + CrdTransf* theTrans = 0; + double data[6]; + int transfTag, secTag; + + if(numArgs == 6) { + numData = 1; + if(OPS_GetIntInput(&numData,&secTag) < 0) return 0; + if(OPS_GetIntInput(&numData,&transfTag) < 0) return 0; + + theSection = OPS_getSectionForceDeformation(secTag); + if(theSection == 0) { + opserr<<"no section is found\n"; + return 0; + } + theTrans = OPS_getCrdTransf(transfTag); + if(theTrans == 0) { + opserr<<"no CrdTransf is found\n"; + return 0; + } + } else { + numData = 6; + if(OPS_GetDoubleInput(&numData,&data[0]) < 0) return 0; + numData = 1; + if(OPS_GetIntInput(&numData,&transfTag) < 0) return 0; + theTrans = OPS_getCrdTransf(transfTag); + if(theTrans == 0) { + opserr<<"no CrdTransf is found\n"; + return 0; + } + } + + // Read Cw + numData = 1; + double Cw; + if(OPS_GetDoubleInput(&numData,&Cw) < 0) + return 0; + + // options + double mass = 0.0; + int cMass = 0; + while(OPS_GetNumRemainingInputArgs() > 0) { + std::string theType = OPS_GetString(); + if (theType == "-mass") { + if(OPS_GetNumRemainingInputArgs() > 0) { + if(OPS_GetDoubleInput(&numData,&mass) < 0) return 0; + } + } + } + + if (theSection != 0) { + return new ElasticBeamWarping3d(iData[0],iData[1],iData[2],theSection,*theTrans,Cw,mass); + } else { + return new ElasticBeamWarping3d(iData[0],data[0],data[1],data[2],data[3],data[4], + data[5],iData[1],iData[2],*theTrans, Cw, mass); + } +} + +ElasticBeamWarping3d::ElasticBeamWarping3d() + :Element(0,ELE_TAG_ElasticBeamWarping3d), + A(0), E(0), G(0), Jx(0), Iy(0), Iz(0), Cw(0), rho(0.0), + Q(14), q(9), connectedExternalNodes(2), theCoordTransf(0) +{ + // does nothing + q0[0] = 0.0; + q0[1] = 0.0; + q0[2] = 0.0; + q0[3] = 0.0; + q0[4] = 0.0; + + p0[0] = 0.0; + p0[1] = 0.0; + p0[2] = 0.0; + p0[3] = 0.0; + p0[4] = 0.0; + + // set node pointers to NULL + for (int i=0; i<2; i++) + theNodes[i] = 0; +} + +ElasticBeamWarping3d::ElasticBeamWarping3d(int tag, double a, double e, double g, + double jx, double iy, double iz, int Nd1, int Nd2, + CrdTransf &coordTransf, double cw, double r) + :Element(tag,ELE_TAG_ElasticBeamWarping3d), + A(a), E(e), G(g), Jx(jx), Iy(iy), Iz(iz), Cw(cw), rho(r), + Q(14), q(9), connectedExternalNodes(2), theCoordTransf(0) +{ + connectedExternalNodes(0) = Nd1; + connectedExternalNodes(1) = Nd2; + + theCoordTransf = coordTransf.getCopy3d(); + + if (!theCoordTransf) { + opserr << "ElasticBeamWarping3d::ElasticBeamWarping3d -- failed to get copy of coordinate transformation\n"; + exit(-1); + } + + q0[0] = 0.0; + q0[1] = 0.0; + q0[2] = 0.0; + q0[3] = 0.0; + q0[4] = 0.0; + + p0[0] = 0.0; + p0[1] = 0.0; + p0[2] = 0.0; + p0[3] = 0.0; + p0[4] = 0.0; + + // set node pointers to NULL + for (int i=0; i<2; i++) + theNodes[i] = 0; +} + +ElasticBeamWarping3d::ElasticBeamWarping3d(int tag, int Nd1, int Nd2, SectionForceDeformation *section, + CrdTransf &coordTransf, double cw, double r) + :Element(tag,ELE_TAG_ElasticBeamWarping3d), Cw(cw), rho(r), + Q(14), q(9), connectedExternalNodes(2), theCoordTransf(0) +{ + if (section != 0) { + E = 1.0; + G = 1.0; + Jx = 0.0; + rho = r; + + const Matrix §Tangent = section->getSectionTangent(); + const ID §Code = section->getType(); + for (int i=0; igetNode(connectedExternalNodes(0)); + theNodes[1] = theDomain->getNode(connectedExternalNodes(1)); + + + if (theNodes[0] == 0) { + opserr << "ElasticBeamWarping3d::setDomain -- Node 1: " << connectedExternalNodes(0) << " does not exist\n"; + exit(-1); + } + + if (theNodes[1] == 0) { + opserr << "ElasticBeamWarping3d::setDomain -- Node 2: " << connectedExternalNodes(1) << " does not exist\n"; + exit(-1); + } + + int dofNd1 = theNodes[0]->getNumberDOF(); + int dofNd2 = theNodes[1]->getNumberDOF(); + + //if (dofNd1 != 6) { + // opserr << "ElasticBeamWarping3d::setDomain -- Node 1: " << connectedExternalNodes(0) + // << " has incorrect number of DOF\n"; + // exit(-1); + // } + + /*if (dofNd2 != 6) { + opserr << "ElasticBeamWarping3d::setDomain -- Node 2: " << connectedExternalNodes(1) + << " has incorrect number of DOF\n"; + exit(-1); + }*/ + + this->DomainComponent::setDomain(theDomain); + + if (theCoordTransf->initialize(theNodes[0], theNodes[1]) != 0) { + opserr << "ElasticBeamWarping3d::setDomain -- Error initializing coordinate transformation\n"; + exit(-1); + } + + double L = theCoordTransf->getInitialLength(); + + if (L == 0.0) { + opserr << "ElasticBeamWarping3d::setDomain -- Element has zero length\n"; + exit(-1); + } +} + +int +ElasticBeamWarping3d::commitState() +{ + int retVal = 0; + // call element commitState to do any base class stuff + if ((retVal = this->Element::commitState()) != 0) { + opserr << "ElasticBeamWarping3d::commitState () - failed in base class"; + } + retVal += theCoordTransf->commitState(); + return retVal; +} + +int +ElasticBeamWarping3d::revertToLastCommit() +{ + return theCoordTransf->revertToLastCommit(); +} + +int +ElasticBeamWarping3d::revertToStart() +{ + return theCoordTransf->revertToStart(); +} + +int +ElasticBeamWarping3d::update(void) +{ + return theCoordTransf->update(); +} + +const Matrix & +ElasticBeamWarping3d::getTangentStiff(void) +{ + const Vector &v = theCoordTransf->getBasicTrialDisp(); + /*for (int j=0; j<9; j++) + { + uuoutput << "v"<<"\t\t"<getInitialLength(); + double oneOverL = 1.0/L; + double EoverL = E*oneOverL; + double EAoverL = A*EoverL; // EA/L + double EIzoverL2 = 2.0*Iz*EoverL; // 2EIz/L + double EIzoverL4 = 2.0*EIzoverL2; // 4EIz/L + double EIyoverL2 = 2.0*Iy*EoverL; // 2EIy/L + double EIyoverL4 = 2.0*EIyoverL2; // 4EIy/L + double GJoverL = G*Jx*oneOverL; // GJ/L + double ECoverL3=E*Cw/L/L/L; + double ECoverL2=E*Cw/L/L; + double ECoverL=E*Cw/L; + double GJover10=G*Jx/10.0; + double GJL=G*Jx*L; + + q(0) = (12.0*ECoverL3+6.0/5.0*GJoverL)*(v(0)-v(4))+(GJover10+6.0*ECoverL2)*(v(3)+v(7)); + q(1) = EIzoverL4*v(1) + EIzoverL2*v(5); + q(2) = EIyoverL4*v(2) + EIyoverL2*v(6); + q(3) = (GJover10+6.0*ECoverL2)*(v(0)-v(4))+(4.0*ECoverL+2.0/15.0*GJL)*v(3)+(2.0*ECoverL-1.0/30.0*GJL)*v(7); + q(4) = (12.*ECoverL3+6./5.*GJoverL)*(v(4)-v(0))-(GJover10+6.*ECoverL2)*(v(3)+v(7)); + q(5) = EIzoverL2*v(1) + EIzoverL4*v(5); + q(6) = EIyoverL2*v(2) + EIyoverL4*v(6); + q(7) = (GJover10+6.*ECoverL2)*(v(0)-v(4))+(2.*ECoverL-1./30.*GJL)*v(3)+(4.*ECoverL+2./15.*GJL)*v(7); + q(8) = EAoverL*v(8); + + q(0) += q0[0]; + q(1) += q0[1]; + q(2) += q0[2]; + q(3) += q0[3]; + q(4) += q0[4]; + + kb(0,0) = 12.*ECoverL3+6./5.*GJoverL; + kb(0,3) = kb(3,0) = kb(0,7) = kb(7,0) = GJover10+6.*ECoverL2; + kb(0,4) = kb(4,0) = -12.*ECoverL3-6./5.*GJoverL; + kb(1,1) = kb(5,5) = EIzoverL4; + kb(1,5) = kb(5,1) = EIzoverL2; + kb(2,2) = kb(6,6) = EIyoverL4; + kb(2,6) = kb(6,2) = EIyoverL2; + kb(3,3) = 4.*ECoverL+2./15.*GJL; + kb(3,4) = kb(4,3) = -kb(3,0); + kb(3,7) = kb(7,3) = 2.*ECoverL-1./30.*GJL; + kb(4,4) = -kb(4,0); + kb(4,7) = kb(7,4) = -GJover10-6.*ECoverL2; + kb(7,7) = 4.*ECoverL+2./15.*GJL; + kb(8,8) = EAoverL; + + return theCoordTransf->getGlobalStiffMatrix(kb,q); +} + + +const Matrix & +ElasticBeamWarping3d::getInitialStiff(void) +{ + // const Vector &v = theCoordTransf->getBasicTrialDisp(); + double L = theCoordTransf->getInitialLength(); + //double Cw=134.46; + double oneOverL = 1.0/L; + double EoverL = E*oneOverL; + double EAoverL = A*EoverL; // EA/L + double EIzoverL2 = 2.0*Iz*EoverL; // 2EIz/L + double EIzoverL4 = 2.0*EIzoverL2; // 4EIz/L + double EIyoverL2 = 2.0*Iy*EoverL; // 2EIy/L + double EIyoverL4 = 2.0*EIyoverL2; // 4EIy/L + double GJoverL = G*Jx*oneOverL; // GJ/L + double ECoverL3=E*Cw/L/L/L; + double ECoverL2=E*Cw/L/L; + double ECoverL=E*Cw/L; + double GJover10=G*Jx/10.; + double GJL=G*Jx*L; + + + kb(0,0) = 12.*ECoverL3+6./5.*GJoverL; + kb(0,3) = kb(3,0) = kb(0,7) = kb(7,0) = GJover10+6.*ECoverL2; + kb(0,4) = kb(4,0) = -12.*ECoverL3-6./5.*GJoverL; + kb(1,1) = kb(5,5) = EIzoverL4; + kb(1,5) = kb(5,1) = EIzoverL2; + kb(2,2) = kb(6,6) = EIyoverL4; + kb(2,6) = kb(6,2) = EIyoverL2; + kb(3,3) = 4.*ECoverL+2./15.*GJL; + kb(3,4) = kb(4,3) = -kb(3,0); + kb(3,7) = kb(7,3) = 2.*ECoverL-1./30.*GJL; + kb(4,4) = -kb(4,0); + kb(4,7) = kb(7,4) = -GJover10-6.*ECoverL2; + kb(7,7) = 4.*ECoverL+2./15.*GJL; + kb(8,8) = EAoverL; + + return theCoordTransf->getInitialGlobalStiffMatrix(kb); +} + +const Matrix & +ElasticBeamWarping3d::getMass(void) +{ + K.Zero(); + + if (rho > 0.0) { + double L = theCoordTransf->getInitialLength(); + double m = 0.5*rho*L; + + K(0,0) = m; + K(1,1) = m; + K(2,2) = m; + + K(6,6) = m; + K(7,7) = m; + K(8,8) = m; + } + + return K; +} + +void +ElasticBeamWarping3d::zeroLoad(void) +{ + Q.Zero(); + + q0[0] = 0.0; + q0[1] = 0.0; + q0[2] = 0.0; + q0[3] = 0.0; + q0[4] = 0.0; + + p0[0] = 0.0; + p0[1] = 0.0; + p0[2] = 0.0; + p0[3] = 0.0; + p0[4] = 0.0; + + return; +} + +int +ElasticBeamWarping3d::addLoad(ElementalLoad *theLoad, double loadFactor) +{ + int type; + const Vector &data = theLoad->getData(type, loadFactor); + double L = theCoordTransf->getInitialLength(); + + if (type == LOAD_TAG_Beam3dUniformLoad) { + double wy = data(0)*loadFactor; // Transverse + double wz = data(1)*loadFactor; // Transverse + double wx = data(2)*loadFactor; // Axial (+ve from node I to J) + + double Vy = 0.5*wy*L; + double Mz = Vy*L/6.0; // wy*L*L/12 + double Vz = 0.5*wz*L; + double My = Vz*L/6.0; // wz*L*L/12 + double P = wx*L; + + // Reactions in basic system + p0[0] -= P; + p0[1] -= Vy; + p0[2] -= Vy; + p0[3] -= Vz; + p0[4] -= Vz; + + // Fixed end forces in basic system + q0[0] -= 0.5*P; + q0[1] -= Mz; + q0[2] += Mz; + q0[3] += My; + q0[4] -= My; + } + else if (type == LOAD_TAG_Beam3dPointLoad) { + double Py = data(0)*loadFactor; + double Pz = data(1)*loadFactor; + double N = data(2)*loadFactor; + double aOverL = data(3); + + if (aOverL < 0.0 || aOverL > 1.0) + return 0; + + double a = aOverL*L; + double b = L-a; + + // Reactions in basic system + p0[0] -= N; + double V1, V2; + V1 = Py*(1.0-aOverL); + V2 = Py*aOverL; + p0[1] -= V1; + p0[2] -= V2; + V1 = Pz*(1.0-aOverL); + V2 = Pz*aOverL; + p0[3] -= V1; + p0[4] -= V2; + + double L2 = 1.0/(L*L); + double a2 = a*a; + double b2 = b*b; + + // Fixed end forces in basic system + q0[0] -= N*aOverL; + double M1, M2; + M1 = -a * b2 * Py * L2; + M2 = a2 * b * Py * L2; + q0[1] += M1; + q0[2] += M2; + M1 = -a * b2 * Pz * L2; + M2 = a2 * b * Pz * L2; + q0[3] -= M1; + q0[4] -= M2; + } + else { + opserr << "ElasticBeamWarping3d::addLoad() -- load type unknown for element with tag: " << this->getTag() << endln; + return -1; + } + + return 0; +} + + +int +ElasticBeamWarping3d::addInertiaLoadToUnbalance(const Vector &accel) +{ + if (rho == 0.0) + return 0; + + // Get R * accel from the nodes + const Vector &Raccel1 = theNodes[0]->getRV(accel); + const Vector &Raccel2 = theNodes[1]->getRV(accel); + + if (6 != Raccel1.Size() || 6 != Raccel2.Size()) { + opserr << "ElasticBeamWarping3d::addInertiaLoadToUnbalance matrix and vector sizes are incompatable\n"; + return -1; + } + + // Want to add ( - fact * M R * accel ) to unbalance + // Take advantage of lumped mass matrix + double L = theCoordTransf->getInitialLength(); + double m = 0.5*rho*L; + + Q(0) -= m * Raccel1(0); + Q(1) -= m * Raccel1(1); + Q(2) -= m * Raccel1(2); + + Q(6) -= m * Raccel2(0); + Q(7) -= m * Raccel2(1); + Q(8) -= m * Raccel2(2); + + return 0; +} + + + +const Vector & +ElasticBeamWarping3d::getResistingForceIncInertia() +{ + P = this->getResistingForce(); + + // add the damping forces if rayleigh damping + if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0) + P += this->getRayleighDampingForces(); + + if (rho == 0.0) + return P; + + else{ + const Vector &accel1 = theNodes[0]->getTrialAccel(); + const Vector &accel2 = theNodes[1]->getTrialAccel(); + + double L = theCoordTransf->getInitialLength(); + double m = 0.5*rho*L; + + P(0) += m * accel1(0); + P(1) += m * accel1(1); + P(2) += m * accel1(2); + + P(6) += m * accel2(0); + P(7) += m * accel2(1); + P(8) += m * accel2(2); + + return P; + } +} + + +const Vector & +ElasticBeamWarping3d::getResistingForce() +{ + const Vector &v = theCoordTransf->getBasicTrialDisp(); + // opserr << "v" <getInitialLength(); + //double Cw=134.46; + double oneOverL = 1.0/L; + double EoverL = E*oneOverL; + double EAoverL = A*EoverL; // EA/L + double EIzoverL2 = 2.0*Iz*EoverL; // 2EIz/L + double EIzoverL4 = 2.0*EIzoverL2; // 4EIz/L + double EIyoverL2 = 2.0*Iy*EoverL; // 2EIy/L + double EIyoverL4 = 2.0*EIyoverL2; // 4EIy/L + double GJoverL = G*Jx*oneOverL; // GJ/L + double ECoverL3=E*Cw/L/L/L; + double ECoverL2=E*Cw/L/L; + double ECoverL=E*Cw/L; + double GJover10=G*Jx/10.; + double GJL=G*Jx*L; + + q(0) = (12.0*ECoverL3+6.0/5.0*GJoverL)*(v(0)-v(4))+(GJover10+6.0*ECoverL2)*(v(3)+v(7)); + q(1) = EIzoverL4*v(1) + EIzoverL2*v(5); + q(2) = EIyoverL4*v(2) + EIyoverL2*v(6); + q(3) = (GJover10+6.0*ECoverL2)*(v(0)-v(4))+(4.0*ECoverL+2.0/15.0*GJL)*v(3)+(2.0*ECoverL-1.0/30.0*GJL)*v(7); + q(4) = (12.*ECoverL3+6./5.*GJoverL)*(v(4)-v(0))-(GJover10+6.*ECoverL2)*(v(3)+v(7)); + q(5) = EIzoverL2*v(1) + EIzoverL4*v(5); + q(6) = EIyoverL2*v(2) + EIyoverL4*v(6); + q(7) = (GJover10+6.*ECoverL2)*(v(0)-v(4))+(2.*ECoverL-1./30.*GJL)*v(3)+(4.*ECoverL+2./15.*GJL)*v(7); + q(8) = EAoverL*v(8); + + + q(0) += q0[0]; + q(1) += q0[1]; + q(2) += q0[2]; + q(3) += q0[3]; + q(4) += q0[4]; + + Vector p0Vec(p0, 5); + + P = theCoordTransf->getGlobalResistingForce(q, p0Vec); + + // P = P - Q; + P.addVector(1.0, Q, -1.0); + + return P; +} + +int +ElasticBeamWarping3d::sendSelf(int cTag, Channel &theChannel) +{ + int res = 0; + + static Vector data(16); + + data(0) = A; + data(1) = E; + data(2) = G; + data(3) = Jx; + data(4) = Iy; + data(5) = Iz; + data(6) = rho; + data(7) = this->getTag(); + data(8) = connectedExternalNodes(0); + data(9) = connectedExternalNodes(1); + data(10) = theCoordTransf->getClassTag(); + + int dbTag = theCoordTransf->getDbTag(); + + if (dbTag == 0) { + dbTag = theChannel.getDbTag(); + if (dbTag != 0) + theCoordTransf->setDbTag(dbTag); + } + + data(11) = dbTag; + + data(12) = alphaM; + data(13) = betaK; + data(14) = betaK0; + data(15) = betaKc; + + // Send the data vector + res += theChannel.sendVector(this->getDbTag(), cTag, data); + if (res < 0) { + opserr << "ElasticBeamWarping3d::sendSelf -- could not send data Vector\n"; + return res; + } + + // Ask the CoordTransf to send itself + res += theCoordTransf->sendSelf(cTag, theChannel); + if (res < 0) { + opserr << "ElasticBeamWarping3d::sendSelf -- could not send CoordTransf\n"; + return res; + } + + return res; +} + +int +ElasticBeamWarping3d::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker) +{ + int res = 0; + static Vector data(16); + + res += theChannel.recvVector(this->getDbTag(), cTag, data); + if (res < 0) { + opserr << "ElasticBeamWarping3d::recvSelf -- could not receive data Vector\n"; + return res; + } + + A = data(0); + E = data(1); + G = data(2); + Jx = data(3); + Iy = data(4); + Iz = data(5); + rho = data(6); + this->setTag((int)data(7)); + connectedExternalNodes(0) = (int)data(8); + connectedExternalNodes(1) = (int)data(9); + + alphaM = data(12); + betaK = data(13); + betaK0 = data(14); + betaKc = data(15); + + // Check if the CoordTransf is null; if so, get a new one + int crdTag = (int)data(10); + if (theCoordTransf == 0) { + theCoordTransf = theBroker.getNewCrdTransf(crdTag); + if (theCoordTransf == 0) { + opserr << "ElasticBeamWarping3d::recvSelf -- could not get a CrdTransf3d\n"; + exit(-1); + } + } + + // Check that the CoordTransf is of the right type; if not, delete + // the current one and get a new one of the right type + if (theCoordTransf->getClassTag() != crdTag) { + delete theCoordTransf; + theCoordTransf = theBroker.getNewCrdTransf(crdTag); + if (theCoordTransf == 0) { + opserr << "ElasticBeamWarping3d::recvSelf -- could not get a CrdTransf3d\n"; + exit(-1); + } + } + + // Now, receive the CoordTransf + theCoordTransf->setDbTag((int)data(11)); + res += theCoordTransf->recvSelf(cTag, theChannel, theBroker); + if (res < 0) { + opserr << "ElasticBeamWarping3d::recvSelf -- could not receive CoordTransf\n"; + return res; + } + + // Revert the crdtrasf to its last committed state + theCoordTransf->revertToLastCommit(); + + return res; +} + +void +ElasticBeamWarping3d::Print(OPS_Stream &s, int flag) +{ + if (flag == -1) { + int eleTag = this->getTag(); + s << "EL_BEAM\t" << eleTag << "\t"; + s << "\t" << connectedExternalNodes(0) << "\t" << connectedExternalNodes(1); + s << "\t0\t0.0000000\n"; + } else if (flag < -1) { + int counter = (flag + 1) * -1; + int eleTag = this->getTag(); + const Vector &force = this->getResistingForce(); + + double P, MZ1, MZ2, VY, MY1, MY2, VZ, T; + double L = theCoordTransf->getInitialLength(); + double oneOverL = 1.0/L; + + P = q(0); + MZ1 = q(1); + MZ2 = q(2); + VY = (MZ1+MZ2)*oneOverL; + MY1 = q(3); + MY2 = q(4); + VZ = (MY1+MY2)*oneOverL; + T = q(5); + + s << "FORCE\t" << eleTag << "\t" << counter << "\t0"; + s << "\t" << -P+p0[0] << "\t" << VY+p0[1] << "\t" << -VZ+p0[3] << endln; + s << "FORCE\t" << eleTag << "\t" << counter << "\t1"; + s << "\t" << P << ' ' << -VY+p0[2] << ' ' << VZ+p0[4] << endln; + s << "MOMENT\t" << eleTag << "\t" << counter << "\t0"; + s << "\t" << -T << "\t" << MY1 << "\t" << MZ1 << endln; + s << "MOMENT\t" << eleTag << "\t" << counter << "\t1"; + s << "\t" << T << ' ' << MY2 << ' ' << MZ2 << endln; + + } + + else if (flag == 2){ + this->getResistingForce(); // in case linear algo + + static Vector xAxis(3); + static Vector yAxis(3); + static Vector zAxis(3); + + theCoordTransf->getLocalAxes(xAxis, yAxis, zAxis); + + s << "#ElasticBeamColumn3D\n"; + s << "#LocalAxis " << xAxis(0) << " " << xAxis(1) << " " << xAxis(2); + s << " " << yAxis(0) << " " << yAxis(1) << " " << yAxis(2) << " "; + s << zAxis(0) << " " << zAxis(1) << " " << zAxis(2) << endln; + + const Vector &node1Crd = theNodes[0]->getCrds(); + const Vector &node2Crd = theNodes[1]->getCrds(); + const Vector &node1Disp = theNodes[0]->getDisp(); + const Vector &node2Disp = theNodes[1]->getDisp(); + + s << "#NODE " << node1Crd(0) << " " << node1Crd(1) << " " << node1Crd(2) + << " " << node1Disp(0) << " " << node1Disp(1) << " " << node1Disp(2) + << " " << node1Disp(3) << " " << node1Disp(4) << " " << node1Disp(5) << endln; + + s << "#NODE " << node2Crd(0) << " " << node2Crd(1) << " " << node2Crd(2) + << " " << node2Disp(0) << " " << node2Disp(1) << " " << node2Disp(2) + << " " << node2Disp(3) << " " << node2Disp(4) << " " << node2Disp(5) << endln; + + double N, Mz1, Mz2, Vy, My1, My2, Vz, T; + double L = theCoordTransf->getInitialLength(); + double oneOverL = 1.0/L; + + N = q(0); + Mz1 = q(1); + Mz2 = q(2); + Vy = (Mz1+Mz2)*oneOverL; + My1 = q(3); + My2 = q(4); + Vz = -(My1+My2)*oneOverL; + T = q(5); + + s << "#END_FORCES " << -N+p0[0] << ' ' << Vy+p0[1] << ' ' << Vz+p0[3] << ' ' + << -T << ' ' << My1 << ' ' << Mz1 << endln; + s << "#END_FORCES " << N << ' ' << -Vy+p0[2] << ' ' << -Vz+p0[4] << ' ' + << T << ' ' << My2 << ' ' << Mz2 << endln; + } + else { + + this->getResistingForce(); // in case linear algo + + s << "\nElasticBeamWarping3d: " << this->getTag() << endln; + s << "\tConnected Nodes: " << connectedExternalNodes ; + s << "\tCoordTransf: " << theCoordTransf->getTag() << endln; + + double N, Mz1, Mz2, Vy, My1, My2, Vz, T; + double L = theCoordTransf->getInitialLength(); + double oneOverL = 1.0/L; + + N = q(0); + Mz1 = q(1); + Mz2 = q(2); + Vy = (Mz1+Mz2)*oneOverL; + My1 = q(3); + My2 = q(4); + Vz = -(My1+My2)*oneOverL; + T = q(5); + + s << "\tEnd 1 Forces (P Mz Vy My Vz T): " + << -N+p0[0] << ' ' << Mz1 << ' ' << Vy+p0[1] << ' ' << My1 << ' ' << Vz+p0[3] << ' ' << -T << endln; + s << "\tEnd 2 Forces (P Mz Vy My Vz T): " + << N << ' ' << Mz2 << ' ' << -Vy+p0[2] << ' ' << My2 << ' ' << -Vz+p0[4] << ' ' << T << endln; + } +} + +int +ElasticBeamWarping3d::displaySelf(Renderer &theViewer, int displayMode, float fact) +{ + // first determine the end points of the quad based on + // the display factor (a measure of the distorted image) + const Vector &end1Crd = theNodes[0]->getCrds(); + const Vector &end2Crd = theNodes[1]->getCrds(); + + static Vector v1(3); + static Vector v2(3); + + if (displayMode >= 0) { + const Vector &end1Disp = theNodes[0]->getDisp(); + const Vector &end2Disp = theNodes[1]->getDisp(); + + for (int i = 0; i < 3; i++) { + v1(i) = end1Crd(i) + end1Disp(i)*fact; + v2(i) = end2Crd(i) + end2Disp(i)*fact; + } + } else { + int mode = displayMode * -1; + const Matrix &eigen1 = theNodes[0]->getEigenvectors(); + const Matrix &eigen2 = theNodes[1]->getEigenvectors(); + if (eigen1.noCols() >= mode) { + for (int i = 0; i < 3; i++) { + v1(i) = end1Crd(i) + eigen1(i,mode-1)*fact; + v2(i) = end2Crd(i) + eigen2(i,mode-1)*fact; + } + } else { + for (int i = 0; i < 3; i++) { + v1(i) = end1Crd(i); + v2(i) = end2Crd(i); + } + } + } + + return theViewer.drawLine (v1, v2, 1.0, 1.0); +} + +Response* +ElasticBeamWarping3d::setResponse(const char **argv, int argc, OPS_Stream &output) +{ + + Response *theResponse = 0; + + output.tag("ElementOutput"); + output.attr("eleType","ElasticBeamWarping3d"); + output.attr("eleTag",this->getTag()); + output.attr("node1",connectedExternalNodes[0]); + output.attr("node2",connectedExternalNodes[1]); + + // global forces + if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0 || + strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0) { + + + output.tag("ResponseType","Px_1"); + output.tag("ResponseType","Py_1"); + output.tag("ResponseType","Pz_1"); + output.tag("ResponseType","Mx_1"); + output.tag("ResponseType","My_1"); + output.tag("ResponseType","Mz_1"); + output.tag("ResponseType","Px_2"); + output.tag("ResponseType","Py_2"); + output.tag("ResponseType","Pz_2"); + output.tag("ResponseType","Mx_2"); + output.tag("ResponseType","My_2"); + output.tag("ResponseType","Mz_2"); + + theResponse = new ElementResponse(this, 2, P); + + // local forces + } else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0) { + + output.tag("ResponseType","N_ 1"); + output.tag("ResponseType","Vy_1"); + output.tag("ResponseType","Vz_1"); + output.tag("ResponseType","T_1"); + output.tag("ResponseType","My_1"); + output.tag("ResponseType","Tz_1"); + output.tag("ResponseType","N_2"); + output.tag("ResponseType","Py_2"); + output.tag("ResponseType","Pz_2"); + output.tag("ResponseType","T_2"); + output.tag("ResponseType","My_2"); + output.tag("ResponseType","Mz_2"); + + theResponse = new ElementResponse(this, 3, P); + + // basic forces + } else if (strcmp(argv[0],"basicForce") == 0 || strcmp(argv[0],"basicForces") == 0) { + + output.tag("ResponseType","N"); + output.tag("ResponseType","Mz_1"); + output.tag("ResponseType","Mz_2"); + output.tag("ResponseType","My_1"); + output.tag("ResponseType","My_2"); + output.tag("ResponseType","T"); + + theResponse = new ElementResponse(this, 4, Vector(6)); + } + + output.endTag(); // ElementOutput + + return theResponse; +} + +int +ElasticBeamWarping3d::getResponse (int responseID, Information &eleInfo) +{ + double N, V, M1, M2, T; + double L = theCoordTransf->getInitialLength(); + double oneOverL = 1.0/L; + + switch (responseID) { + case 1: // stiffness + return eleInfo.setMatrix(this->getTangentStiff()); + + case 2: // global forces + return eleInfo.setVector(this->getResistingForce()); + + case 3: // local forces + // Axial + N = q(0); + P(6) = N; + P(0) = -N+p0[0]; + + // Torsion + T = q(5); + P(9) = T; + P(3) = -T; + + // Moments about z and shears along y + M1 = q(1); + M2 = q(2); + P(5) = M1; + P(11) = M2; + V = (M1+M2)*oneOverL; + P(1) = V+p0[1]; + P(7) = -V+p0[2]; + + // Moments about y and shears along z + M1 = q(3); + M2 = q(4); + P(4) = M1; + P(10) = M2; + V = -(M1+M2)*oneOverL; + P(2) = -V+p0[3]; + P(8) = V+p0[4]; + + return eleInfo.setVector(P); + + case 4: // basic forces + return eleInfo.setVector(q); + + default: + return -1; + } +} diff --git a/SRC/element/elasticBeamColumn/ElasticBeamWarping3d.h b/SRC/element/elasticBeamColumn/ElasticBeamWarping3d.h new file mode 100755 index 000000000..db8ec186e --- /dev/null +++ b/SRC/element/elasticBeamColumn/ElasticBeamWarping3d.h @@ -0,0 +1,117 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.10 $ +// $Date: 2007/02/02 01:30:47 $ +// $Source: /usr/local/cvs/OpenSees/SRC/element/elasticBeamColumn/ElasticBeam3d.h,v $ + + +// Written: fmk 11/95 +// Revised: +// +// Purpose: This file contains the class definition for ElasticBeam3d. +// ElasticBeam3d is a plane frame member. + +#ifndef ElasticBeam3d_h +#define ElasticBeam3d_h + +#include +#include +#include +#include + +class Channel; +class Information; +class CrdTransf; +class Response; +class Renderer; +class SectionForceDeformation; + +class ElasticBeamWarping3d : public Element +{ + public: + ElasticBeamWarping3d(); + ElasticBeamWarping3d(int tag, double A, double E, double G, + double Jx, double Iy, double Iz, int Nd1, int Nd2, + CrdTransf &theTransf, double Cw, double rho = 0.0); + + ElasticBeamWarping3d(int tag, int Nd1, int Nd2, SectionForceDeformation *section, + CrdTransf &theTransf, double Cw, double rho = 0.0); + + ~ElasticBeamWarping3d(); + + const char *getClassType(void) const {return "ElasticBeam3d";}; + + int getNumExternalNodes(void) const; + const ID &getExternalNodes(void); + Node **getNodePtrs(void); + + int getNumDOF(void); + void setDomain(Domain *theDomain); + + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + int update(void); + const Matrix &getTangentStiff(void); + const Matrix &getInitialStiff(void); + const Matrix &getMass(void); + + void zeroLoad(void); + int addLoad(ElementalLoad *theLoad, double loadFactor); + int addInertiaLoadToUnbalance(const Vector &accel); + + const Vector &getResistingForce(void); + const Vector &getResistingForceIncInertia(void); + + int sendSelf(int commitTag, Channel &theChannel); + int recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker); + + void Print(OPS_Stream &s, int flag =0); + int displaySelf(Renderer &theViewer, int displayMode, float fact); + + Response *setResponse (const char **argv, int argc, OPS_Stream &s); + int getResponse (int responseID, Information &info); + + private: + double A,E,G,Jx,Iy,Iz,Cw; + + double rho; + + static Matrix K; + static Vector P; + Vector Q; + + static Matrix kb; + Vector q; + double q0[5]; // Fixed end forces in basic system (no torsion) + double p0[5]; // Reactions in basic system (no torsion) + + Node *theNodes[2]; + + ID connectedExternalNodes; + + CrdTransf *theCoordTransf; +}; + +#endif + + diff --git a/SRC/material/section/FiberSectionWarping3d.cpp b/SRC/material/section/FiberSectionWarping3d.cpp new file mode 100755 index 000000000..f7422aa16 --- /dev/null +++ b/SRC/material/section/FiberSectionWarping3d.cpp @@ -0,0 +1,1344 @@ +/* ****************************************************************** ** +** 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.31 $ +// $Date: 2009/09/28 22:48:15 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/section/FiberSectionWarping3d.cpp,v $ + +// Written: fmk +// Created: 04/04 +// +// Description: This file contains the class implementation of FiberSectionWarping3d. +// Modified by Xi Zhang from University of Sydney, Australia (include warping degrees of freedom). Refer to +// Formulation and Implementation of Three-dimensional Doubly Symmetric Beam-Column Analyses with Warping Effects in OpenSees +// Research Report R917, School of Civil Engineering, University of Sydney. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using std::string; +using namespace std; + + +ID FiberSectionWarping3d::code(6); + +void* OPS_FiberSectionWarping3d() +{ + int numData = OPS_GetNumRemainingInputArgs(); + if(numData < 1) { + opserr<<"insufficient arguments for FiberSectionWarping3d\n"; + return 0; + } + + numData = 1; + int tag; + if (OPS_GetIntInput(&numData, &tag) < 0) return 0; + + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "WARNING torsion not specified for FiberSection\n"; + opserr << "Use either -GJ $GJ or -torsion $matTag\n"; + opserr << "\nFiberSection3d section: " << tag << endln; + return 0; + } + + UniaxialMaterial *torsion = 0; + bool deleteTorsion = false; + bool computeCentroid = true; + while (OPS_GetNumRemainingInputArgs() > 0) { + const char* opt = OPS_GetString(); + if (strcmp(opt,"-noCentroid") == 0) { + computeCentroid = false; + } + if (strcmp(opt, "-GJ") == 0 && OPS_GetNumRemainingInputArgs() > 0) { + numData = 1; + double GJ; + if (OPS_GetDoubleInput(&numData, &GJ) < 0) { + opserr << "WARNING: failed to read GJ\n"; + return 0; + } + torsion = new ElasticMaterial(0,GJ); + deleteTorsion = true; + } + if (strcmp(opt, "-torsion") == 0 && OPS_GetNumRemainingInputArgs() > 0) { + numData = 1; + int torsionTag; + if (OPS_GetIntInput(&numData, &torsionTag) < 0) { + opserr << "WARNING: failed to read torsion\n"; + return 0; + } + torsion = OPS_getUniaxialMaterial(torsionTag); + } + } + + if (torsion == 0) { + opserr << "WARNING torsion not specified for FiberSection\n"; + opserr << "\nFiberSection3d section: " << tag << endln; + return 0; + } + + int num = 30; + SectionForceDeformation *section = new FiberSectionWarping3d(tag, num, *torsion); + if (deleteTorsion) + delete torsion; + return section; +} + +// constructors: +FiberSectionWarping3d::FiberSectionWarping3d(int tag, int num, Fiber **fibers, + UniaxialMaterial &torsion): + SectionForceDeformation(tag, SEC_TAG_FiberSectionWarping3d), + numFibers(num), sizeFibers(num), theMaterials(0), matData(0), + yBar(0.0), zBar(0.0), e(8), eCommit(8), s(0), ks(0), theTorsion(0) +{ + if (numFibers != 0) { + theMaterials = new UniaxialMaterial *[numFibers]; + + if (theMaterials == 0) { + opserr << "FiberSectionWarping3d::FiberSectionWarping3d -- failed to allocate Material pointers\n"; + exit(-1); + } + + matData = new double [numFibers*4]; + + if (matData == 0) { + opserr << "FiberSectionWarping3d::FiberSectionWarping3d -- failed to allocate double array for material data\n"; + exit(-1); + } + + double Qz = 0.0; + double Qy = 0.0; + double A = 0.0; + double Heightt; + + for (int i = 0; i < numFibers; i++) { + Fiber *theFiber = fibers[i]; + double yLoc, zLoc, Area; + theFiber->getFiberLocation(yLoc, zLoc); + Area = theFiber->getArea(); + Heightt = theFiber->getd(); + + Qz += yLoc*Area; + Qy += zLoc*Area; + A += Area; + + matData[i*4] = yLoc; + matData[i*4+1] = zLoc; + matData[i*4+2] = Area; + matData[i*4+3] = Heightt; + UniaxialMaterial *theMat = theFiber->getMaterial(); + theMaterials[i] = theMat->getCopy(); + + if (theMaterials[i] == 0) { + opserr << "FiberSectionWarping3d::FiberSectionWarping3d -- failed to get copy of a Material\n"; + exit(-1); + } + } + + yBar = -Qz/A; + zBar = Qy/A; + } + + theTorsion = torsion.getCopy(); + if (theTorsion == 0) + opserr << "FiberSectionWarping3d::FiberSectionWarping3d -- failed to get copy of torsion material\n"; + + s = new Vector(sData, 6); + ks = new Matrix(kData, 6, 6); + + sData[0] = 0.0; + sData[1] = 0.0; + sData[2] = 0.0; + sData[3] = 0.0; + sData[4] = 0.0; + sData[5] = 0.0; + + for (int i=0; i<36; i++) + kData[i] = 0.0; + + code(0) = SECTION_RESPONSE_P; + code(1) = SECTION_RESPONSE_MZ; + code(2) = SECTION_RESPONSE_MY; + code(3) = SECTION_RESPONSE_W; + code(4) = SECTION_RESPONSE_B; + code(5) = SECTION_RESPONSE_T; + + // AddingSensitivity:BEGIN //////////////////////////////////// + parameterID = 0; + SHVs=0; + // AddingSensitivity:END ////////////////////////////////////// +} + +FiberSectionWarping3d::FiberSectionWarping3d(int tag, int num, UniaxialMaterial &torsion): + SectionForceDeformation(tag, SEC_TAG_FiberSectionWarping3d), + numFibers(0), sizeFibers(num), theMaterials(0), matData(0), + yBar(0.0), zBar(0.0), + e(8), eCommit(8), s(0), ks(0), theTorsion(0) +{ + if(sizeFibers != 0) { + theMaterials = new UniaxialMaterial *[sizeFibers]; + + if (theMaterials == 0) { + opserr << "FiberSection3d::FiberSection3d -- failed to allocate Material pointers\n"; + exit(-1); + } + + matData = new double [sizeFibers*4]; + + if (matData == 0) { + opserr << "FiberSection3d::FiberSection3d -- failed to allocate double array for material data\n"; + exit(-1); + } + + for (int i = 0; i < sizeFibers; i++) { + matData[i*4] = 0.0; + matData[i*4+1] = 0.0; + matData[i*4+2] = 0.0; + matData[i*4+3] = 0.0; + theMaterials[i] = 0; + } + } + + theTorsion = torsion.getCopy(); + if (theTorsion == 0) + opserr << "FiberSection3d::FiberSection3d -- failed to get copy of torsion material\n"; + + s = new Vector(sData, 6); + ks = new Matrix(kData, 6, 6); + + sData[0] = 0.0; + sData[1] = 0.0; + sData[2] = 0.0; + sData[3] = 0.0; + sData[4] = 0.0; + sData[5] = 0.0; + + for (int i=0; i<36; i++) + kData[i] = 0.0; + + code(0) = SECTION_RESPONSE_P; + code(1) = SECTION_RESPONSE_MZ; + code(2) = SECTION_RESPONSE_MY; + code(3) = SECTION_RESPONSE_W; + code(4) = SECTION_RESPONSE_B; + code(5) = SECTION_RESPONSE_T; +} + +// constructor for blank object that recvSelf needs to be invoked upon +FiberSectionWarping3d::FiberSectionWarping3d(): + SectionForceDeformation(0, SEC_TAG_FiberSectionWarping3d), + numFibers(0), theMaterials(0), matData(0), + yBar(0.0), zBar(0.0), e(8), eCommit(8), s(0), ks(0), theTorsion(0) +{ + s = new Vector(sData, 6); + ks = new Matrix(kData, 6, 6); + + sData[0] = 0.0; + sData[1] = 0.0; + sData[2] = 0.0; + sData[3] = 0.0; + sData[4] = 0.0; + sData[5] = 0.0; + + for (int i=0; i<36; i++) + kData[i] = 0.0; + + code(0) = SECTION_RESPONSE_P; + code(1) = SECTION_RESPONSE_MZ; + code(2) = SECTION_RESPONSE_MY; + code(3) = SECTION_RESPONSE_W; + code(4) = SECTION_RESPONSE_B; + code(5) = SECTION_RESPONSE_T; + + // AddingSensitivity:BEGIN //////////////////////////////////// + parameterID = 0; + SHVs=0; + // AddingSensitivity:END ////////////////////////////////////// +} + +int +FiberSectionWarping3d::addFiber(Fiber &newFiber) +{ + // need to create a larger array + int newSize = numFibers+1; + + UniaxialMaterial **newArray = new UniaxialMaterial *[newSize]; + double *newMatData = new double [4 * newSize]; + + if (newArray == 0 || newMatData == 0) { + opserr << "FiberSectionWarping3d::addFiber -- failed to allocate Fiber pointers\n"; + exit(-1); + } + + // copy the old pointers + int i; + for (i = 0; i < numFibers; i++) { + newArray[i] = theMaterials[i]; + newMatData[4*i] = matData[4*i]; + newMatData[4*i+1] = matData[4*i+1]; + newMatData[4*i+2] = matData[4*i+2]; + newMatData[4*i+3] = matData[4*i+3]; + } + // set the new pointers + double yLoc, zLoc, Area, Height; + newFiber.getFiberLocation(yLoc, zLoc); + Area = newFiber.getArea(); + Height = newFiber.getd(); + newMatData[numFibers*4] = -yLoc; + newMatData[numFibers*4+1] = zLoc; + newMatData[numFibers*4+2] = Area; + newMatData[numFibers*4+3] = Height; + UniaxialMaterial *theMat = newFiber.getMaterial(); + newArray[numFibers] = theMat->getCopy(); + + if (newArray[numFibers] == 0) { + opserr << "FiberSectionWarping3d::addFiber -- failed to get copy of a Material\n"; + exit(-1); + + delete [] newArray; + delete [] newMatData; + return -1; + } + + numFibers++; + + if (theMaterials != 0) { + delete [] theMaterials; + delete [] matData; + } + + theMaterials = newArray; + matData = newMatData; + + double Qz = 0.0; + double Qy = 0.0; + double A = 0.0; + + // Recompute centroid + for (i = 0; i < numFibers; i++) { + yLoc = -matData[4*i]; + zLoc = matData[4*i+1]; + Area = matData[4*i+2]; + Height = matData[4*i+3]; + A += Area; + Qz += yLoc*Area; + Qy += zLoc*Area; + } + + yBar = -Qz/A; + zBar = Qy/A; + + return 0; +} + + + +// destructor: +FiberSectionWarping3d::~FiberSectionWarping3d() +{ + if (theMaterials != 0) { + for (int i = 0; i < numFibers; i++) + if (theMaterials[i] != 0) + delete theMaterials[i]; + + delete [] theMaterials; + } + + if (matData != 0) + delete [] matData; + + if (s != 0) + delete s; + + if (ks != 0) + delete ks; + + if (theTorsion != 0) + delete theTorsion; +} + +int +FiberSectionWarping3d::setTrialSectionDeformation (const Vector &deforms) +{ + int res = 0; + e = deforms; + + for (int i = 0; i < 36; i++) + kData[i] = 0.0; + + sData[0] = 0.0; + sData[1] = 0.0; + sData[2] = 0.0; + sData[3] = 0.0; + sData[4] = 0.0; + sData[5] = 0.0; + + int loc = 0; + + double d0 = deforms(0); + double d1 = deforms(1); + double d2 = deforms(2); + double d3 = deforms(3); + double d4 = deforms(4); + double d5 = deforms(5); + double d6 = deforms(6); + double d7 = deforms(7); + double d8 = 0.0; // Torsion?? -- MHS + + for (int i = 0; i < numFibers; i++) { + UniaxialMaterial *theMat = theMaterials[i]; + double y = matData[loc++] - yBar; + double z = matData[loc++] - zBar; + double A = matData[loc++]; + double Height=matData[loc++]; + + // calculate sectorial area + double omig=0.0; + if (y>0.0) + omig = -z*(y-Height); + else + omig = -z* (y+Height); + + + // determine material strain and set it, include second order terms + double strain = d0 - y*d1 - z*d2 - omig*d3 + 0.5*d5*d5 + 0.5*d6*d6 + 0.5*(y*y+z*z)*d4*d4 - y*d7*d2 + z*d7*d1; + double tangent, stress; + res += theMat->setTrial(strain, stress, tangent); + + double value = tangent * A; + double vas1 = y*value; + double vas2 = z*value; + double vas1as2 = vas1*z; + + // section stiffness matrix k, refer to Alemdar + kData[0] += value; + kData[3] += (y*y+z*z)*value; + kData[6] += vas1 * y; + kData[12] += vas2 * z; + kData[15] += (y*y+z*z)*value; + kData[18] += (y*y+z*z)*(y*y+z*z)*value; + kData[24] += omig*omig*value; + + // section force vector D, refer to Alemdar + double fs0 = stress * A; + sData[0] += fs0; + sData[1] += -1.0 * fs0 * y; + sData[2] += -1.0 * fs0 * z; + sData[3] += fs0 * (y*y+z*z); + sData[4] += -fs0 * omig; + } + + if (theTorsion != 0) { + res += theTorsion->setTrial(d8, stress, tangent); + sData[5] = stress; + kData[35] = tangent; + } + + return res; +} + +const Matrix& +FiberSectionWarping3d::getInitialTangent(void) +{ + static double kInitialData[36]; + static Matrix kInitial(kInitialData, 6, 6); + for (int i=0; i<36; i++) + kInitialData[i]=0.0; + + int loc = 0; + + for (int i = 0; i < numFibers; i++) { + UniaxialMaterial *theMat = theMaterials[i]; + double y = matData[loc++] - yBar; + double z = matData[loc++] - zBar; + double A = matData[loc++]; + double Height = matData[loc++]; + // calculate sectorial area + double omig; + if (y>0.0) + omig = -z*(y-Height); + else + omig = -z* (y+Height); + + double tangent = theMat->getInitialTangent(); + + double value = tangent * A; + double vas1 = y*value; + double vas2 = z*value; + double vas1as2 = vas1*z; + + // section stiffness matrix k, refer to Alemdar + kInitialData[0] += value; + kInitialData[3] += (y*y+z*z)*value; + kInitialData[6] += vas1 * y; + kInitialData[12] += vas2 * z; + kInitialData[15] += (y*y+z*z)*value; + kInitialData[18] += (y*y+z*z)*(y*y+z*z)*value; + kInitialData[24] += omig*omig*value; + } + + if (theTorsion != 0) + kInitialData[35] = theTorsion->getInitialTangent(); + + return kInitial; +} + +const Vector& +FiberSectionWarping3d::getSectionDeformation(void) +{ + return e; +} + +const Matrix& +FiberSectionWarping3d::getSectionTangent(void) +{ + return *ks; +} + +const Vector& +FiberSectionWarping3d::getStressResultant(void) +{ + return *s; +} + +SectionForceDeformation* +FiberSectionWarping3d::getCopy(void) +{ + FiberSectionWarping3d *theCopy = new FiberSectionWarping3d (); + theCopy->setTag(this->getTag()); + + theCopy->numFibers = numFibers; + + if (numFibers != 0) { + theCopy->theMaterials = new UniaxialMaterial *[numFibers]; + + if (theCopy->theMaterials == 0) { + opserr << "FiberSectionWarping3d::FiberSectionWarping3d -- failed to allocate Material pointers\n"; + exit(-1); + } + + theCopy->matData = new double [numFibers*4]; + + if (theCopy->matData == 0) { + opserr << "FiberSectionWarping3d::FiberSectionWarping3d -- failed to allocate double array for material data\n"; + exit(-1); + } + + + for (int i = 0; i < numFibers; i++) { + theCopy->matData[i*4] = matData[i*4]; + theCopy->matData[i*4+1] = matData[i*4+1]; + theCopy->matData[i*4+2] = matData[i*4+2]; + theCopy->matData[i*4+3] = matData[i*4+3]; + theCopy->theMaterials[i] = theMaterials[i]->getCopy(); + + if (theCopy->theMaterials[i] == 0) { + opserr << "FiberSectionWarping3d::getCopy -- failed to get copy of a Material\n"; + exit(-1); + } + } + } + + theCopy->eCommit = eCommit; + theCopy->e = e; + theCopy->yBar = yBar; + theCopy->zBar = zBar; + + for (int i=0; i<36; i++) + theCopy->kData[i] = kData[i]; + + theCopy->sData[0] = sData[0]; + theCopy->sData[1] = sData[1]; + theCopy->sData[2] = sData[2]; + theCopy->sData[3] = sData[3]; + theCopy->sData[4] = sData[4]; + theCopy->sData[5] = sData[5]; + + if (theTorsion != 0) + theCopy->theTorsion = theTorsion->getCopy(); + else + theCopy->theTorsion = 0; + + return theCopy; +} + +const ID& +FiberSectionWarping3d::getType () +{ + return code; +} + +int +FiberSectionWarping3d::getOrder () const +{ + return 5; +} + +int +FiberSectionWarping3d::commitState(void) +{ + int err = 0; + + for (int i = 0; i < numFibers; i++) + err += theMaterials[i]->commitState(); + + if (theTorsion != 0) + err += theTorsion->commitState(); + + eCommit = e; + + return err; +} + +int +FiberSectionWarping3d::revertToLastCommit(void) +{ + int err = 0; + + // Last committed section deformations + e = eCommit; + + for (int i = 0; i < 36; i++) + kData[i] = 0.0; + + sData[0] = 0.0; + sData[1] = 0.0; + sData[2] = 0.0; + sData[3] = 0.0; + sData[4] = 0.0; + sData[5] = 0.0; + + int loc = 0; + + for (int i = 0; i < numFibers; i++) { + UniaxialMaterial *theMat = theMaterials[i]; + double y = matData[loc++] - yBar; + double z = matData[loc++] - zBar; + double A = matData[loc++]; + double Height = matData[loc++]; + + // invoke revertToLast on the material + err += theMat->revertToLastCommit(); + + double tangent = theMat->getTangent(); + double stress = theMat->getStress(); + + double value = tangent * A; + double vas1 = y*value; + double vas2 = z*value; + double vas1as2 = vas1*z; + double omig; + if (y>0.0) + omig = -z*(y-Height); + else + omig = -z* (y+Height); + + kData[0] += value; + kData[3] += (y*y+z*z)*value; + kData[6] += vas1 * y; + kData[12] += vas2 * z; + kData[15] += (y*y+z*z)*value; + kData[18] += (y*y+z*z)*(y*y+z*z)*value; + kData[24] += omig*omig*value; + + double fs0 = stress * A; + + sData[0] += fs0; + sData[1] += -1.0 * fs0 * y; + sData[2] += -1.0 * fs0 * z; + sData[3] += fs0 * (y*y+z*z); + sData[4] += -fs0 * omig; + } + + if (theTorsion != 0) { + err += theTorsion->revertToLastCommit(); + sData[5] = theTorsion->getStress(); + kData[35] = theTorsion->getTangent(); + } else { + sData[5] = 0.0; + kData[35] = 0.0; + } + + return err; +} + +int +FiberSectionWarping3d::revertToStart(void) +{ + // revert the fibers to start + int err = 0; + + for (int i = 0; i < 36; i++) + kData[i] = 0.0; + + sData[0] = 0.0; + sData[1] = 0.0; + sData[2] = 0.0; + sData[3] = 0.0; + sData[4] = 0.0; + sData[5] = 0.0; + + int loc = 0; + + for (int i = 0; i < numFibers; i++) { + UniaxialMaterial *theMat = theMaterials[i]; + double y = matData[loc++] - yBar; + double z = matData[loc++] - zBar; + double A = matData[loc++]; + double Height = matData[loc++]; + double omig; + if (y>0.0) + omig = -z*(y-Height); + else + omig = -z* (y+Height); + + // invoke revertToStart on the material + err += theMat->revertToStart(); + + double tangent = theMat->getTangent(); + double stress = theMat->getStress(); + + double value = tangent * A; + double vas1 = y*value; + double vas2 = z*value; + double vas1as2 = vas1*z; + + kData[0] += value; + kData[3] += (y*y+z*z)*value; + kData[6] += vas1 * y; + kData[12] += vas2 * z; + kData[15] += (y*y+z*z)*value; + kData[18] += (y*y+z*z)*(y*y+z*z)*value; + kData[24] += omig*omig*value; + + double fs0 = stress * A; + + sData[0] += fs0; + sData[1] += -1.0 * fs0 * y; + sData[2] += -1.0 * fs0 * z; + sData[3] += fs0 * (y*y+z*z); + sData[4] += -fs0 * omig; + } + + if (theTorsion != 0) { + err += theTorsion->revertToStart(); + kData[35] = theTorsion->getTangent(); + sData[5] = theTorsion->getStress(); + } else { + kData[35] = 0.0; + sData[5] = 0.0; + } + + return err; +} + +int +FiberSectionWarping3d::sendSelf(int commitTag, Channel &theChannel) +{ + int res = 0; + + // create an id to send objects tag and numFibers, + // size 5 so no conflict with matData below if just 1 fiber + static ID data(5); + data(0) = this->getTag(); + data(1) = numFibers; + data(2) = (theTorsion != 0) ? 1 : 0; + int dbTag = this->getDbTag(); + if (theTorsion != 0) { + theTorsion->setDbTag(dbTag); + data(3) = theTorsion->getClassTag(); + } + res += theChannel.sendID(dbTag, commitTag, data); + if (res < 0) { + opserr << "FiberSectionWarping3d::sendSelf - failed to send ID data\n"; + return res; + } + + if (theTorsion != 0) + theTorsion->sendSelf(commitTag, theChannel); + + if (numFibers != 0) { + + // create an id containingg classTag and dbTag for each material & send it + ID materialData(2*numFibers); + for (int i=0; igetClassTag(); + int matDbTag = theMat->getDbTag(); + if (matDbTag == 0) { + matDbTag = theChannel.getDbTag(); + if (matDbTag != 0) + theMat->setDbTag(matDbTag); + } + materialData(2*i+1) = matDbTag; + } + + res += theChannel.sendID(dbTag, commitTag, materialData); + if (res < 0) { + opserr << "FiberSectionWarping3d::sendSelf - failed to send material data\n"; + return res; + } + + // send the fiber data, i.e. area and loc + Vector fiberData(matData, 4*numFibers); + res += theChannel.sendVector(dbTag, commitTag, fiberData); + if (res < 0) { + opserr << "FiberSectionWarping3d::sendSelf - failed to send material data\n"; + return res; + } + + // now invoke send(0 on all the materials + for (int j=0; jsendSelf(commitTag, theChannel); + } + + return res; +} + +int +FiberSectionWarping3d::recvSelf(int commitTag, Channel &theChannel, + FEM_ObjectBroker &theBroker) +{ + int res = 0; + + static ID data(5); + + int dbTag = this->getDbTag(); + res += theChannel.recvID(dbTag, commitTag, data); + + if (res < 0) { + opserr << "FiberSectionWarping3d::sendSelf - failed to recv ID data\n"; + return res; + } + + this->setTag(data(0)); + + if (data(2) == 1 && theTorsion == 0) { + int cTag = data(3); + theTorsion = theBroker.getNewUniaxialMaterial(cTag); + if (theTorsion == 0) { + opserr << "FiberSectionWarping3d::recvSelf - failed to get torsion material \n"; + return -1; + } + theTorsion->setDbTag(dbTag); + } + + if (theTorsion->recvSelf(commitTag, theChannel, theBroker) < 0) { + opserr << "FiberSectionWarping3d::recvSelf - torsion failed to recvSelf \n"; + return -2; + } + + // recv data about materials objects, classTag and dbTag + if (data(1) != 0) { + ID materialData(2*data(1)); + res += theChannel.recvID(dbTag, commitTag, materialData); + if (res < 0) { + opserr << "FiberSectionWarping3d::sendSelf - failed to send material data\n"; + return res; + } + + // if current arrays not of correct size, release old and resize + if (theMaterials == 0 || numFibers != data(1)) { + // delete old stuff if outa date + if (theMaterials != 0) { + for (int i=0; igetClassTag() != classTag) { + delete theMaterials[i]; + theMaterials[i] = theBroker.getNewUniaxialMaterial(classTag); + } + + if (theMaterials[i] == 0) { + opserr << "FiberSectionWarping3d::recvSelf -- failed to allocate double array for material data\n"; + exit(-1); + } + + theMaterials[i]->setDbTag(dbTag); + res += theMaterials[i]->recvSelf(commitTag, theChannel, theBroker); + } + + double Qz = 0.0; + double Qy = 0.0; + double A = 0.0; + double yLoc, zLoc, Area;//, Height; + + // Recompute centroid + for (i = 0; i < numFibers; i++) { + yLoc = -matData[4*i]; + zLoc = matData[4*i+1]; + Area = matData[4*i+2]; + //Height=matData[4*i+3]; + A += Area; + Qz += yLoc*Area; + Qy += zLoc*Area; + } + + yBar = -Qz/A; + zBar = Qy/A; + } + + return res; +} + +void +FiberSectionWarping3d::Print(OPS_Stream &s, int flag) +{ + if (flag == 2) { + for (int i = 0; i < numFibers; i++) { + s << -matData[4*i] << " " << matData[4*i+1] << " " << matData[4*i+2] << " " ; + s << theMaterials[i]->getStress() << " " << theMaterials[i]->getStrain() << endln; + } + } else { + s << "\nFiberSectionWarping3d, tag: " << this->getTag() << endln; + s << "\tSection code: " << code; + s << "\tNumber of Fibers: " << numFibers << endln; + s << "\tCentroid: (" << -yBar << ", " << zBar << ')' << endln; + + if (flag == 1) { + for (int i = 0; i < numFibers; i++) { + s << "\nLocation (y, z) = (" << -matData[4*i] << ", " << matData[4*i+1] << ")"; + s << "\nArea = " << matData[4*i+2] << endln; + theMaterials[i]->Print(s, flag); + } + } + } +} + +Response* +FiberSectionWarping3d::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 i=0; igetOrder())); + + } + + 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[4*j]; + zSearch = matData[4*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[4*j]; + zSearch = matData[4*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[4*j]; + zSearch = matData[4*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[4*key]); + output.attr("zLoc",matData[4*key+1]); + output.attr("area",matData[4*key+2]); + + theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, output); + + output.endTag(); + } + } + } + + output.endTag(); + return theResponse; +} + + +int +FiberSectionWarping3d::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, sectInfo); +} + +int +FiberSectionWarping3d::setParameter(const char **argv, int argc, Parameter ¶m) +{ + if (argc < 3) + return -1; + + + int result = 0; + + // A material parameter + if (strstr(argv[0],"material") != 0) { + + // Get the tag of the material + int paramMatTag = atoi(argv[1]); + + // Loop over fibers to find the right material(s) + int ok = 0; + for (int i = 0; i < numFibers; i++) + if (paramMatTag == theMaterials[i]->getTag()) { + ok = theMaterials[i]->setParameter(&argv[2], argc-2, param); + if (ok != -1) + result = ok; + } + + return result; + } + + int ok = 0; + + // loop over every material + for (int i = 0; i < numFibers; i++) { + ok = theMaterials[i]->setParameter(argv, argc, param); + if (ok != -1) + result = ok; + } + + return result; +} + +const Vector & +FiberSectionWarping3d::getSectionDeformationSensitivity(int gradIndex) +{ + static Vector dummy(3); + dummy.Zero(); + if (SHVs !=0) { + dummy(0) = (*SHVs)(0,gradIndex); + dummy(1) = (*SHVs)(1,gradIndex); + dummy(2) = (*SHVs)(2,gradIndex); + } + return dummy; +} + + +const Vector & +FiberSectionWarping3d::getStressResultantSensitivity(int gradIndex, bool conditional) +{ + + static Vector ds(3); + + ds.Zero(); + + double stressGradient; + int loc = 0; + + + for (int i = 0; i < numFibers; i++) { + UniaxialMaterial *theMat = theMaterials[i]; + double y = matData[loc++] - yBar; + double z = matData[loc++] - zBar; + double A = matData[loc++]; + stressGradient = theMaterials[i]->getStressSensitivity(gradIndex,conditional); + stressGradient *= A; + ds(0) += stressGradient; + ds(1) += stressGradient * y; + ds(2) += stressGradient * z; + + } + + return ds; +} + +const Matrix & +FiberSectionWarping3d::getSectionTangentSensitivity(int gradIndex) +{ + static Matrix something(2,2); + + something.Zero(); + + return something; +} + +int +FiberSectionWarping3d::commitSensitivity(const Vector& defSens, int gradIndex, int numGrads) +{ + + // here add SHVs to store the strain sensitivity. + + if (SHVs == 0) { + SHVs = new Matrix(3,numGrads); + } + + (*SHVs)(0,gradIndex) = defSens(0); + (*SHVs)(1,gradIndex) = defSens(1); + (*SHVs)(2,gradIndex) = defSens(2); + + int loc = 0; + + double d0 = defSens(0); + double d1 = defSens(1); + double d2 = defSens(2); + + for (int i = 0; i < numFibers; i++) { + UniaxialMaterial *theMat = theMaterials[i]; + double y = matData[loc++] - yBar; + double z = matData[loc++] - zBar; + loc++; // skip A data. + + double strainSens = d0 + y*d1 + z*d2; + + theMat->commitSensitivity(strainSens,gradIndex,numGrads); + } + + return 0; +} + +// AddingSensitivity:END /////////////////////////////////// + + diff --git a/SRC/material/section/FiberSectionWarping3d.h b/SRC/material/section/FiberSectionWarping3d.h new file mode 100755 index 000000000..3cd40e19c --- /dev/null +++ b/SRC/material/section/FiberSectionWarping3d.h @@ -0,0 +1,122 @@ +/* ****************************************************************** ** +** OpenSees - Open System for Earthquake Engineering Simulation ** +** Pacific Earthquake Engineering Research Center ** +** ** +** ** +** (C) Copyright 1999, The Regents of the University of California ** +** All Rights Reserved. ** +** ** +** Commercial use of this program without express permission of the ** +** University of California, Berkeley, is strictly prohibited. See ** +** file 'COPYRIGHT' in main directory for information on usage and ** +** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** +** ** +** Developed by: ** +** Frank McKenna (fmckenna@ce.berkeley.edu) ** +** Gregory L. Fenves (fenves@ce.berkeley.edu) ** +** Filip C. Filippou (filippou@ce.berkeley.edu) ** +** ** +** ****************************************************************** */ + +// $Revision: 1.14 $ +// $Date: 2008/08/26 16:47:42 $ +// $Source: /usr/local/cvs/OpenSees/SRC/material/section/FiberSectionWarping3d.h,v $ + +// Written: fmk +// Created: 04/01 +// +// Description: This file contains the class definition for +// FiberSectionWarping3d.h. FiberSectionWarping3d provides the abstraction of a +// 3d beam section discretized by fibers. The section stiffness and +// stress resultants are obtained by summing fiber contributions. + +#ifndef FiberSectionWarping3d_h +#define FiberSectionWarping3d_h + +#include +#include +#include + +class UniaxialMaterial; +class Fiber; +class Response; +class SectionIntegration; + +class FiberSectionWarping3d : public SectionForceDeformation +{ + public: + FiberSectionWarping3d(); + FiberSectionWarping3d(int tag, int numFibers, Fiber **fibers, UniaxialMaterial &torsion); + FiberSectionWarping3d(int tag, int numFibers, UniaxialMaterial &torsion); + FiberSectionWarping3d(int tag, int numFibers, UniaxialMaterial **mats, + SectionIntegration &si, UniaxialMaterial &torsion); + ~FiberSectionWarping3d(); + + const char *getClassType(void) const {return "FiberSectionWarping3d";}; + + int setTrialSectionDeformation(const Vector &deforms); + const Vector &getSectionDeformation(void); + + const Vector &getStressResultant(void); + const Matrix &getSectionTangent(void); + const Matrix &getInitialTangent(void); + + int commitState(void); + int revertToLastCommit(void); + int revertToStart(void); + + SectionForceDeformation *getCopy(void); + const ID &getType (void); + int getOrder (void) const; + + int sendSelf(int cTag, Channel &theChannel); + int recvSelf(int cTag, Channel &theChannel, + FEM_ObjectBroker &theBroker); + void Print(OPS_Stream &s, int flag = 0); + + Response *setResponse(const char **argv, int argc, + OPS_Stream &s); + int getResponse(int responseID, Information &info); + + int addFiber(Fiber &theFiber); + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int setParameter(const char **argv, int argc, Parameter ¶m); + + const Vector & getStressResultantSensitivity(int gradIndex, bool conditional); + const Matrix & getSectionTangentSensitivity(int gradIndex); + int commitSensitivity(const Vector& sectionDeformationGradient, int gradIndex, int numGrads); + + const Vector & getSectionDeformationSensitivity(int gradIndex); + // AddingSensitivity:END /////////////////////////////////////////// + + + + protected: + + private: + int numFibers, sizeFibers; // number of fibers in the section + UniaxialMaterial **theMaterials; // array of pointers to materials + double *matData; // data for the materials [yloc and area] + double kData[25]; // data for ks matrix + double sData[5]; // data for s vector + // double Height; + double yBar; // Section centroid + double zBar; + + static ID code; + + Vector e; // trial section deformations + Vector eCommit; // committed section deformations + Vector *s; // section resisting forces (axial force, bending moment) + Matrix *ks; // section stiffness + + UniaxialMaterial *theTorsion; + + // AddingSensitivity:BEGIN ////////////////////////////////////////// + int parameterID; + Matrix *SHVs; + // AddingSensitivity:END /////////////////////////////////////////// +}; + +#endif From 48c50edacaa762551b9c9ba7dbc75f9b871fc7b3 Mon Sep 17 00:00:00 2001 From: mhscott Date: Sun, 28 Mar 2021 19:41:22 -0700 Subject: [PATCH 021/207] Modifying files for U.Sydney warping elements --- SRC/Makefile | 6 ++- SRC/classTags.h | 2 +- SRC/coordTransformation/CrdTransf.cpp | 2 +- SRC/coordTransformation/CrdTransf.h | 8 +++- SRC/coordTransformation/Makefile | 1 + SRC/element/dispBeamColumn/Makefile | 1 + SRC/element/elasticBeamColumn/Makefile | 1 + SRC/interpreter/OpenSeesCrdTransfCommands.cpp | 5 ++- SRC/interpreter/OpenSeesElementCommands.cpp | 4 ++ SRC/interpreter/OpenSeesSectionCommands.cpp | 39 ++++++++++++++++++- SRC/material/section/Makefile | 1 + .../section/SectionForceDeformation.h | 2 + SRC/material/section/fiber/Fiber.h | 1 + SRC/material/section/fiber/NDFiber2d.h | 3 +- SRC/material/section/fiber/NDFiber3d.cpp | 8 ++-- SRC/material/section/fiber/NDFiber3d.h | 9 +++-- SRC/material/section/fiber/UniaxialFiber2d.h | 3 +- .../section/fiber/UniaxialFiber3d.cpp | 8 ++-- SRC/material/section/fiber/UniaxialFiber3d.h | 6 ++- SRC/material/section/repres/cell/Cell.h | 3 +- .../section/repres/cell/CircSectionCell.cpp | 4 ++ .../section/repres/cell/CircSectionCell.h | 1 + SRC/material/section/repres/cell/QuadCell.cpp | 7 +++- SRC/material/section/repres/cell/QuadCell.h | 3 +- 24 files changed, 104 insertions(+), 24 deletions(-) diff --git a/SRC/Makefile b/SRC/Makefile index b84d17ca0..88f91c169 100644 --- a/SRC/Makefile +++ b/SRC/Makefile @@ -247,7 +247,8 @@ REMO_LIBS = $(FE)/element/nonlinearBeamColumn/matrixutil/MatrixUtil.o \ $(FE)/coordTransformation/CorotCrdTransfWarping2d.o \ $(FE)/coordTransformation/LinearCrdTransf3d.o \ $(FE)/coordTransformation/PDeltaCrdTransf3d.o \ - $(FE)/coordTransformation/CorotCrdTransf3d.o + $(FE)/coordTransformation/CorotCrdTransf3d.o \ + $(FE)/coordTransformation/CorotCrdTransfWarping3d.o LAW_LIBS = $(FE)/system_of_eqn/linearSOE/sparseSYM/SymSparseLinSOE.o \ $(FE)/system_of_eqn/linearSOE/sparseSYM/SymSparseLinSolver.o \ @@ -511,6 +512,7 @@ ELE_LIBS = $(FE)/element/Element.o \ $(FE)/element/dispBeamColumn/DispBeamColumnNL2d.o \ $(FE)/element/dispBeamColumn/DispBeamColumn2dThermal.o \ $(FE)/element/dispBeamColumn/DispBeamColumn3d.o \ + $(FE)/element/dispBeamColumn/DispBeamColumnWarping3d.o \ $(FE)/element/dispBeamColumn/DispBeamColumn3dThermal.o \ $(FE)/element/dispBeamColumn/DispBeamColumn2dWithSensitivity.o \ $(FE)/element/dispBeamColumn/DispBeamColumn3dWithSensitivity.o \ @@ -520,6 +522,7 @@ ELE_LIBS = $(FE)/element/Element.o \ $(FE)/element/elasticBeamColumn/ElasticBeam2d.o \ $(FE)/element/elasticBeamColumn/ModElasticBeam2d.o \ $(FE)/element/elasticBeamColumn/ElasticBeam3d.o \ + $(FE)/element/elasticBeamColumn/ElasticBeamWarping3d.o \ $(FE)/element/elasticBeamColumn/ElasticTimoshenkoBeam2d.o \ $(FE)/element/elasticBeamColumn/ElasticTimoshenkoBeam3d.o \ $(FE)/element/elasticBeamColumn/WheelRail.o \ @@ -1014,6 +1017,7 @@ SECTION_LIBS = $(FE)/material/section/SectionForceDeformation.o \ $(FE)/material/section/MembranePlateFiberSectionThermal.o \ $(FE)/material/section/FiberSectionGJThermal.o \ $(FE)/material/section/FiberSection3d.o \ + $(FE)/material/section/FiberSectionWarping3d.o \ $(FE)/material/section/NDFiberSection3d.o \ $(FE)/material/section/SectionAggregator.o \ $(FE)/material/section/ParallelSection.o \ diff --git a/SRC/classTags.h b/SRC/classTags.h index 8f3076979..a492f930a 100644 --- a/SRC/classTags.h +++ b/SRC/classTags.h @@ -560,7 +560,7 @@ #define ELE_TAG_ElasticBeam2d 3 #define ELE_TAG_ModElasticBeam2d 4 #define ELE_TAG_ElasticBeam3d 5 -#define ELE_TAG_ElasticWarpingBeam3d 5001 +#define ELE_TAG_ElasticBeamWarping3d 5001 #define ELE_TAG_Beam2d 6 #define ELE_TAG_beam2d02 7 #define ELE_TAG_beam2d03 8 diff --git a/SRC/coordTransformation/CrdTransf.cpp b/SRC/coordTransformation/CrdTransf.cpp index e4bb7cbca..6bfa6192d 100644 --- a/SRC/coordTransformation/CrdTransf.cpp +++ b/SRC/coordTransformation/CrdTransf.cpp @@ -29,7 +29,7 @@ // Description: This file contains the implementation for the CrdTransf class. // CrdTransf provides the abstraction of a frame // coordinate transformation. It is an abstract base class and -// thus no objects of it's type can be instatiated. +// thus no objects of its type can be instatiated. #include #include diff --git a/SRC/coordTransformation/CrdTransf.h b/SRC/coordTransformation/CrdTransf.h index 696f51931..848e757f0 100644 --- a/SRC/coordTransformation/CrdTransf.h +++ b/SRC/coordTransformation/CrdTransf.h @@ -30,7 +30,7 @@ // CrdTransf.h. CrdTransf provides the abstraction of a frame // coordinate transformation. It is an abstract base class and // thus no objects of it's type can be instatiated. It has pure -// virtual functions which must be implemented in it's derived classes. +// virtual functions which must be implemented in its derived classes. // // What: "@(#) CrdTransf.h, revA" @@ -43,6 +43,7 @@ class Vector; class Matrix; class Node; +class Response; // class definition @@ -95,6 +96,11 @@ class CrdTransf: public TaggedObject, public MovableObject virtual const Vector &getPointGlobalCoordFromLocal(const Vector &localCoords) = 0; virtual const Vector &getPointGlobalDisplFromBasic(double xi, const Vector &basicDisps) = 0; virtual const Vector &getPointLocalDisplFromBasic(double xi, const Vector &basicDisps) = 0; + + // method for obtaining information specific to a coordinate transformation + virtual Response *setResponse(const char **argv, int argc, + OPS_Stream &theHandler) {return 0;} + virtual int getResponse(int responseID, Information &eleInformation) {return -1;} protected: diff --git a/SRC/coordTransformation/Makefile b/SRC/coordTransformation/Makefile index ce0599c63..ca4e7713c 100644 --- a/SRC/coordTransformation/Makefile +++ b/SRC/coordTransformation/Makefile @@ -11,6 +11,7 @@ OBJS = CrdTransf.o \ CorotCrdTransf2d.o \ CorotCrdTransf3d.o \ CorotCrdTransfWarping2d.o \ + CorotCrdTransfWarping3d.o \ TclGeomTransfCommand.o # Compilation control diff --git a/SRC/element/dispBeamColumn/Makefile b/SRC/element/dispBeamColumn/Makefile index 9154ddf2b..ea473f780 100644 --- a/SRC/element/dispBeamColumn/Makefile +++ b/SRC/element/dispBeamColumn/Makefile @@ -7,6 +7,7 @@ OBJS = DispBeamColumn2d.o \ DispBeamColumnNL2d.o \ DispBeamColumn2dWithSensitivity.o \ DispBeamColumn3dWithSensitivity.o \ + DispBeamColumnWarping3d.o \ AxEqDispBeamColumn2d.o \ TimoshenkoBeamColumn2d.o \ DispBeamColumn3dID.o diff --git a/SRC/element/elasticBeamColumn/Makefile b/SRC/element/elasticBeamColumn/Makefile index 24b20b72c..381515bcf 100644 --- a/SRC/element/elasticBeamColumn/Makefile +++ b/SRC/element/elasticBeamColumn/Makefile @@ -6,6 +6,7 @@ OBJS = ElasticBeam2d.o \ ElasticTimoshenkoBeam2d.o \ ElasticTimoshenkoBeam3d.o \ WheelRail.o \ + ElasticBeamWarping3d.o \ TclElasticBeamCommand.o # Compilation control diff --git a/SRC/interpreter/OpenSeesCrdTransfCommands.cpp b/SRC/interpreter/OpenSeesCrdTransfCommands.cpp index d46fc64eb..8e1c02fc6 100644 --- a/SRC/interpreter/OpenSeesCrdTransfCommands.cpp +++ b/SRC/interpreter/OpenSeesCrdTransfCommands.cpp @@ -18,6 +18,7 @@ void* OPS_PDeltaCrdTransf2d(); void* OPS_PDeltaCrdTransf3d(); void* OPS_CorotCrdTransf2d(); void* OPS_CorotCrdTransf3d(); +void* OPS_CorotCrdTransfWarping3d(); namespace { static void* OPS_LinearCrdTransf() @@ -55,7 +56,9 @@ namespace { return OPS_CorotCrdTransf2d(); } else if(ndm == 3 && ndf == 6) { return OPS_CorotCrdTransf3d(); - } else { + } else if(ndm == 3 && ndf == 7) { + return OPS_CorotCrdTransfWarping3d(); + } else { opserr<<"current NDM and NDF is incompatible with frame elements\n"; return 0; } diff --git a/SRC/interpreter/OpenSeesElementCommands.cpp b/SRC/interpreter/OpenSeesElementCommands.cpp index a8ae33a78..226c6c8d8 100644 --- a/SRC/interpreter/OpenSeesElementCommands.cpp +++ b/SRC/interpreter/OpenSeesElementCommands.cpp @@ -140,6 +140,7 @@ void* OPS_PFEMElement2Dmini(const ID& info); void* OPS_fElmt02(); void* OPS_ElasticBeam2d(const ID& info); void* OPS_ElasticBeam3d(); +void* OPS_ElasticBeamWarping3d(); void* OPS_DispBeamColumn2dInt(); void* OPS_ForceBeamColumn2d(const ID& info); void* OPS_NonlinearBeamColumn(); @@ -149,6 +150,7 @@ void* OPS_ForceBeamColumn2dThermal(); void* OPS_DispBeamColumn2d(const ID& info); void* OPS_DispBeamColumnNL2d(const ID& info); void* OPS_DispBeamColumn3d(); +void* OPS_DispBeamColumnWarping3d(); void* OPS_MixedBeamColumn2d(); void* OPS_MixedBeamColumn3d(); void* OPS_ForceBeamColumnCBDI2d(); @@ -661,6 +663,8 @@ namespace { functionMap.insert(std::make_pair("SSPBrickUP", &OPS_SSPbrickUP)); functionMap.insert(std::make_pair("SurfaceLoad", &OPS_SurfaceLoad)); functionMap.insert(std::make_pair("elasticBeamColumn", &OPS_ElasticBeam)); + functionMap.insert(std::make_pair("elasticBeamColumnWarping", &OPS_ElasticBeamWarping3d)); + functionMap.insert(std::make_pair("dispBeamColumnWarping", &OPS_DispBeamColumnWarping3d)); functionMap.insert(std::make_pair("forceBeamColumn", &OPS_ForceBeamColumn)); functionMap.insert(std::make_pair("nonlinearBeamColumn", &OPS_NonlinearBeamColumn)); functionMap.insert(std::make_pair("dispBeamColumn", &OPS_DispBeamColumn)); diff --git a/SRC/interpreter/OpenSeesSectionCommands.cpp b/SRC/interpreter/OpenSeesSectionCommands.cpp index 5b943940e..e227ef425 100644 --- a/SRC/interpreter/OpenSeesSectionCommands.cpp +++ b/SRC/interpreter/OpenSeesSectionCommands.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,7 @@ void* OPS_ElasticShearSection2d(); void* OPS_ElasticShearSection3d(); void* OPS_FiberSection2d(); void* OPS_FiberSection3d(); +void* OPS_FiberSectionWarping3d(); void* OPS_NDFiberSection2d(); void* OPS_NDFiberSection3d(); void* OPS_UniaxialFiber2d(); @@ -90,6 +92,7 @@ void* OPS_FiberSection2dThermal(); namespace { static FiberSection2d* theActiveFiberSection2d = 0; static FiberSection3d* theActiveFiberSection3d = 0; + static FiberSectionWarping3d* theActiveFiberSectionWarping3d = 0; static NDFiberSection2d* theActiveNDFiberSection2d = 0; static NDFiberSection3d* theActiveNDFiberSection3d = 0; @@ -188,12 +191,18 @@ namespace { { void* theSec = 0; int ndm = OPS_GetNDM(); + int ndf = OPS_GetNDF(); if(ndm == 2) { theSec = OPS_FiberSection2d(); theActiveFiberSection2d = (FiberSection2d*)theSec; } else if(ndm == 3) { + if (ndf == 7) { + theSec = OPS_FiberSectionWarping3d(); + theActiveFiberSectionWarping3d = (FiberSectionWarping3d*)theSec; + } else { theSec = OPS_FiberSection3d(); theActiveFiberSection3d = (FiberSection3d*)theSec; + } } return theSec; @@ -1068,6 +1077,7 @@ int OPS_Section() { theActiveFiberSection2d = 0; theActiveFiberSection3d = 0; + theActiveFiberSectionWarping3d = 0; theActiveNDFiberSection2d = 0; theActiveNDFiberSection3d = 0; @@ -1104,6 +1114,7 @@ int OPS_Section() opserr<<"ERROR could not add section.\n"; theActiveFiberSection2d = 0; theActiveFiberSection3d = 0; + theActiveFiberSectionWarping3d = 0; theActiveNDFiberSection2d = 0; theActiveNDFiberSection3d = 0; @@ -1127,7 +1138,7 @@ int OPS_Fiber() theFiber = (UniaxialFiber2d*) OPS_UniaxialFiber2d(); - } else if (theActiveFiberSection3d != 0 || theActiveFiberSection3dThermal!=0) { + } else if (theActiveFiberSection3d != 0 || theActiveFiberSectionWarping3d != 0 || theActiveFiberSection3dThermal!=0) { theFiber = (UniaxialFiber3d*) OPS_UniaxialFiber3d(); @@ -1158,6 +1169,10 @@ int OPS_Fiber() res = theActiveFiberSection3d->addFiber(*theFiber); + } else if (theActiveFiberSectionWarping3d != 0) { + + res = theActiveFiberSectionWarping3d->addFiber(*theFiber); + } else if (theActiveNDFiberSection2d != 0) { res = theActiveNDFiberSection2d->addFiber(*theFiber); @@ -1264,6 +1279,17 @@ int OPS_Patch() theFiber = new UniaxialFiber3d(j,*material,area,cPos); theActiveFiberSection3d->addFiber(*theFiber); + } else if (theActiveFiberSectionWarping3d != 0) { + + material = OPS_getUniaxialMaterial(matTag); + if (material == 0) { + opserr << "WARNING material "<addFiber(*theFiber); + } else if (theActiveFiberSection3dThermal != 0) { material = OPS_getUniaxialMaterial(matTag); @@ -1387,6 +1413,17 @@ int OPS_Layer() theFiber = new UniaxialFiber3d(j,*material,area,cPos); theActiveFiberSection3d->addFiber(*theFiber); + } else if (theActiveFiberSectionWarping3d != 0) { + + material = OPS_getUniaxialMaterial(matTag); + if (material == 0) { + opserr << "WARNING material "<addFiber(*theFiber); + } else if (theActiveFiberSection3dThermal != 0) { material = OPS_getUniaxialMaterial(matTag); diff --git a/SRC/material/section/Makefile b/SRC/material/section/Makefile index 86c05596a..d6ea21a23 100644 --- a/SRC/material/section/Makefile +++ b/SRC/material/section/Makefile @@ -20,6 +20,7 @@ OBJS = SectionForceDeformation.o \ NDFiberSectionWarping2d.o \ FiberSection2dThermal.o \ FiberSection3d.o \ + FiberSectionWarping3d.o \ FiberSectionGJ.o \ Bidirectional.o \ Elliptical.o \ diff --git a/SRC/material/section/SectionForceDeformation.h b/SRC/material/section/SectionForceDeformation.h index 05fa8b617..dd9cbd523 100644 --- a/SRC/material/section/SectionForceDeformation.h +++ b/SRC/material/section/SectionForceDeformation.h @@ -55,6 +55,8 @@ class Response; #define SECTION_RESPONSE_T 6 #define SECTION_RESPONSE_R 7 #define SECTION_RESPONSE_Q 8 +#define SECTION_RESPONSE_B 9 // Bi-moment (FiberSectionWarping3d) +#define SECTION_RESPONSE_W 10 // (FiberSectionWarping3d) class SectionForceDeformation : public Material { diff --git a/SRC/material/section/fiber/Fiber.h b/SRC/material/section/fiber/Fiber.h index 3a0e94e0b..25a280f47 100644 --- a/SRC/material/section/fiber/Fiber.h +++ b/SRC/material/section/fiber/Fiber.h @@ -74,6 +74,7 @@ class Fiber : public TaggedObject, public MovableObject virtual void getFiberLocation(double &y, double &z) =0; virtual double getArea(void) =0; + virtual double getd(void) =0; virtual UniaxialMaterial *getMaterial(void) {return 0;} virtual NDMaterial *getNDMaterial(void) {return 0;} diff --git a/SRC/material/section/fiber/NDFiber2d.h b/SRC/material/section/fiber/NDFiber2d.h index 444721f40..a1b76c7f0 100644 --- a/SRC/material/section/fiber/NDFiber2d.h +++ b/SRC/material/section/fiber/NDFiber2d.h @@ -77,7 +77,8 @@ class NDFiber2d : public Fiber void getFiberLocation(double &y, double &z); NDMaterial *getNDMaterial(void) {return theMaterial;} double getArea(void) {return area;}; - + double getd(void) {return 1.0;}; + int setParameter(const char **argv, int argc, Parameter ¶m); int updateParameter(int parameterID, Information &info); int activateParameter(int parameterID); diff --git a/SRC/material/section/fiber/NDFiber3d.cpp b/SRC/material/section/fiber/NDFiber3d.cpp index cc08a97d9..6eef6c3ed 100644 --- a/SRC/material/section/fiber/NDFiber3d.cpp +++ b/SRC/material/section/fiber/NDFiber3d.cpp @@ -83,9 +83,9 @@ void* OPS_NDFiber3d() // constructor: NDFiber3d::NDFiber3d(int tag, NDMaterial &theMat, - double Area, double yy, double zz): + double Area, double yy, double zz, double d): Fiber(tag, FIBER_TAG_ND3d), - theMaterial(0), area(Area), y(yy), z(zz) + theMaterial(0), area(Area), y(yy), z(zz), dValue(d) { theMaterial = theMat.getCopy("BeamFiber"); @@ -107,7 +107,7 @@ NDFiber3d::NDFiber3d(int tag, NDMaterial &theMat, // constructor for blank object that recvSelf needs to be invoked upon NDFiber3d::NDFiber3d(): Fiber(0, FIBER_TAG_ND3d), - theMaterial(0), area(0), y(0.0), z(0.0) + theMaterial(0), area(0), y(0.0), z(0.0), dValue(0.0) { if (code(0) != SECTION_RESPONSE_P) { code(0) = SECTION_RESPONSE_P; @@ -172,7 +172,7 @@ NDFiber3d::getCopy (void) { // make a copy of the fiber NDFiber3d *theCopy = new NDFiber3d (this->getTag(), - *theMaterial, area, y, z); + *theMaterial, area, y, z, dValue); return theCopy; } diff --git a/SRC/material/section/fiber/NDFiber3d.h b/SRC/material/section/fiber/NDFiber3d.h index 92dcd1baa..2c20722a1 100644 --- a/SRC/material/section/fiber/NDFiber3d.h +++ b/SRC/material/section/fiber/NDFiber3d.h @@ -51,7 +51,8 @@ class NDFiber3d : public Fiber { public: NDFiber3d (); - NDFiber3d (int tag, NDMaterial &theMat, double Area, double y, double z); + NDFiber3d (int tag, NDMaterial &theMat, double Area, + double y, double z, double dvalue=1.0); ~NDFiber3d(); @@ -77,7 +78,8 @@ class NDFiber3d : public Fiber void getFiberLocation(double &y, double &z); NDMaterial *getNDMaterial(void) {return theMaterial;} double getArea(void) {return area;}; - + double getd(void) {return dValue;}; + int setParameter(const char **argv, int argc, Parameter ¶m); int updateParameter(int parameterID, Information &info); int activateParameter(int parameterID); @@ -90,9 +92,10 @@ class NDFiber3d : public Fiber private: NDMaterial *theMaterial; // pointer to a material - double area; // area of the fiber + double area; // area of the fiber double y; // fiber location double z; + double dValue; static Matrix ks; // static class wide matrix object for returns static Vector fs; // static class wide vector object for returns diff --git a/SRC/material/section/fiber/UniaxialFiber2d.h b/SRC/material/section/fiber/UniaxialFiber2d.h index 5c6a49f98..0c383704a 100644 --- a/SRC/material/section/fiber/UniaxialFiber2d.h +++ b/SRC/material/section/fiber/UniaxialFiber2d.h @@ -77,7 +77,8 @@ class UniaxialFiber2d : public Fiber void getFiberLocation(double &y, double &z); UniaxialMaterial *getMaterial(void) {return theMaterial;}; double getArea(void) {return area;}; - + double getd(void) {return 1.0;}; + int setParameter(const char **argv, int argc, Parameter ¶m); int updateParameter(int parameterID, Information &info); int activateParameter(int parameterID); diff --git a/SRC/material/section/fiber/UniaxialFiber3d.cpp b/SRC/material/section/fiber/UniaxialFiber3d.cpp index b6cbb994c..3135cce66 100644 --- a/SRC/material/section/fiber/UniaxialFiber3d.cpp +++ b/SRC/material/section/fiber/UniaxialFiber3d.cpp @@ -93,7 +93,7 @@ void* OPS_UniaxialFiber3d() // constructor: UniaxialFiber3d::UniaxialFiber3d() :Fiber(0, FIBER_TAG_Uniaxial3d), - theMaterial(0), area(0.0) + theMaterial(0), area(0.0), dValue(0.0) { if (code(0) != SECTION_RESPONSE_P) { code(0) = SECTION_RESPONSE_P; @@ -107,9 +107,9 @@ UniaxialFiber3d::UniaxialFiber3d() UniaxialFiber3d::UniaxialFiber3d(int tag, UniaxialMaterial &theMat, - double Area, const Vector &position) + double Area, const Vector &position, double d) :Fiber(tag, FIBER_TAG_Uniaxial3d), - theMaterial(0), area(Area) + theMaterial(0), area(Area), dValue(d) { theMaterial = theMat.getCopy(); // get a copy of the MaterialModel @@ -206,7 +206,7 @@ UniaxialFiber3d::getCopy (void) UniaxialFiber3d *theCopy = new UniaxialFiber3d (this->getTag(), *theMaterial, area, - position); + position, dValue); return theCopy; } diff --git a/SRC/material/section/fiber/UniaxialFiber3d.h b/SRC/material/section/fiber/UniaxialFiber3d.h index 507523120..82773b520 100644 --- a/SRC/material/section/fiber/UniaxialFiber3d.h +++ b/SRC/material/section/fiber/UniaxialFiber3d.h @@ -52,7 +52,7 @@ class UniaxialFiber3d: public Fiber public: UniaxialFiber3d (); UniaxialFiber3d (int tag, UniaxialMaterial &theMat, double Area, - const Vector &position); + const Vector &position, double dvalue=1.0); ~UniaxialFiber3d(); @@ -78,12 +78,14 @@ class UniaxialFiber3d: public Fiber void getFiberLocation(double &y, double &z); UniaxialMaterial *getMaterial(void) {return theMaterial;}; double getArea(void) {return area;}; + double getd(void) {return dValue;}; protected: private: UniaxialMaterial *theMaterial; // pointer to a material - double area; // area of the fiber + double area; // area of the fiber + double dValue; double as[2]; // matrix that transforms // section deformations into fiber strain static Matrix ks; // static class wide matrix object for returns diff --git a/SRC/material/section/repres/cell/Cell.h b/SRC/material/section/repres/cell/Cell.h index ba3f295a9..02af071ce 100644 --- a/SRC/material/section/repres/cell/Cell.h +++ b/SRC/material/section/repres/cell/Cell.h @@ -19,7 +19,7 @@ ** ****************************************************************** */ // $Revision: 1.2 $ -// $Date: 2003-02-14 23:01:36 $ +// $Date: 2003/02/14 23:01:36 $ // $Source: /usr/local/cvs/OpenSees/SRC/material/section/repres/cell/Cell.h,v $ @@ -48,6 +48,7 @@ class Cell // reinforcing bar inquiring functions virtual double getArea (void) const = 0; + virtual double getdValue (void) const = 0; virtual const Vector &getCentroidPosition (void) = 0; virtual void Print(OPS_Stream &s, int flag =0) const = 0; diff --git a/SRC/material/section/repres/cell/CircSectionCell.cpp b/SRC/material/section/repres/cell/CircSectionCell.cpp index 9cc951466..7826076b7 100644 --- a/SRC/material/section/repres/cell/CircSectionCell.cpp +++ b/SRC/material/section/repres/cell/CircSectionCell.cpp @@ -56,6 +56,10 @@ double CircSectionCell::getArea (void) const return A; } +double CircSectionCell::getdValue (void) const +{ + return 1.0; // Should be something meaningful -- MHS +} const Vector & CircSectionCell::getCentroidPosition(void) diff --git a/SRC/material/section/repres/cell/CircSectionCell.h b/SRC/material/section/repres/cell/CircSectionCell.h index d0759276a..07c66c8d1 100644 --- a/SRC/material/section/repres/cell/CircSectionCell.h +++ b/SRC/material/section/repres/cell/CircSectionCell.h @@ -44,6 +44,7 @@ class CircSectionCell: public Cell // reinforcing bar inquiring functions double getArea (void) const; + double getdValue (void) const; const Matrix &getVertCoords (void) const; const Vector &getCentroidPosition (void); diff --git a/SRC/material/section/repres/cell/QuadCell.cpp b/SRC/material/section/repres/cell/QuadCell.cpp index 9a01a0470..a1108cda5 100644 --- a/SRC/material/section/repres/cell/QuadCell.cpp +++ b/SRC/material/section/repres/cell/QuadCell.cpp @@ -19,7 +19,7 @@ ** ****************************************************************** */ // $Revision: 1.3 $ -// $Date: 2003-05-02 18:34:56 $ +// $Date: 2003/05/02 18:34:56 $ // $Source: /usr/local/cvs/OpenSees/SRC/material/section/repres/cell/QuadCell.cpp,v $ @@ -58,6 +58,11 @@ QuadCell::getVertCoords (void) const return vertCoord; } +double QuadCell::getdValue (void) const +{ + double dVa=vertCoord(0,0); + return dVa; +} void QuadCell::setVertCoords (const Matrix &vertexCoords) { vertCoord = vertexCoords; diff --git a/SRC/material/section/repres/cell/QuadCell.h b/SRC/material/section/repres/cell/QuadCell.h index 9f3e70b04..314005d35 100644 --- a/SRC/material/section/repres/cell/QuadCell.h +++ b/SRC/material/section/repres/cell/QuadCell.h @@ -19,7 +19,7 @@ ** ****************************************************************** */ // $Revision: 1.2 $ -// $Date: 2003-02-14 23:01:36 $ +// $Date: 2003/02/14 23:01:36 $ // $Source: /usr/local/cvs/OpenSees/SRC/material/section/repres/cell/QuadCell.h,v $ @@ -55,6 +55,7 @@ class QuadCell: public Cell // reinforcing bar inquiring functions double getArea (void) const; + double getdValue (void) const; const Matrix &getVertCoords (void) const; const Vector &getCentroidPosition (void); From 2f55bfcab094a5019c492a5c33ce0dcb31554f75 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Mon, 29 Mar 2021 12:31:24 -0700 Subject: [PATCH 022/207] Update FiberSectionWarping3d.cpp --- SRC/material/section/FiberSectionWarping3d.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/SRC/material/section/FiberSectionWarping3d.cpp b/SRC/material/section/FiberSectionWarping3d.cpp index f7422aa16..9c0c9d018 100755 --- a/SRC/material/section/FiberSectionWarping3d.cpp +++ b/SRC/material/section/FiberSectionWarping3d.cpp @@ -462,6 +462,7 @@ FiberSectionWarping3d::setTrialSectionDeformation (const Vector &deforms) } if (theTorsion != 0) { + double stress, tangent; res += theTorsion->setTrial(d8, stress, tangent); sData[5] = stress; kData[35] = tangent; From 2b72e807916909d2ae4bb98552f5913502fe69af Mon Sep 17 00:00:00 2001 From: Codi McKee Date: Tue, 30 Mar 2021 16:34:48 -0500 Subject: [PATCH 023/207] Correct PartitionedDomain::partition Correcting erroneous commenting out of getPartitioner --- SRC/domain/domain/partitioned/PartitionedDomain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/domain/domain/partitioned/PartitionedDomain.cpp b/SRC/domain/domain/partitioned/PartitionedDomain.cpp index e1d1334b0..b9f44a168 100644 --- a/SRC/domain/domain/partitioned/PartitionedDomain.cpp +++ b/SRC/domain/domain/partitioned/PartitionedDomain.cpp @@ -1498,7 +1498,7 @@ PartitionedDomain::partition(int numPartitions, bool usingMain, int mainPartitio Graph &theEleGraph = this->getElementGraph(); // now we call partition on the domainPartitioner which does the partitioning - DomainPartitioner *thePartitioner = 0;//this->getPartitioner(); + DomainPartitioner *thePartitioner = this->getPartitioner(); if (thePartitioner != 0) { thePartitioner->setPartitionedDomain(*this); result = thePartitioner->partition(numPartitions, usingMain, mainPartitionID, specialElementTag); From 5935189c9be727b4f741415f1c11405051aa88eb Mon Sep 17 00:00:00 2001 From: ambaker1 Date: Sat, 3 Apr 2021 14:03:43 -0400 Subject: [PATCH 024/207] Added ndm and ndf Utility commands for getting the input ndm and input ndf, as well as the nodal ndm and ndf. Syntax: ndm <$nodeTag> ndf <$nodeTag> If the nodeTag argument is provided, it will return the nodal dimensions/degrees of freedom, or throw an error if the node does not exist. If the nodeTag argument is not provided, it will return the input ndm/ndf, or the blank string if the model builder is undefined. --- SRC/tcl/commands.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++ SRC/tcl/commands.h | 6 ++++ 2 files changed, 78 insertions(+) diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index 3c5a1ca6f..bc35d11d9 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -811,6 +811,11 @@ int OpenSeesAppInit(Tcl_Interp *interp) { Tcl_CreateObjCommand(interp, "source", &OPS_SourceCmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "ndm", &ndm, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + Tcl_CreateCommand(interp, "ndf", &ndf, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + Tcl_CreateCommand(interp, "wipe", &wipeModel, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); @@ -6683,6 +6688,73 @@ updateElementDomain(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Cha return 0; } +int +ndm(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) +{ + int ndm; + + if (argc > 1) { + int tag; + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING ndm nodeTag? \n"; + return TCL_ERROR; + } + Node* theNode = theDomain.getNode(tag); + if (theNode == 0) { + opserr << "WARNING nodeTag " << tag << " does not exist \n"; + return TCL_ERROR; + } + const Vector& coords = theNode->getCrds(); + ndm = coords.Size(); + } else { + if (theBuilder == 0) { + return TCL_OK; + } + else { + ndm = OPS_GetNDM(); + } + } + + char buffer[20]; + sprintf(buffer, "%d", ndm); + Tcl_AppendResult(interp, buffer, NULL); + + return TCL_OK; +} + +int +ndf(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) +{ + int ndf; + + if (argc > 1) { + int tag; + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING ndf nodeTag? \n"; + return TCL_ERROR; + } + Node* theNode = theDomain.getNode(tag); + if (theNode == 0) { + opserr << "WARNING nodeTag " << tag << " does not exist \n"; + return TCL_ERROR; + } + ndf = theNode->getNumberDOF(); + } else { + if (theBuilder == 0) { + return TCL_OK; + } + else { + ndf = OPS_GetNDF(); + } + } + + char buffer[20]; + sprintf(buffer, "%d", ndf); + Tcl_AppendResult(interp, buffer, NULL); + + return TCL_OK; +} + int eleNodes(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { diff --git a/SRC/tcl/commands.h b/SRC/tcl/commands.h index 89539c806..d210f290c 100644 --- a/SRC/tcl/commands.h +++ b/SRC/tcl/commands.h @@ -47,6 +47,12 @@ OPS_SetObjCmd(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj * con int OPS_SourceCmd(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj * const *argv); +int +ndm(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); + +int +ndf(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); + int wipeModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); From 3f3b78c439042b7d6e5f7224bb8f2d961804ca10 Mon Sep 17 00:00:00 2001 From: ambaker1 Date: Sat, 3 Apr 2021 14:09:55 -0400 Subject: [PATCH 025/207] Added eleType, utility to get element class eleType accesses the getClassType() method for elements, and returns the result as a string syntax: eleType $eleTag Returns an error if the eleTag does not exist Also added the same error handling to eleNodes. Entering a bad element tag would crash the program. --- SRC/tcl/commands.cpp | 34 ++++++++++++++++++++++++++++++++++ SRC/tcl/commands.h | 3 +++ 2 files changed, 37 insertions(+) diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index 3c5a1ca6f..7cae33163 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -923,6 +923,8 @@ int OpenSeesAppInit(Tcl_Interp *interp) { (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); Tcl_CreateCommand(interp, "updateElementDomain", &updateElementDomain, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "eleType", &eleType, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); Tcl_CreateCommand(interp, "eleNodes", &eleNodes, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); Tcl_CreateCommand(interp, "nodeMass", &nodeMass, @@ -6683,6 +6685,34 @@ updateElementDomain(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Cha return 0; } +int +eleType(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) +{ + if (argc < 2) { + opserr << "WARNING want - eleType eleTag?\n"; + return TCL_ERROR; + } + + int tag; + + if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { + opserr << "WARNING eleType eleTag? \n"; + return TCL_ERROR; + } + + char buffer[20]; + Element* theElement = theDomain.getElement(tag); + if (theElement == 0) { + opserr << "WARNING eleType ele " << tag << " not found" << endln; + return TCL_ERROR; + } + const char* type = theElement->getClassType(); + sprintf(buffer, "%s", type); + Tcl_AppendResult(interp, buffer, NULL); + + return TCL_OK; +} + int eleNodes(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { @@ -6707,6 +6737,10 @@ eleNodes(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) //const Vector *tags = theDomain.getElementResponse(tag, &myArgv[0], 1); Element *theElement = theDomain.getElement(tag); + if (theElement == 0) { + opserr << "WARNING eleNodes ele " << tag << " not found" << endln; + return TCL_ERROR; + } int numTags = theElement->getNumExternalNodes(); const ID &tags = theElement->getExternalNodes(); for (int i = 0; i < numTags; i++) { diff --git a/SRC/tcl/commands.h b/SRC/tcl/commands.h index 89539c806..f7f1b31c0 100644 --- a/SRC/tcl/commands.h +++ b/SRC/tcl/commands.h @@ -172,6 +172,9 @@ setNodeCoord(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **arg int updateElementDomain(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); +int +eleType(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); + int eleNodes(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); From 22f2e9278fd4a811a21a854848d168eaa5be7085 Mon Sep 17 00:00:00 2001 From: fmckenna Date: Sat, 3 Apr 2021 16:58:31 -0700 Subject: [PATCH 026/207] fmk - fixing Makefile --- SRC/element/mvlem/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/SRC/element/mvlem/Makefile b/SRC/element/mvlem/Makefile index 334b99c23..e909802b1 100644 --- a/SRC/element/mvlem/Makefile +++ b/SRC/element/mvlem/Makefile @@ -1,10 +1,9 @@ include ../../../Makefile.def -OBJS = MVLEM.o \ - SFI_MVLEM.o +OBJS = MVLEM.o \ + SFI_MVLEM.o \ MVLEM_3D.o - all: $(OBJS) # Miscellaneous From 677ec3942278494ef4fc69f28a1f39198aa66c99 Mon Sep 17 00:00:00 2001 From: ambaker1 Date: Sun, 4 Apr 2021 02:33:59 -0400 Subject: [PATCH 027/207] Utility commands for SP and MP constraints Six commands added: fixedNodes, fixedDOFs, constrainedNodes, constrainedDOFs, retainedNodes, retainedDOFs. These are especially useful for trouble-shooting SP/MP conflicts. Syntax: fixedNodes; # all nodes with fixities fixedDOFs $fNode; # all fixed dofs at fixed node constrainedNodes <$rNode>; # all constrained nodes, optionally from specific node constrainedDOFs $cNode <$rNode>; # all constrained dofs at a node, optionally from specific node retainedNodes <$cNode>; # all retained nodes, optionally to specific node retainedDOFs $rNode <$cNode>; # all retained DOFs, optionally to specific node Example Tcl script to check for MP/SP conflicts: foreach nodeTag [fixedNodes] { set fDOFs [fixedDOFs $nodeTag] set cDOFs [constrainedDOFs $nodeTag] foreach dof $fDOFs { if {$dof in $cDOFs} { puts "Node $nodeTag is fixed and constrained at dof $dof" } } } Additionally, it can be used to get all the fixed nodes in a certain direction (for reaction recorders): foreach nodeTag [fixedNodes] { foreach dof [fixedDOFs $nodeTag] { switch $dof { 1 {lappend xNodes $nodeTag} 2 {lappend yNodes $nodeTag} 3 {lappend zNodes $nodeTag} } } } --- SRC/tcl/commands.cpp | 261 +++++++++++++++++++++++++++++++++++++++++++ SRC/tcl/commands.h | 18 +++ 2 files changed, 279 insertions(+) diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index 3c5a1ca6f..82cbed1ae 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -47,6 +47,9 @@ extern "C" { #include #include #include +#include +#include +#include extern void OPS_clearAllUniaxialMaterial(void); extern void OPS_clearAllNDMaterial(void); @@ -110,6 +113,8 @@ OPS_Stream *opserrPtr = &sserr; #include #include //Joey UC Davis #include //Joey UC Davis +#include +#include #include #include #include @@ -990,6 +995,19 @@ int OpenSeesAppInit(Tcl_Interp *interp) { Tcl_CreateCommand(interp, "getParamValue", &getParamValue, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "fixedNodes", &fixedNodes, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + Tcl_CreateCommand(interp, "fixedDOFs", &fixedDOFs, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + Tcl_CreateCommand(interp, "constrainedNodes", &constrainedNodes, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + Tcl_CreateCommand(interp, "constrainedDOFs", &constrainedDOFs, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + Tcl_CreateCommand(interp, "retainedNodes", &retainedNodes, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + Tcl_CreateCommand(interp, "retainedDOFs", &retainedDOFs, + (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); + Tcl_CreateCommand(interp, "sdfResponse", &sdfResponse, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); @@ -6629,6 +6647,249 @@ nodeCoord(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) return TCL_ERROR; } +int +fixedNodes(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) +{ + SP_Constraint* theSP; + SP_ConstraintIter& spIter = theDomain.getDomainAndLoadPatternSPs(); + + char buffer[20]; + + int tag; + int count = 0; + int lastTag; + while ((theSP = spIter()) != 0) { + tag = theSP->getNodeTag(); + if (count == 0 || tag != lastTag) { + sprintf(buffer, "%d ", tag); + Tcl_AppendResult(interp, buffer, NULL); + } + count += 1; + lastTag = tag; + } + + return TCL_OK; +} + +int +fixedDOFs(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) +{ + if (argc < 2) { + opserr << "WARNING want - fixedDOFs fNode?\n"; + return TCL_ERROR; + } + + int fNode; + if (Tcl_GetInt(interp, argv[1], &fNode) != TCL_OK) { + opserr << "WARNING fixedDOFs fNode? - could not read fNode? \n"; + return TCL_ERROR; + } + + SP_Constraint* theSP; + SP_ConstraintIter& spIter = theDomain.getDomainAndLoadPatternSPs(); + + int tag; + static Vector fixed(6); + while ((theSP = spIter()) != 0) { + tag = theSP->getNodeTag(); + if (tag == fNode) { + fixed(theSP->getDOF_Number()) = 1; + } + } + + char buffer[20]; + for (int i = 0; i < 6; i++) { + if (fixed(i) == 1) { + sprintf(buffer, "%d ", i + 1); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} + +int +constrainedNodes(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) +{ + bool all = 1; + int rNode; + if (argc > 1) { + if (Tcl_GetInt(interp, argv[1], &rNode) != TCL_OK) { + opserr << "WARNING constrainedNodes - could not read rNode? \n"; + return TCL_ERROR; + } + all = 0; + } + + MP_Constraint* theMP; + MP_ConstraintIter& mpIter = theDomain.getMPs(); + + // get unique constrained nodes with set + set tags; + int tag; + while ((theMP = mpIter()) != 0) { + tag = theMP->getNodeConstrained(); + if (all || rNode == theMP->getNodeRetained()) { + tags.insert(tag); + } + } + // assign set to vector and sort + vector tagv; + tagv.assign(tags.begin(), tags.end()); + sort(tagv.begin(), tagv.end()); + // loop through unique, sorted tags, adding to output + char buffer[20]; + for (int tag : tagv) { + sprintf(buffer, "%d ", tag); + Tcl_AppendResult(interp, buffer, NULL); + } + + return TCL_OK; +} + +int +constrainedDOFs(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) +{ + + if (argc < 2) { + opserr << "WARNING want - constrainedDOFs cNode? \n"; + return TCL_ERROR; + } + + int cNode; + if (Tcl_GetInt(interp, argv[1], &cNode) != TCL_OK) { + opserr << "WARNING constrainedDOFs cNode? - could not read cNode? \n"; + return TCL_ERROR; + } + + int rNode; + bool all = 1; + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &rNode) != TCL_OK) { + opserr << "WARNING constrainedDOFs cNode? - could not read rNode? \n"; + return TCL_ERROR; + } + all = 0; + } + + MP_Constraint* theMP; + MP_ConstraintIter& mpIter = theDomain.getMPs(); + + int tag; + Vector constrained(6); + while ((theMP = mpIter()) != 0) { + tag = theMP->getNodeConstrained(); + if (tag == cNode) { + if (all || rNode == theMP->getNodeRetained()) { + const ID &dofs = theMP->getConstrainedDOFs(); + for (int i = 0; i < dofs.Size(); i++) { + constrained(dofs(i)) = 1; + } + } + } + } + char buffer[20]; + for (int i = 0; i < 6; i++) { + if (constrained(i) == 1) { + sprintf(buffer, "%d ", i + 1); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} + +int +retainedNodes(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) +{ + bool all = 1; + int cNode; + if (argc > 1) { + if (Tcl_GetInt(interp, argv[1], &cNode) != TCL_OK) { + opserr << "WARNING retainedNodes - could not read cNode? \n"; + return TCL_ERROR; + } + all = 0; + } + + MP_Constraint* theMP; + MP_ConstraintIter& mpIter = theDomain.getMPs(); + + // get unique constrained nodes with set + set tags; + int tag; + while ((theMP = mpIter()) != 0) { + tag = theMP->getNodeRetained(); + if (all || cNode == theMP->getNodeConstrained()) { + tags.insert(tag); + } + } + // assign set to vector and sort + vector tagv; + tagv.assign(tags.begin(), tags.end()); + sort(tagv.begin(), tagv.end()); + // loop through unique, sorted tags, adding to output + char buffer[20]; + for (int tag : tagv) { + sprintf(buffer, "%d ", tag); + Tcl_AppendResult(interp, buffer, NULL); + } + + return TCL_OK; +} + +int +retainedDOFs(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) +{ + + if (argc < 2) { + opserr << "WARNING want - retainedDOFs rNode? \n"; + return TCL_ERROR; + } + + int rNode; + if (Tcl_GetInt(interp, argv[1], &rNode) != TCL_OK) { + opserr << "WARNING retainedDOFs rNode? - could not read rNode? \n"; + return TCL_ERROR; + } + + int cNode; + bool all = 1; + if (argc > 2) { + if (Tcl_GetInt(interp, argv[2], &cNode) != TCL_OK) { + opserr << "WARNING retainedDOFs rNode? - could not read cNode? \n"; + return TCL_ERROR; + } + all = 0; + } + + MP_Constraint* theMP; + MP_ConstraintIter& mpIter = theDomain.getMPs(); + + int tag; + Vector retained(6); + while ((theMP = mpIter()) != 0) { + tag = theMP->getNodeRetained(); + if (tag == rNode) { + if (all || cNode == theMP->getNodeConstrained()) { + const ID& dofs = theMP->getRetainedDOFs(); + for (int i = 0; i < dofs.Size(); i++) { + retained(dofs(i)) = 1; + } + } + } + } + char buffer[20]; + for (int i = 0; i < 6; i++) { + if (retained(i) == 1) { + sprintf(buffer, "%d ", i + 1); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + return TCL_OK; +} + int setNodeCoord(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { diff --git a/SRC/tcl/commands.h b/SRC/tcl/commands.h index 89539c806..f0769df02 100644 --- a/SRC/tcl/commands.h +++ b/SRC/tcl/commands.h @@ -205,6 +205,24 @@ getNodeTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv int getEleTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); +int +fixedNodes(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); + +int +fixedDOFs(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); + +int +constrainedNodes(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); + +int +constrainedDOFs(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); + +int +retainedNodes(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); + +int +retainedDOFs(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); + int nodeDOFs(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); From 7a6249980a5316d76e4b54a39a2a21aa638a19a2 Mon Sep 17 00:00:00 2001 From: ambaker1 Date: Sun, 4 Apr 2021 02:47:48 -0400 Subject: [PATCH 028/207] Update commands.cpp fixedNodes fix -> using same sort/unique algorithm as constrainedNodes and retainedNodes. general clean-up --- SRC/tcl/commands.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index 82cbed1ae..ce9dc0286 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -6653,19 +6653,22 @@ fixedNodes(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) SP_Constraint* theSP; SP_ConstraintIter& spIter = theDomain.getDomainAndLoadPatternSPs(); - char buffer[20]; - + // get unique constrained nodes with set + set tags; int tag; - int count = 0; - int lastTag; while ((theSP = spIter()) != 0) { tag = theSP->getNodeTag(); - if (count == 0 || tag != lastTag) { - sprintf(buffer, "%d ", tag); - Tcl_AppendResult(interp, buffer, NULL); - } - count += 1; - lastTag = tag; + tags.insert(tag); + } + // assign set to vector and sort + vector tagv; + tagv.assign(tags.begin(), tags.end()); + sort(tagv.begin(), tagv.end()); + // loop through unique, sorted tags, adding to output + char buffer[20]; + for (int tag : tagv) { + sprintf(buffer, "%d ", tag); + Tcl_AppendResult(interp, buffer, NULL); } return TCL_OK; @@ -6689,7 +6692,7 @@ fixedDOFs(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) SP_ConstraintIter& spIter = theDomain.getDomainAndLoadPatternSPs(); int tag; - static Vector fixed(6); + Vector fixed(6); while ((theSP = spIter()) != 0) { tag = theSP->getNodeTag(); if (tag == fNode) { @@ -6750,7 +6753,6 @@ constrainedNodes(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** int constrainedDOFs(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) { - if (argc < 2) { opserr << "WARNING want - constrainedDOFs cNode? \n"; return TCL_ERROR; From 7dd9e354365f325870475f8e55e5d8edaee17456 Mon Sep 17 00:00:00 2001 From: ambaker1 Date: Mon, 5 Apr 2021 11:33:42 -0400 Subject: [PATCH 029/207] Update commands.cpp Added optional argument for constrained/retained DOF. Especially useful for mixed equal DOF constraints --- SRC/tcl/commands.cpp | 82 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index ce9dc0286..f2e87afd3 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -6754,38 +6754,61 @@ int constrainedDOFs(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) { if (argc < 2) { - opserr << "WARNING want - constrainedDOFs cNode? \n"; + opserr << "WARNING want - constrainedDOFs cNode? \n"; return TCL_ERROR; } int cNode; if (Tcl_GetInt(interp, argv[1], &cNode) != TCL_OK) { - opserr << "WARNING constrainedDOFs cNode? - could not read cNode? \n"; + opserr << "WARNING constrainedDOFs cNode? - could not read cNode? \n"; return TCL_ERROR; } int rNode; - bool all = 1; + bool allNodes = 1; if (argc > 2) { if (Tcl_GetInt(interp, argv[2], &rNode) != TCL_OK) { - opserr << "WARNING constrainedDOFs cNode? - could not read rNode? \n"; + opserr << "WARNING constrainedDOFs cNode? - could not read rNode? \n"; return TCL_ERROR; } - all = 0; + allNodes = 0; + } + + int rDOF; + bool allDOFs = 1; + if (argc > 3) { + if (Tcl_GetInt(interp, argv[3], &rDOF) != TCL_OK) { + opserr << "WARNING constrainedDOFs cNode? - could not read rDOF? \n"; + return TCL_ERROR; + } + rDOF--; + allDOFs = 0; } MP_Constraint* theMP; MP_ConstraintIter& mpIter = theDomain.getMPs(); int tag; + int i; + int n; Vector constrained(6); while ((theMP = mpIter()) != 0) { tag = theMP->getNodeConstrained(); if (tag == cNode) { - if (all || rNode == theMP->getNodeRetained()) { - const ID &dofs = theMP->getConstrainedDOFs(); - for (int i = 0; i < dofs.Size(); i++) { - constrained(dofs(i)) = 1; + if (allNodes || rNode == theMP->getNodeRetained()) { + const ID &cDOFs = theMP->getConstrainedDOFs(); + n = cDOFs.Size(); + if (allDOFs) { + for (i = 0; i < n; i++) { + constrained(cDOFs(i)) = 1; + } + } + else { + const ID &rDOFs = theMP->getRetainedDOFs(); + for (i = 0; i < n; i++) { + if (rDOF == rDOFs(i)) + constrained(cDOFs(i)) = 1; + } } } } @@ -6845,38 +6868,61 @@ retainedDOFs(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** arg { if (argc < 2) { - opserr << "WARNING want - retainedDOFs rNode? \n"; + opserr << "WARNING want - retainedDOFs rNode? \n"; return TCL_ERROR; } int rNode; if (Tcl_GetInt(interp, argv[1], &rNode) != TCL_OK) { - opserr << "WARNING retainedDOFs rNode? - could not read rNode? \n"; + opserr << "WARNING retainedDOFs rNode? - could not read rNode? \n"; return TCL_ERROR; } int cNode; - bool all = 1; + bool allNodes = 1; if (argc > 2) { if (Tcl_GetInt(interp, argv[2], &cNode) != TCL_OK) { - opserr << "WARNING retainedDOFs rNode? - could not read cNode? \n"; + opserr << "WARNING retainedDOFs rNode? - could not read cNode? \n"; return TCL_ERROR; } - all = 0; + allNodes = 0; + } + + int cDOF; + bool allDOFs = 1; + if (argc > 3) { + if (Tcl_GetInt(interp, argv[3], &cDOF) != TCL_OK) { + opserr << "WARNING retainedDOFs rNode? - could not read cDOF? \n"; + return TCL_ERROR; + } + cDOF--; + allDOFs = 0; } MP_Constraint* theMP; MP_ConstraintIter& mpIter = theDomain.getMPs(); int tag; + int i; + int n; Vector retained(6); while ((theMP = mpIter()) != 0) { tag = theMP->getNodeRetained(); if (tag == rNode) { - if (all || cNode == theMP->getNodeConstrained()) { - const ID& dofs = theMP->getRetainedDOFs(); - for (int i = 0; i < dofs.Size(); i++) { - retained(dofs(i)) = 1; + if (allNodes || cNode == theMP->getNodeConstrained()) { + const ID& rDOFs = theMP->getRetainedDOFs(); + n = rDOFs.Size(); + if (allDOFs) { + for (i = 0; i < n; i++) { + retained(rDOFs(i)) = 1; + } + } + else { + const ID& cDOFs = theMP->getConstrainedDOFs(); + for (i = 0; i < n; i++) { + if (cDOF == cDOFs(i)) + retained(rDOFs(i)) = 1; + } } } } From 600f00d2da87143ac142f99615dedc30479ff48d Mon Sep 17 00:00:00 2001 From: Seweryn Kokot Date: Fri, 5 Feb 2021 08:12:54 +0100 Subject: [PATCH 030/207] add getNumEles, getEleLoadClassTags/Tags/Data commands --- SRC/interpreter/OpenSeesCommands.h | 4 + SRC/interpreter/OpenSeesOutputCommands.cpp | 143 +++++++++++++++++++++ SRC/interpreter/PythonWrapper.cpp | 52 ++++++++ SRC/interpreter/TclWrapper.cpp | 40 ++++++ 4 files changed, 239 insertions(+) diff --git a/SRC/interpreter/OpenSeesCommands.h b/SRC/interpreter/OpenSeesCommands.h index a389deb76..929992680 100644 --- a/SRC/interpreter/OpenSeesCommands.h +++ b/SRC/interpreter/OpenSeesCommands.h @@ -281,6 +281,10 @@ int OPS_sensNodeAccel(); int OPS_sensLambda(); int OPS_sensSectionForce(); int OPS_sensNodePressure(); +int OPS_getNumElements(); +int OPS_getEleLoadClassTags(); +int OPS_getEleLoadTags(); +int OPS_getEleLoadData(); // Sensitivity:END ///////////////////////////////////////////// /* OpenSeesMiscCommands.cpp */ diff --git a/SRC/interpreter/OpenSeesOutputCommands.cpp b/SRC/interpreter/OpenSeesOutputCommands.cpp index 00dd89bd4..12d4c1173 100644 --- a/SRC/interpreter/OpenSeesOutputCommands.cpp +++ b/SRC/interpreter/OpenSeesOutputCommands.cpp @@ -47,6 +47,12 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #include #include #include +// #include +// #include +// #include +// #include +#include +#include #include #include #include @@ -3103,4 +3109,141 @@ int OPS_sensNodePressure() return 0; } +int OPS_getEleLoadClassTags() +{ + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + int numdata = OPS_GetNumRemainingInputArgs(); + if (numdata < 1) { + opserr << "WARNING want - getEleLoadTags patternTag?\n"; + return -1; + } + + int patternTag; + numdata = 1; + if (OPS_GetIntInput(&numdata, &patternTag) < 0) { + opserr << "could not read patternTag\n"; + return -1; + } + + LoadPattern *thePattern = theDomain->getLoadPattern(patternTag); + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + std::vector data; + + while ((theLoad = theEleLoads()) != 0) { + data.push_back(theLoad->getClassTag()); + } + + int size = data.size(); + + if (OPS_SetIntOutput(&size, data.data(), false) < 0) { + opserr << "WARNING failed to set output\n"; + return -1; + } + + return 0; +} + +int OPS_getEleLoadTags() +{ + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + int numdata = OPS_GetNumRemainingInputArgs(); + if (numdata < 1) { + opserr << "WARNING want - getEleLoadTags patternTag?\n"; + return -1; + } + + int patternTag; + numdata = 1; + if (OPS_GetIntInput(&numdata, &patternTag) < 0) { + opserr << "could not read patternTag\n"; + return -1; + } + + LoadPattern* thePattern = theDomain->getLoadPattern(patternTag); + ElementalLoadIter& theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + std::vector data; + + while ((theLoad = theEleLoads()) != 0) { + data.push_back(theLoad->getElementTag()); + } + + int size = data.size(); + + if (OPS_SetIntOutput(&size, data.data(), false) < 0) { + opserr << "WARNING failed to set output\n"; + return -1; + } + + return 0; +} + +int OPS_getEleLoadData() +{ + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + int numdata = OPS_GetNumRemainingInputArgs(); + if (numdata < 1) { + opserr << "WARNING want - getEleLoadData patternTag?\n"; + return -1; + } + + int patternTag; + numdata = 1; + if (OPS_GetIntInput(&numdata, &patternTag) < 0) { + opserr << "could not read patternTag\n"; + return -1; + } + + LoadPattern* thePattern = theDomain->getLoadPattern(patternTag); + ElementalLoadIter& theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + std::vector data; + + int typeEL; + + while ((theLoad = theEleLoads()) != 0) { + const Vector &eleLoadData = theLoad->getData(typeEL, 1.0); + + int eleLoadDataSize = eleLoadData.Size(); + for (int i = 0; i < eleLoadDataSize; i++) { + data.push_back(eleLoadData(i)); + } + } + + int size = data.size(); + + if (OPS_SetDoubleOutput(&size, data.data(), false) < 0) { + opserr << "WARNING failed to set output\n"; + return -1; + } + + return 0; +} + +int OPS_getNumElements() +{ + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + int nEles = theDomain->getNumElements(); + int size = 1; + + if (OPS_SetIntOutput(&size, &nEles, false) < 0) { + opserr << "WARNING failed to set output\n"; + return -1; + } + + return 0; +} + // Sensitivity:END ///////////////////////////////////////////// diff --git a/SRC/interpreter/PythonWrapper.cpp b/SRC/interpreter/PythonWrapper.cpp index aacce860b..1c1d6d613 100644 --- a/SRC/interpreter/PythonWrapper.cpp +++ b/SRC/interpreter/PythonWrapper.cpp @@ -1992,6 +1992,54 @@ static PyObject *Py_ops_sensNodePressure(PyObject *self, PyObject *args) return wrapper->getResults(); } +static PyObject *Py_ops_getNumElements(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_getNumElements() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + +static PyObject *Py_ops_getEleLoadClassTags(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_getEleLoadClassTags() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + +static PyObject *Py_ops_getEleLoadTags(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_getEleLoadTags() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + +static PyObject *Py_ops_getEleLoadData(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_getEleLoadData() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + static PyObject *Py_ops_randomVariable(PyObject *self, PyObject *args) { wrapper->resetCommandLine(PyTuple_Size(args), 1, args); @@ -2381,6 +2429,10 @@ PythonWrapper::addOpenSeesCommands() addCommand("sensLambda", &Py_ops_sensLambda); addCommand("sensSectionForce", &Py_ops_sensSectionForce); addCommand("sensNodePressure", &Py_ops_sensNodePressure); + addCommand("getNumElements", &Py_ops_getNumElements); + addCommand("getEleLoadClassTags", &Py_ops_getEleLoadClassTags); + addCommand("getEleLoadTags", &Py_ops_getEleLoadTags); + addCommand("getEleLoadData", &Py_ops_getEleLoadData); addCommand("randomVariable", &Py_ops_randomVariable); addCommand("getRVTags", &Py_ops_getRVTags); addCommand("getMean", &Py_ops_getRVMean); diff --git a/SRC/interpreter/TclWrapper.cpp b/SRC/interpreter/TclWrapper.cpp index 99ca5b278..4cbd26acc 100644 --- a/SRC/interpreter/TclWrapper.cpp +++ b/SRC/interpreter/TclWrapper.cpp @@ -1308,6 +1308,42 @@ static int Tcl_ops_sensNodePressure(ClientData clientData, Tcl_Interp *interp, i return TCL_OK; } +static int Tcl_ops_getNumElements(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + wrapper->resetCommandLine(argc, 1, argv); + + if (OPS_getNumElements() < 0) return TCL_ERROR; + + return TCL_OK; +} + +static int Tcl_ops_getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + wrapper->resetCommandLine(argc, 1, argv); + + if (OPS_getEleLoadClassTags() < 0) return TCL_ERROR; + + return TCL_OK; +} + +static int Tcl_ops_getEleLoadTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + wrapper->resetCommandLine(argc, 1, argv); + + if (OPS_getEleLoadTags() < 0) return TCL_ERROR; + + return TCL_OK; +} + +static int Tcl_ops_getEleLoadData(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + wrapper->resetCommandLine(argc, 1, argv); + + if (OPS_getEleLoadData() < 0) return TCL_ERROR; + + return TCL_OK; +} + static int Tcl_ops_randomVariable(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { wrapper->resetCommandLine(argc, 1, argv); @@ -1653,6 +1689,10 @@ TclWrapper::addOpenSeesCommands(Tcl_Interp* interp) addCommand(interp,"sensLambda", &Tcl_ops_sensLambda); addCommand(interp,"sensSectionForce", &Tcl_ops_sensSectionForce); addCommand(interp,"sensNodePressure", &Tcl_ops_sensNodePressure); + addCommand(interp,"getNumElements", &Tcl_ops_getNumElements); + addCommand(interp,"getEleLoadClassTags", &Tcl_ops_getEleLoadClassTags); + addCommand(interp,"getEleLoadTags", &Tcl_ops_getEleLoadTags); + addCommand(interp,"getEleLoadData", &Tcl_ops_getEleLoadData); addCommand(interp,"randomVariable", &Tcl_ops_randomVariable); addCommand(interp,"getRVTags", &Tcl_ops_getRVTags); addCommand(interp,"getMean", &Tcl_ops_getRVMean); From 7b6af5ef90806b754ef860a30350cbd66b6fb8df Mon Sep 17 00:00:00 2001 From: Seweryn Kokot Date: Tue, 30 Mar 2021 10:36:39 +0200 Subject: [PATCH 031/207] add getEleClassTags utility command --- SRC/interpreter/OpenSeesCommands.h | 1 + SRC/interpreter/OpenSeesOutputCommands.cpp | 48 +++++++++++++++++++++- SRC/interpreter/PythonWrapper.cpp | 13 ++++++ SRC/interpreter/TclWrapper.cpp | 10 +++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/SRC/interpreter/OpenSeesCommands.h b/SRC/interpreter/OpenSeesCommands.h index 929992680..a8a5972fc 100644 --- a/SRC/interpreter/OpenSeesCommands.h +++ b/SRC/interpreter/OpenSeesCommands.h @@ -282,6 +282,7 @@ int OPS_sensLambda(); int OPS_sensSectionForce(); int OPS_sensNodePressure(); int OPS_getNumElements(); +int OPS_getEleClassTags(); int OPS_getEleLoadClassTags(); int OPS_getEleLoadTags(); int OPS_getEleLoadData(); diff --git a/SRC/interpreter/OpenSeesOutputCommands.cpp b/SRC/interpreter/OpenSeesOutputCommands.cpp index 12d4c1173..076fb1e1e 100644 --- a/SRC/interpreter/OpenSeesOutputCommands.cpp +++ b/SRC/interpreter/OpenSeesOutputCommands.cpp @@ -3109,6 +3109,52 @@ int OPS_sensNodePressure() return 0; } +int OPS_getEleClassTags() +{ + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + int numdata = OPS_GetNumRemainingInputArgs(); + + std::vector data; + + // all element tags + if (numdata < 1) { + Element *theEle; + ElementIter &theEles = theDomain->getElements(); + + while ((theEle = theEles()) != 0) { + data.push_back(theEle->getClassTag()); + } + + // specific element tag + } else if (numdata == 1) { + int eleTag; + + if (OPS_GetIntInput(&numdata, &eleTag) < 0) { + opserr << "could not read eleTag\n"; + return -1; + } + + Element *theEle = theDomain->getElement(eleTag); + + data.push_back(theEle->getClassTag()); + + } else { + opserr << "WARNING want - getEleClassTags \n"; + return -1; + } + + int size = data.size(); + + if (OPS_SetIntOutput(&size, data.data(), false) < 0) { + opserr << "WARNING failed to set output\n"; + return -1; + } + + return 0; +} + int OPS_getEleLoadClassTags() { Domain* theDomain = OPS_GetDomain(); @@ -3116,7 +3162,7 @@ int OPS_getEleLoadClassTags() int numdata = OPS_GetNumRemainingInputArgs(); if (numdata < 1) { - opserr << "WARNING want - getEleLoadTags patternTag?\n"; + opserr << "WARNING want - getEleLoadClassTags patternTag?\n"; return -1; } diff --git a/SRC/interpreter/PythonWrapper.cpp b/SRC/interpreter/PythonWrapper.cpp index 1c1d6d613..d8e200e35 100644 --- a/SRC/interpreter/PythonWrapper.cpp +++ b/SRC/interpreter/PythonWrapper.cpp @@ -2004,6 +2004,18 @@ static PyObject *Py_ops_getNumElements(PyObject *self, PyObject *args) return wrapper->getResults(); } +static PyObject *Py_ops_getEleClassTags(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_getEleClassTags() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + static PyObject *Py_ops_getEleLoadClassTags(PyObject *self, PyObject *args) { wrapper->resetCommandLine(PyTuple_Size(args), 1, args); @@ -2430,6 +2442,7 @@ PythonWrapper::addOpenSeesCommands() addCommand("sensSectionForce", &Py_ops_sensSectionForce); addCommand("sensNodePressure", &Py_ops_sensNodePressure); addCommand("getNumElements", &Py_ops_getNumElements); + addCommand("getEleClassTags", &Py_ops_getEleClassTags); addCommand("getEleLoadClassTags", &Py_ops_getEleLoadClassTags); addCommand("getEleLoadTags", &Py_ops_getEleLoadTags); addCommand("getEleLoadData", &Py_ops_getEleLoadData); diff --git a/SRC/interpreter/TclWrapper.cpp b/SRC/interpreter/TclWrapper.cpp index 4cbd26acc..b75503e03 100644 --- a/SRC/interpreter/TclWrapper.cpp +++ b/SRC/interpreter/TclWrapper.cpp @@ -1317,6 +1317,15 @@ static int Tcl_ops_getNumElements(ClientData clientData, Tcl_Interp *interp, int return TCL_OK; } +static int Tcl_ops_getEleClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + wrapper->resetCommandLine(argc, 1, argv); + + if (OPS_getEleClassTags() < 0) return TCL_ERROR; + + return TCL_OK; +} + static int Tcl_ops_getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { wrapper->resetCommandLine(argc, 1, argv); @@ -1690,6 +1699,7 @@ TclWrapper::addOpenSeesCommands(Tcl_Interp* interp) addCommand(interp,"sensSectionForce", &Tcl_ops_sensSectionForce); addCommand(interp,"sensNodePressure", &Tcl_ops_sensNodePressure); addCommand(interp,"getNumElements", &Tcl_ops_getNumElements); + addCommand(interp,"getEleClassTags", &Tcl_ops_getEleClassTags); addCommand(interp,"getEleLoadClassTags", &Tcl_ops_getEleLoadClassTags); addCommand(interp,"getEleLoadTags", &Tcl_ops_getEleLoadTags); addCommand(interp,"getEleLoadData", &Tcl_ops_getEleLoadData); From c64203a8b151efc29fa82638d9d84fefe7188606 Mon Sep 17 00:00:00 2001 From: Seweryn Kokot Date: Tue, 30 Mar 2021 12:58:58 +0200 Subject: [PATCH 032/207] Element load output commands: no pattern tag means all pattern tags --- SRC/interpreter/OpenSeesOutputCommands.cpp | 160 ++++++++++++++------- 1 file changed, 108 insertions(+), 52 deletions(-) diff --git a/SRC/interpreter/OpenSeesOutputCommands.cpp b/SRC/interpreter/OpenSeesOutputCommands.cpp index 076fb1e1e..be90e1354 100644 --- a/SRC/interpreter/OpenSeesOutputCommands.cpp +++ b/SRC/interpreter/OpenSeesOutputCommands.cpp @@ -45,6 +45,7 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #include #include #include +#include #include #include // #include @@ -3161,27 +3162,44 @@ int OPS_getEleLoadClassTags() if (theDomain == 0) return -1; int numdata = OPS_GetNumRemainingInputArgs(); + + std::vector data; + if (numdata < 1) { - opserr << "WARNING want - getEleLoadClassTags patternTag?\n"; - return -1; - } + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain->getLoadPatterns(); - int patternTag; - numdata = 1; - if (OPS_GetIntInput(&numdata, &patternTag) < 0) { - opserr << "could not read patternTag\n"; - return -1; - } + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; - LoadPattern *thePattern = theDomain->getLoadPattern(patternTag); - ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); - ElementalLoad* theLoad; + while ((theLoad = theEleLoads()) != 0) { + data.push_back(theLoad->getClassTag()); + } - std::vector data; + } + + } else if (numdata == 1) { + + int patternTag; + if (OPS_GetIntInput(&numdata, &patternTag) < 0) { + opserr << "could not read patternTag\n"; + return -1; + } + + LoadPattern *thePattern = theDomain->getLoadPattern(patternTag); + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + while ((theLoad = theEleLoads()) != 0) { + data.push_back(theLoad->getClassTag()); + } + + } else { + opserr << "WARNING want - getEleLoadClassTags \n"; + return -1; + } - while ((theLoad = theEleLoads()) != 0) { - data.push_back(theLoad->getClassTag()); - } int size = data.size(); @@ -3199,27 +3217,43 @@ int OPS_getEleLoadTags() if (theDomain == 0) return -1; int numdata = OPS_GetNumRemainingInputArgs(); + + std::vector data; + if (numdata < 1) { - opserr << "WARNING want - getEleLoadTags patternTag?\n"; - return -1; - } + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain->getLoadPatterns(); - int patternTag; - numdata = 1; - if (OPS_GetIntInput(&numdata, &patternTag) < 0) { - opserr << "could not read patternTag\n"; - return -1; - } + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + while ((theLoad = theEleLoads()) != 0) { + data.push_back(theLoad->getElementTag()); + } - LoadPattern* thePattern = theDomain->getLoadPattern(patternTag); - ElementalLoadIter& theEleLoads = thePattern->getElementalLoads(); - ElementalLoad* theLoad; + } - std::vector data; + } else if (numdata == 1) { - while ((theLoad = theEleLoads()) != 0) { - data.push_back(theLoad->getElementTag()); - } + int patternTag; + if (OPS_GetIntInput(&numdata, &patternTag) < 0) { + opserr << "could not read patternTag\n"; + return -1; + } + + LoadPattern* thePattern = theDomain->getLoadPattern(patternTag); + ElementalLoadIter& theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + while ((theLoad = theEleLoads()) != 0) { + data.push_back(theLoad->getElementTag()); + } + + } else { + opserr << "WARNING want - getEleLoadTags \n"; + return -1; + } int size = data.size(); @@ -3237,34 +3271,56 @@ int OPS_getEleLoadData() if (theDomain == 0) return -1; int numdata = OPS_GetNumRemainingInputArgs(); + + std::vector data; + if (numdata < 1) { - opserr << "WARNING want - getEleLoadData patternTag?\n"; - return -1; - } + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain->getLoadPatterns(); + + int typeEL; + + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter &theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + while ((theLoad = theEleLoads()) != 0) { + const Vector &eleLoadData = theLoad->getData(typeEL, 1.0); + + int eleLoadDataSize = eleLoadData.Size(); + for (int i = 0; i < eleLoadDataSize; i++) { + data.push_back(eleLoadData(i)); + } + } + } - int patternTag; - numdata = 1; - if (OPS_GetIntInput(&numdata, &patternTag) < 0) { - opserr << "could not read patternTag\n"; - return -1; - } + } else if (numdata == 1) { - LoadPattern* thePattern = theDomain->getLoadPattern(patternTag); - ElementalLoadIter& theEleLoads = thePattern->getElementalLoads(); - ElementalLoad* theLoad; + int patternTag; + if (OPS_GetIntInput(&numdata, &patternTag) < 0) { + opserr << "could not read patternTag\n"; + return -1; + } - std::vector data; + LoadPattern* thePattern = theDomain->getLoadPattern(patternTag); + ElementalLoadIter& theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; - int typeEL; + int typeEL; - while ((theLoad = theEleLoads()) != 0) { - const Vector &eleLoadData = theLoad->getData(typeEL, 1.0); + while ((theLoad = theEleLoads()) != 0) { + const Vector &eleLoadData = theLoad->getData(typeEL, 1.0); - int eleLoadDataSize = eleLoadData.Size(); - for (int i = 0; i < eleLoadDataSize; i++) { - data.push_back(eleLoadData(i)); + int eleLoadDataSize = eleLoadData.Size(); + for (int i = 0; i < eleLoadDataSize; i++) { + data.push_back(eleLoadData(i)); + } } - } + + } else { + opserr << "WARNING want - getEleLoadData \n"; + return -1; + } int size = data.size(); From cc40c4b1ed4e32a1fd44d6a32c180e067fc0ee89 Mon Sep 17 00:00:00 2001 From: Seweryn Kokot Date: Thu, 1 Apr 2021 07:16:40 +0200 Subject: [PATCH 033/207] add the output commands to the Tcl interpreter --- SRC/tcl/commands.cpp | 216 +++++++++++++++++++++++++++++++++++++++++++ SRC/tcl/commands.h | 14 +++ 2 files changed, 230 insertions(+) diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index 3c5a1ca6f..3a6cb68ad 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -990,6 +990,17 @@ int OpenSeesAppInit(Tcl_Interp *interp) { Tcl_CreateCommand(interp, "getParamValue", &getParamValue, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "getNumElements", &getNumElements, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "getEleClassTags", &getEleClassTags, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "getEleLoadClassTags", &getEleLoadClassTags, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "getEleLoadTags", &getEleLoadTags, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "getEleLoadData", &getEleLoadData, + (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); + Tcl_CreateCommand(interp, "sdfResponse", &sdfResponse, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); @@ -8459,6 +8470,211 @@ getNP(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) return TCL_OK; } +// sewi +int +getNumElements(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + char buffer[20]; + + sprintf(buffer, "%d ", theDomain.getNumElements()); + Tcl_AppendResult(interp, buffer, NULL); + + return TCL_OK; +} + +// sewi +int +getEleClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + + if (argc == 1) { + Element *theEle; + ElementIter &eleIter = theDomain.getElements(); + + char buffer[20]; + + while ((theEle = eleIter()) != 0) { + sprintf(buffer, "%d ", theEle->getClassTag()); + Tcl_AppendResult(interp, buffer, NULL); + } + } else if (argc == 2) { + int eleTag; + + if (Tcl_GetInt(interp, argv[1], &eleTag) != TCL_OK) { + opserr << "WARNING getParamValue -- could not read paramTag \n"; + return TCL_ERROR; + } + + Element *theEle = theDomain.getElement(eleTag); + + char buffer[20]; + + sprintf(buffer, "%d ", theEle->getClassTag()); + Tcl_AppendResult(interp, buffer, NULL); + + } else { + opserr << "WARNING want - getEleClassTags \n" << endln; + return TCL_ERROR; + } + + return TCL_OK; +} + +int +getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + + if (argc == 1) { + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain.getLoadPatterns(); + + char buffer[20]; + + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad *theLoad; + + while ((theLoad = theEleLoads()) != 0) { + sprintf(buffer, "%d ", theLoad->getClassTag()); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + } else if (argc == 2) { + int patternTag; + + if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { + opserr << "WARNING getParamValue -- could not read paramTag \n"; + return TCL_ERROR; + } + + LoadPattern *thePattern = theDomain.getLoadPattern(patternTag); + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + char buffer[20]; + + while ((theLoad = theEleLoads()) != 0) { + sprintf(buffer, "%d ", theLoad->getClassTag()); + Tcl_AppendResult(interp, buffer, NULL); + } + + } else { + opserr << "WARNING want - getEleLoadClassTags \n" << endln; + return TCL_ERROR; + } + + return TCL_OK; +} + +int +getEleLoadTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + + if (argc == 1) { + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain.getLoadPatterns(); + + char buffer[20]; + + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad *theLoad; + + while ((theLoad = theEleLoads()) != 0) { + sprintf(buffer, "%d ", theLoad->getElementTag()); + Tcl_AppendResult(interp, buffer, NULL); + } + } + + } else if (argc == 2) { + int patternTag; + + if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { + opserr << "WARNING getParamValue -- could not read paramTag \n"; + return TCL_ERROR; + } + + LoadPattern *thePattern = theDomain.getLoadPattern(patternTag); + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + char buffer[20]; + + while ((theLoad = theEleLoads()) != 0) { + sprintf(buffer, "%d ", theLoad->getElementTag()); + Tcl_AppendResult(interp, buffer, NULL); + } + + } else { + opserr << "WARNING want - getEleLoadTags \n" << endln; + return TCL_ERROR; + } + + return TCL_OK; +} + +int +getEleLoadData(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +{ + + if (argc == 1) { + LoadPattern *thePattern; + LoadPatternIter &thePatterns = theDomain.getLoadPatterns(); + + char buffer[40]; + int typeEL; + + while ((thePattern = thePatterns()) != 0) { + ElementalLoadIter &theEleLoads = thePattern->getElementalLoads(); + ElementalLoad *theLoad; + + while ((theLoad = theEleLoads()) != 0) { + const Vector &eleLoadData = theLoad->getData(typeEL, 1.0); + + int eleLoadDataSize = eleLoadData.Size(); + opserr << "eleLoadDataSize: "<< eleLoadDataSize << "\n"; + for (int i = 0; i < eleLoadDataSize; i++) { + sprintf(buffer, "%35.20f ", eleLoadData(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + } + } + + } else if (argc == 2) { + int patternTag; + + if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { + opserr << "WARNING getParamValue -- could not read paramTag \n"; + return TCL_ERROR; + } + + LoadPattern *thePattern = theDomain.getLoadPattern(patternTag); + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); + ElementalLoad* theLoad; + + int typeEL; + char buffer[40]; + + while ((theLoad = theEleLoads()) != 0) { + const Vector &eleLoadData = theLoad->getData(typeEL, 1.0); + + int eleLoadDataSize = eleLoadData.Size(); + for (int i = 0; i < eleLoadDataSize; i++) { + sprintf(buffer, "%35.20f ", eleLoadData(i)); + Tcl_AppendResult(interp, buffer, NULL); + } + + } + + } else { + opserr << "WARNING want - getEleLoadTags \n" << endln; + return TCL_ERROR; + } + + return TCL_OK; +} + int getEleTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) { diff --git a/SRC/tcl/commands.h b/SRC/tcl/commands.h index 89539c806..c4e7b2341 100644 --- a/SRC/tcl/commands.h +++ b/SRC/tcl/commands.h @@ -254,6 +254,20 @@ int sensitivityIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); // AddingSensitivity:END /////////////////////////////////////////////////// +int +getNumElements(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); + +int +getEleClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); + +int +getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); + +int +getEleLoadTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); + +int +getEleLoadData(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); int startTimer(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); From a2976e4a8c4b825e682aa766491021222b7ce2cb Mon Sep 17 00:00:00 2001 From: Seweryn Kokot Date: Fri, 2 Apr 2021 08:57:31 +0200 Subject: [PATCH 034/207] add error messages when the patternTag does not exist, minor fixes --- SRC/interpreter/OpenSeesOutputCommands.cpp | 18 +++++++++++++----- SRC/tcl/commands.cpp | 21 ++++++++++++++++++--- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/SRC/interpreter/OpenSeesOutputCommands.cpp b/SRC/interpreter/OpenSeesOutputCommands.cpp index be90e1354..6cbefb682 100644 --- a/SRC/interpreter/OpenSeesOutputCommands.cpp +++ b/SRC/interpreter/OpenSeesOutputCommands.cpp @@ -48,10 +48,6 @@ UPDATES, ENHANCEMENTS, OR MODIFICATIONS. #include #include #include -// #include -// #include -// #include -// #include #include #include #include @@ -3188,6 +3184,10 @@ int OPS_getEleLoadClassTags() } LoadPattern *thePattern = theDomain->getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadClassTags\n"; + return -1; + } ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); ElementalLoad* theLoad; @@ -3243,6 +3243,10 @@ int OPS_getEleLoadTags() } LoadPattern* thePattern = theDomain->getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadTags\n"; + return -1; + } ElementalLoadIter& theEleLoads = thePattern->getElementalLoads(); ElementalLoad* theLoad; @@ -3279,7 +3283,7 @@ int OPS_getEleLoadData() LoadPatternIter &thePatterns = theDomain->getLoadPatterns(); int typeEL; - + while ((thePattern = thePatterns()) != 0) { ElementalLoadIter &theEleLoads = thePattern->getElementalLoads(); ElementalLoad* theLoad; @@ -3303,6 +3307,10 @@ int OPS_getEleLoadData() } LoadPattern* thePattern = theDomain->getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadData\n"; + return -1; + } ElementalLoadIter& theEleLoads = thePattern->getElementalLoads(); ElementalLoad* theLoad; diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index 3a6cb68ad..35ae786b0 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -8544,11 +8544,16 @@ getEleLoadClassTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Cha int patternTag; if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { - opserr << "WARNING getParamValue -- could not read paramTag \n"; + opserr << "WARNING getEleLoadClassTags -- could not read patternTag\n"; return TCL_ERROR; } LoadPattern *thePattern = theDomain.getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadClassTags\n"; + return TCL_ERROR; + } + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); ElementalLoad* theLoad; @@ -8591,11 +8596,16 @@ getEleLoadTags(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **a int patternTag; if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { - opserr << "WARNING getParamValue -- could not read paramTag \n"; + opserr << "WARNING getEleLoadTags -- could not read patternTag \n"; return TCL_ERROR; } LoadPattern *thePattern = theDomain.getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadTags\n"; + return TCL_ERROR; + } + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); ElementalLoad* theLoad; @@ -8645,11 +8655,16 @@ getEleLoadData(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **a int patternTag; if (Tcl_GetInt(interp, argv[1], &patternTag) != TCL_OK) { - opserr << "WARNING getParamValue -- could not read paramTag \n"; + opserr << "WARNING getEleLoadData -- could not read patternTag \n"; return TCL_ERROR; } LoadPattern *thePattern = theDomain.getLoadPattern(patternTag); + if (thePattern == nullptr) { + opserr << "ERROR load pattern with tag " << patternTag << " not found in domain -- getEleLoadData\n"; + return TCL_ERROR; + } + ElementalLoadIter theEleLoads = thePattern->getElementalLoads(); ElementalLoad* theLoad; From 97ebde208239b848e8c3971deeae73da0bd738c8 Mon Sep 17 00:00:00 2001 From: ambaker1 Date: Wed, 7 Apr 2021 11:14:04 -0400 Subject: [PATCH 035/207] Renamed ndm and ndf to getNDM and getNDF This should be more consistent with other queries such as getTime. --- SRC/tcl/commands.cpp | 8 ++++---- SRC/tcl/commands.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index bc35d11d9..0113c88cc 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -811,9 +811,9 @@ int OpenSeesAppInit(Tcl_Interp *interp) { Tcl_CreateObjCommand(interp, "source", &OPS_SourceCmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "ndm", &ndm, + Tcl_CreateCommand(interp, "getNDM", &getNDM, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); - Tcl_CreateCommand(interp, "ndf", &ndf, + Tcl_CreateCommand(interp, "getNDF", &getNDF, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); Tcl_CreateCommand(interp, "wipe", &wipeModel, @@ -6689,7 +6689,7 @@ updateElementDomain(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Cha } int -ndm(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) +getNDM(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) { int ndm; @@ -6723,7 +6723,7 @@ ndm(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) } int -ndf(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) +getNDF(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) { int ndf; diff --git a/SRC/tcl/commands.h b/SRC/tcl/commands.h index d210f290c..e54764203 100644 --- a/SRC/tcl/commands.h +++ b/SRC/tcl/commands.h @@ -48,10 +48,10 @@ int OPS_SourceCmd(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj * const *argv); int -ndm(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); +getNDM(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); int -ndf(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); +getNDF(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv); int wipeModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); From 0eb869d96db8b1f32a9cf160d6ced4840c4abc58 Mon Sep 17 00:00:00 2001 From: Minjie Zhu Date: Wed, 7 Apr 2021 17:53:09 +0000 Subject: [PATCH 036/207] add pc command --- .gitignore | 1 + .../constraints/Pressure_Constraint.cpp | 38 +++++++++++++++++++ SRC/interpreter/OpenSeesCommands.h | 1 + SRC/interpreter/PythonWrapper.cpp | 11 ++++++ 4 files changed, 51 insertions(+) diff --git a/.gitignore b/.gitignore index 761ef63aa..accf9f068 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ cmake-build-release # VSCode .vscode +.clang-format # OTHER Makefile.def diff --git a/SRC/domain/constraints/Pressure_Constraint.cpp b/SRC/domain/constraints/Pressure_Constraint.cpp index 87dc836dc..e8cfab361 100644 --- a/SRC/domain/constraints/Pressure_Constraint.cpp +++ b/SRC/domain/constraints/Pressure_Constraint.cpp @@ -46,6 +46,44 @@ #include #include #include +#include + +int OPS_Pressure_Constraint() { + Domain* theDomain = OPS_GetDomain(); + + if (theDomain == 0) { + opserr << "WARNING: domain is not defined\n"; + return -1; + } + + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "WARNING: need nodeTag, pNodeTag\n"; + return -1; + } + + // get node tags + int tags[2]; + int num = 2; + if (OPS_GetIntInput(&num, &tags[0]) < 0) { + opserr << "WARNING: invalid node tag\n"; + return -1; + } + + // set domain + Pressure_Constraint* pc = new Pressure_Constraint(tags[0], tags[1]); + if (pc == 0) { + opserr << "WARNING: failed to create pc\n"; + return -1; + } + + if (theDomain->addPressure_Constraint(pc) == false) { + opserr << "WARNING: failed to add pc to domain\n"; + delete pc; + return -1; + } + + return 0; +} Pressure_Constraint::Pressure_Constraint(int classTag) :DomainComponent(0,classTag), pTag(0), fluidEleTags(), otherEleTags(), diff --git a/SRC/interpreter/OpenSeesCommands.h b/SRC/interpreter/OpenSeesCommands.h index a389deb76..0ec8a14a0 100644 --- a/SRC/interpreter/OpenSeesCommands.h +++ b/SRC/interpreter/OpenSeesCommands.h @@ -397,6 +397,7 @@ int OPS_HomogeneousBC_X(); int OPS_HomogeneousBC_Y(); int OPS_HomogeneousBC_Z(); int OPS_ShallowFoundationGen(); +int OPS_Pressure_Constraint(); void* OPS_TimeSeriesIntegrator(); diff --git a/SRC/interpreter/PythonWrapper.cpp b/SRC/interpreter/PythonWrapper.cpp index aacce860b..f3e7c0189 100644 --- a/SRC/interpreter/PythonWrapper.cpp +++ b/SRC/interpreter/PythonWrapper.cpp @@ -2220,6 +2220,16 @@ static PyObject *Py_ops_partition(PyObject *self, PyObject *args) return wrapper->getResults(); } +static PyObject *Py_ops_pc(PyObject *self, PyObject *args) { + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_Pressure_Constraint() < 0) { + opserr << (void *)0; + return NULL; + } + + return wrapper->getResults(); +} ///////////////////////////////////////////////// ////////////// Add Python commands ////////////// @@ -2403,6 +2413,7 @@ PythonWrapper::addOpenSeesCommands() addCommand("strengthDegradation", &Py_ops_strengthDegradation); addCommand("unloadingRule", &Py_ops_unloadingRule); addCommand("partition", &Py_ops_partition); + addCommand("pc", &Py_ops_pc); PyMethodDef method = {NULL,NULL,0,NULL}; methodsOpenSees.push_back(method); From ea533d8d2f19a495451add50f7c3ff9537043ba5 Mon Sep 17 00:00:00 2001 From: "Michael H. Scott" Date: Wed, 7 Apr 2021 13:10:30 -0700 Subject: [PATCH 037/207] Update PythonWrapper.cpp --- SRC/interpreter/PythonWrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRC/interpreter/PythonWrapper.cpp b/SRC/interpreter/PythonWrapper.cpp index f3e7c0189..4b25809cb 100644 --- a/SRC/interpreter/PythonWrapper.cpp +++ b/SRC/interpreter/PythonWrapper.cpp @@ -2413,7 +2413,7 @@ PythonWrapper::addOpenSeesCommands() addCommand("strengthDegradation", &Py_ops_strengthDegradation); addCommand("unloadingRule", &Py_ops_unloadingRule); addCommand("partition", &Py_ops_partition); - addCommand("pc", &Py_ops_pc); + addCommand("pressureConstraint", &Py_ops_pc); PyMethodDef method = {NULL,NULL,0,NULL}; methodsOpenSees.push_back(method); From 24b1cdc25b153b775c4a24f51dd608da2b926690 Mon Sep 17 00:00:00 2001 From: mhscott Date: Thu, 8 Apr 2021 10:58:33 -0700 Subject: [PATCH 038/207] interpreter/OpenSeesSectionCommands.cpp --- SRC/material/section/Elliptical2.cpp | 77 +++++++ .../section/TclModelBuilderSectionCommand.cpp | 204 ++---------------- 2 files changed, 92 insertions(+), 189 deletions(-) diff --git a/SRC/material/section/Elliptical2.cpp b/SRC/material/section/Elliptical2.cpp index 15359ba62..98bfe91c7 100644 --- a/SRC/material/section/Elliptical2.cpp +++ b/SRC/material/section/Elliptical2.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,82 @@ Vector Elliptical2::s(2); Matrix Elliptical2::ks(2,2); ID Elliptical2::code(2); +void* OPS_Elliptical2() +{ + if (OPS_GetNumRemainingInputArgs() < 8) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: section Elliptical tag? E1? E2? sigY1? sigY2? Hiso? Hkin1? Hkin2? " << endln; + return 0; + } + + int tag; + int numdata = 1; + if (OPS_GetIntInput(&numdata, &tag) < 0) { + opserr << "WARNING invalid Elliptical tag" << endln; + return 0; + } + + numdata = 7; + double data[7]; + if (OPS_GetDoubleInput(&numdata, data) < 0) { + opserr << "WARNING invalid double inputs\n"; + opserr << "section Elliptical: " << tag << endln; + return 0; + } + double E1 = data[0]; + double E2 = data[1]; + double sigY1 = data[2]; + double sigY2 = data[3]; + double Hi = data[4]; + double Hk1 = data[5]; + double Hk2 = data[6]; + + if (OPS_GetNumRemainingInputArgs() > 1) { + int code1, code2; + const char* type1 = OPS_GetString(); + const char* type2 = OPS_GetString(); + if (strcmp(type1,"Mz") == 0) + code1 = SECTION_RESPONSE_MZ; + else if (strcmp(type1,"P") == 0) + code1 = SECTION_RESPONSE_P; + else if (strcmp(type1,"Vy") == 0) + code1 = SECTION_RESPONSE_VY; + else if (strcmp(type1,"My") == 0) + code1 = SECTION_RESPONSE_MY; + else if (strcmp(type1,"Vz") == 0) + code1 = SECTION_RESPONSE_VZ; + else if (strcmp(type1,"T") == 0) + code1 = SECTION_RESPONSE_T; + else { + opserr << "WARNING invalid code 1 " << type1 << endln; + opserr << "section Elliptical: " << tag << endln; + return 0; + } + + if (strcmp(type2,"Mz") == 0) + code2 = SECTION_RESPONSE_MZ; + else if (strcmp(type2,"P") == 0) + code2 = SECTION_RESPONSE_P; + else if (strcmp(type2,"Vy") == 0) + code2 = SECTION_RESPONSE_VY; + else if (strcmp(type2,"My") == 0) + code2 = SECTION_RESPONSE_MY; + else if (strcmp(type2,"Vz") == 0) + code2 = SECTION_RESPONSE_VZ; + else if (strcmp(type2,"T") == 0) + code2 = SECTION_RESPONSE_T; + else { + opserr << "WARNING invalid code 2 " << type2 << endln; + opserr << "section Elliptical: " << tag << endln; + return 0; + } + return new Elliptical2(tag, E1, E2, sigY1, sigY2, Hi, Hk1, Hk2, code1, code2); + } else { + return new Elliptical2(tag, E1, E2, sigY1, sigY2, Hi, Hk1, Hk2); + } + +} + Elliptical2::Elliptical2 (int tag, double e1, double e2, double sy1, double sy2, double Hi, double Hk1, double Hk2, int c1, int c2) : diff --git a/SRC/material/section/TclModelBuilderSectionCommand.cpp b/SRC/material/section/TclModelBuilderSectionCommand.cpp index b77d73b23..34ef9d45e 100755 --- a/SRC/material/section/TclModelBuilderSectionCommand.cpp +++ b/SRC/material/section/TclModelBuilderSectionCommand.cpp @@ -111,6 +111,8 @@ extern void *OPS_RCTunnelSection(void); extern void *OPS_UniaxialSection(void); extern void *OPS_TubeSection(void); extern void *OPS_ParallelSection(void); +extern void *OPS_Bidirectional(void); +extern void *OPS_Elliptical2(void); int TclCommand_addFiberSection (ClientData clientData, Tcl_Interp *interp, int argc, @@ -835,196 +837,20 @@ TclModelBuilderSectionCommand (ClientData clientData, Tcl_Interp *interp, int ar //end L.Jiang [SIF] added based on LayeredShellFiberSectionThermal section created by Yuli Huang & Xinzheng Lu ---- else if (strcmp(argv[1],"Bidirectional") == 0) { - if (argc < 7) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: section Bidirectional tag? E? sigY? Hiso? Hkin?" << endln; - return TCL_ERROR; - } - - int tag; - double E, sigY, Hi, Hk; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid Bidirectional tag" << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &E) != TCL_OK) { - opserr << "WARNING invalid E\n"; - opserr << "section Bidirectional: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &sigY) != TCL_OK) { - opserr << "WARNING invalid sigY\n"; - opserr << "section Bidirectional: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &Hi) != TCL_OK) { - opserr << "WARNING invalid Hiso\n"; - opserr << "section Bidirectional: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &Hk) != TCL_OK) { - opserr << "WARNING invalid Hkin\n"; - opserr << "section Bidirectional: " << tag << endln; - return TCL_ERROR; - } - - if (argc > 8) { - int code1, code2; - if (strcmp(argv[7],"Mz") == 0) - code1 = SECTION_RESPONSE_MZ; - else if (strcmp(argv[7],"P") == 0) - code1 = SECTION_RESPONSE_P; - else if (strcmp(argv[7],"Vy") == 0) - code1 = SECTION_RESPONSE_VY; - else if (strcmp(argv[7],"My") == 0) - code1 = SECTION_RESPONSE_MY; - else if (strcmp(argv[7],"Vz") == 0) - code1 = SECTION_RESPONSE_VZ; - else if (strcmp(argv[7],"T") == 0) - code1 = SECTION_RESPONSE_T; - else { - opserr << "WARNING invalid code 1 " << argv[7] << endln; - opserr << "section Bidirectional: " << tag << endln; - return TCL_ERROR; - } - - if (strcmp(argv[8],"Mz") == 0) - code2 = SECTION_RESPONSE_MZ; - else if (strcmp(argv[8],"P") == 0) - code2 = SECTION_RESPONSE_P; - else if (strcmp(argv[8],"Vy") == 0) - code2 = SECTION_RESPONSE_VY; - else if (strcmp(argv[8],"My") == 0) - code2 = SECTION_RESPONSE_MY; - else if (strcmp(argv[8],"Vz") == 0) - code2 = SECTION_RESPONSE_VZ; - else if (strcmp(argv[8],"T") == 0) - code2 = SECTION_RESPONSE_T; - else { - opserr << "WARNING invalid code 2 " << argv[8] << endln; - opserr << "section Bidirectional: " << tag << endln; - return TCL_ERROR; - } - theSection = new Bidirectional(tag, E, sigY, Hi, Hk, code1, code2); - } - else - theSection = new Bidirectional(tag, E, sigY, Hi, Hk); - - } - - else if (strcmp(argv[1],"Elliptical") == 0 || strcmp(argv[1],"Elliptical2") == 0) { - if (argc < 10) { - opserr << "WARNING insufficient arguments\n"; - opserr << "Want: section Elliptical tag? E1? E2? sigY1? sigY2? Hiso? Hkin1? Hkin2? " << endln; - return TCL_ERROR; - } - - int tag; - double E1, E2, sigY1, sigY2, Hi, Hk1, Hk2; - - if (Tcl_GetInt(interp, argv[2], &tag) != TCL_OK) { - opserr << "WARNING invalid Elliptical tag" << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[3], &E1) != TCL_OK) { - opserr << "WARNING invalid E1\n"; - opserr << "section Elliptical: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[4], &E2) != TCL_OK) { - opserr << "WARNING invalid E2\n"; - opserr << "section Elliptical: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[5], &sigY1) != TCL_OK) { - opserr << "WARNING invalid sigY1\n"; - opserr << "section Elliptical: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[6], &sigY2) != TCL_OK) { - opserr << "WARNING invalid sigY2\n"; - opserr << "section Elliptical: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[7], &Hi) != TCL_OK) { - opserr << "WARNING invalid Hiso\n"; - opserr << "section Elliptical: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[8], &Hk1) != TCL_OK) { - opserr << "WARNING invalid Hkin1\n"; - opserr << "section Elliptical: " << tag << endln; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[9], &Hk2) != TCL_OK) { - opserr << "WARNING invalid Hkin2\n"; - opserr << "section Elliptical: " << tag << endln; - return TCL_ERROR; - } - - if (argc > 11) { - int code1, code2; - if (strcmp(argv[10],"Mz") == 0) - code1 = SECTION_RESPONSE_MZ; - else if (strcmp(argv[10],"P") == 0) - code1 = SECTION_RESPONSE_P; - else if (strcmp(argv[10],"Vy") == 0) - code1 = SECTION_RESPONSE_VY; - else if (strcmp(argv[10],"My") == 0) - code1 = SECTION_RESPONSE_MY; - else if (strcmp(argv[10],"Vz") == 0) - code1 = SECTION_RESPONSE_VZ; - else if (strcmp(argv[10],"T") == 0) - code1 = SECTION_RESPONSE_T; - else { - opserr << "WARNING invalid code 1 " << argv[10] << endln; - opserr << "section Elliptical: " << tag << endln; - return TCL_ERROR; - } + void *theMat = OPS_Bidirectional(); + if (theMat != 0) + theSection = (SectionForceDeformation *)theMat; + else + return TCL_ERROR; + } - if (strcmp(argv[11],"Mz") == 0) - code2 = SECTION_RESPONSE_MZ; - else if (strcmp(argv[11],"P") == 0) - code2 = SECTION_RESPONSE_P; - else if (strcmp(argv[11],"Vy") == 0) - code2 = SECTION_RESPONSE_VY; - else if (strcmp(argv[11],"My") == 0) - code2 = SECTION_RESPONSE_MY; - else if (strcmp(argv[11],"Vz") == 0) - code2 = SECTION_RESPONSE_VZ; - else if (strcmp(argv[11],"T") == 0) - code2 = SECTION_RESPONSE_T; - else { - opserr << "WARNING invalid code 2 " << argv[11] << endln; - opserr << "section Elliptical: " << tag << endln; - return TCL_ERROR; - } - if (strcmp(argv[1],"Elliptical") == 0) - //theSection = new Elliptical(tag, E1, E2, sigY1, sigY2, Hi, Hk1, Hk2, code1, code2); - theSection = new Elliptical2(tag, E1, E2, sigY1, sigY2, Hi, Hk1, Hk2, code1, code2); - else - theSection = new Elliptical2(tag, E1, E2, sigY1, sigY2, Hi, Hk1, Hk2, code1, code2); - } - else { - if (strcmp(argv[1],"Elliptical") == 0) - //theSection = new Elliptical(tag, E1, E2, sigY1, sigY2, Hi, Hk1, Hk2); - theSection = new Elliptical2(tag, E1, E2, sigY1, sigY2, Hi, Hk1, Hk2); - else - theSection = new Elliptical2(tag, E1, E2, sigY1, sigY2, Hi, Hk1, Hk2); - } - } + else if (strcmp(argv[1],"Elliptical") == 0 || strcmp(argv[1],"Elliptical2") == 0) { + void *theMat = OPS_Elliptical2(); + if (theMat != 0) + theSection = (SectionForceDeformation *)theMat; + else + return TCL_ERROR; + } else if (strcmp(argv[1],"Iso2spring") == 0) { if (argc < 10) { From 948282afe6284a0967c73a4f70a585db5e14ba76 Mon Sep 17 00:00:00 2001 From: mhscott Date: Thu, 8 Apr 2021 11:00:38 -0700 Subject: [PATCH 039/207] Updating section commands --- SRC/interpreter/OpenSeesSectionCommands.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SRC/interpreter/OpenSeesSectionCommands.cpp b/SRC/interpreter/OpenSeesSectionCommands.cpp index e227ef425..9f1dc5d8b 100644 --- a/SRC/interpreter/OpenSeesSectionCommands.cpp +++ b/SRC/interpreter/OpenSeesSectionCommands.cpp @@ -86,6 +86,7 @@ void* OPS_ElasticPlateSection(); void* OPS_MembranePlateFiberSection(); void* OPS_LayeredShellFiberSection(); void* OPS_Bidirectional(); +void* OPS_Elliptical2(); void* OPS_Isolator2spring(); void* OPS_FiberSection2dThermal(); @@ -1064,6 +1065,7 @@ namespace { functionMap.insert(std::make_pair("PlateFiber", &OPS_MembranePlateFiberSection)); functionMap.insert(std::make_pair("LayeredShell", &OPS_LayeredShellFiberSection)); functionMap.insert(std::make_pair("Bidirectional", &OPS_Bidirectional)); + functionMap.insert(std::make_pair("Elliptical", &OPS_Elliptical2)); functionMap.insert(std::make_pair("Isolator2spring", &OPS_Isolator2spring)); functionMap.insert(std::make_pair("RCCircularSection", &OPS_RCCircularSection)); functionMap.insert(std::make_pair("RCTunnelSection", &OPS_RCTunnelSection)); From 63a49a0f57b5eda27c9174acfd84b948aa2ecd2f Mon Sep 17 00:00:00 2001 From: Zarak Kasi Date: Thu, 8 Apr 2021 14:34:10 -0700 Subject: [PATCH 040/207] Added setNodePressure Command --- SRC/interpreter/OpenSeesCommands.h | 1 + 1 file changed, 1 insertion(+) diff --git a/SRC/interpreter/OpenSeesCommands.h b/SRC/interpreter/OpenSeesCommands.h index 0ec8a14a0..109e7ab34 100644 --- a/SRC/interpreter/OpenSeesCommands.h +++ b/SRC/interpreter/OpenSeesCommands.h @@ -254,6 +254,7 @@ int OPS_eleNodes(); int OPS_nodeDOFs(); int OPS_nodeMass(); int OPS_nodePressure(); +int OPS_setNodePressure(); int OPS_nodeBounds(); int OPS_setPrecision(); int OPS_getEleTags(); From b37a5afcd2c4e085f0dcb84eb99ca4d556273c90 Mon Sep 17 00:00:00 2001 From: Zarak Kasi Date: Thu, 8 Apr 2021 14:34:50 -0700 Subject: [PATCH 041/207] Added setNodePressure Command --- SRC/interpreter/OpenSeesOutputCommands.cpp | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/SRC/interpreter/OpenSeesOutputCommands.cpp b/SRC/interpreter/OpenSeesOutputCommands.cpp index 00dd89bd4..02409717c 100644 --- a/SRC/interpreter/OpenSeesOutputCommands.cpp +++ b/SRC/interpreter/OpenSeesOutputCommands.cpp @@ -1749,6 +1749,40 @@ int OPS_nodePressure() return 0; } +int OPS_setNodePressure() +{ + if (OPS_GetNumRemainingInputArgs() < 2) { + opserr << "WARNING: want - setNodePressure nodeTag? Pressure?\n"; + return -1; + } + + int tag; + int numdata = 1; + + if (OPS_GetIntInput(&numdata, &tag) < 0) { + opserr << "WARNING: setNodePressure invalid tag\n"; + return -1; + } + + Domain* theDomain = OPS_GetDomain(); + if (theDomain == 0) return -1; + + double pressure = 0.0; + + if (OPS_GetDoubleInput(&numdata, &pressure) < 0) { + opserr << "WARNING: setNodePressure invalid pressure\n"; + return -1; + } + + Pressure_Constraint* thePC = theDomain->getPressure_Constraint(tag); + if(thePC != 0) { + thePC->setPressure(pressure); + } + + return 0; +} + + int OPS_nodeBounds() { From d0d286d893d4511a3f9a16e8bf9fb21fe986580b Mon Sep 17 00:00:00 2001 From: Zarak Kasi Date: Thu, 8 Apr 2021 14:35:10 -0700 Subject: [PATCH 042/207] Added setNodePressure Command --- SRC/interpreter/PythonWrapper.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/SRC/interpreter/PythonWrapper.cpp b/SRC/interpreter/PythonWrapper.cpp index 4b25809cb..9febb1e84 100644 --- a/SRC/interpreter/PythonWrapper.cpp +++ b/SRC/interpreter/PythonWrapper.cpp @@ -1163,6 +1163,18 @@ static PyObject *Py_ops_nodePressure(PyObject *self, PyObject *args) return wrapper->getResults(); } +static PyObject *Py_ops_setNodePressure(PyObject *self, PyObject *args) +{ + wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + + if (OPS_setNodePressure() < 0) { + opserr<<(void*)0; + return NULL; + } + + return wrapper->getResults(); +} + static PyObject *Py_ops_nodeBounds(PyObject *self, PyObject *args) { wrapper->resetCommandLine(PyTuple_Size(args), 1, args); @@ -2321,6 +2333,7 @@ PythonWrapper::addOpenSeesCommands() addCommand("nodeDOFs", &Py_ops_nodeDOFs); addCommand("nodeMass", &Py_ops_nodeMass); addCommand("nodePressure", &Py_ops_nodePressure); + addCommand("setNodePressure", &Py_ops_setNodePressure); addCommand("nodeBounds", &Py_ops_nodeBounds); addCommand("start", &Py_ops_startTimer); addCommand("stop", &Py_ops_stopTimer); From 78c5d230799f2ca9d0e5466e7033c8cb9015eb6f Mon Sep 17 00:00:00 2001 From: ambaker1 Date: Sun, 18 Apr 2021 18:20:42 -0400 Subject: [PATCH 043/207] Create MaterialTest.cpp Created MaterialTest Design intent is to be a combination of uniaxial material, ND material, and section testers. Main commands: testUniaxialMaterial testNDMaterial testSection Each of the main test commands will define the test type (1 for uniaxial, 2 for ND, 3 for section), and set the static object to the corresponding material/section. The other commands will each have a switch based on test type (0, 1, 2, and 3). 0 is the default, and will throw an error The other commands are taken from the uniaxial material test commands in the python interpreter, with the exception that setTrialStrain, commitStrain, and getResponse will be added. --- SRC/material/MaterialTest.cpp | 276 ++++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 SRC/material/MaterialTest.cpp diff --git a/SRC/material/MaterialTest.cpp b/SRC/material/MaterialTest.cpp new file mode 100644 index 000000000..1265bfc73 --- /dev/null +++ b/SRC/material/MaterialTest.cpp @@ -0,0 +1,276 @@ +/* ***************************************************************************** +Copyright (c) 2015-2017, The Regents of the University of California (Regents). +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. + +REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS +PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, +UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +*************************************************************************** */ + +// Written: Alex Baker +// Created: 04/21 +// +// Description: This file contains the material testing commands + +#include +#include +#include +#include +#include + +static int testType = 0; +static UniaxialMaterial* theTestingUniaxialMaterial = 0; +static NDMaterial* theTestingNDMaterial = 0; +static SectionForceDeformation* theTestingSection = 0; + +int OPS_testUniaxialMaterial() +{ + if (OPS_GetNumRemainingInputArgs() != 1) { + opserr << "testUniaxialMaterial - You must provide a material tag.\n"; + return -1; + } + + int tag; + int numData = 1; + if (OPS_GetIntInput(&numData, &tag) < 0) { + opserr << "invalid int value\n"; + return -1; + } + + UniaxialMaterial* mat = OPS_getUniaxialMaterial(tag); + + if (mat == 0) { + opserr << "testUniaxialMaterial - Material Not Found.\n"; + return -1; + } + + theTestingUniaxialMaterial = mat; + testType = 1; + + return 0; +} + +int OPS_testNDMaterial() +{ + if (OPS_GetNumRemainingInputArgs() != 1) { + opserr << "testNDMaterial - You must provide a material tag.\n"; + return -1; + } + + int tag; + int numData = 1; + if (OPS_GetIntInput(&numData, &tag) < 0) { + opserr << "invalid int value\n"; + return -1; + } + + NDMaterial* mat = OPS_getNDMaterial(tag); + + if (mat == 0) { + opserr << "testNDMaterial - Material Not Found.\n"; + return -1; + } + + theTestingNDMaterial = mat; + testType = 2; + + return 0; +} + +int OPS_testSection() +{ + if (OPS_GetNumRemainingInputArgs() != 1) { + opserr << "testSection - You must provide a section tag.\n"; + return -1; + } + + int tag; + int numData = 1; + if (OPS_GetIntInput(&numData, &tag) < 0) { + opserr << "invalid int value\n"; + return -1; + } + + SectionForceDeformation* mat = OPS_getNDMaterial(tag); + + if (mat == 0) { + opserr << "testSection - Section Not Found.\n"; + return -1; + } + + theTestingSection = mat; + testType = 3; + + return 0; +} + +int OPS_setStrain() +{ + if (testType == 0) { + opserr << "setStrain WARNING no active test\n"; + return -1; + } + OPS_setTrialStrain() + OPS_commitStrain() +} + +int OPS_setTrialStrain() +{ + if (testType == 0) { + opserr << "setTrialStrain WARNING no active test\n"; + return -1; + } + else if (testType == 1) { + if (OPS_GetNumRemainingInputArgs() != 1) { + opserr << "testUniaxialMaterial - You must provide a strain value.\n"; + return -1; + } + double strain; + int numData = 1; + if (OPS_GetDoubleInput(&numData, &strain) < 0) { + opserr << "invalid double value\n"; + return -1; + } + theTestingUniaxialMaterial->setTrialStrain(strain); + } + else if (testType == 2) { + opserr << "nDMaterial test - not implemented yet\n"; + } + else if (testType == 3) { + opserr << "section test - not implemented yet\n"; + } + + return 0; +} + +int OPS_commitStrain() +{ + if (testType == 0) { + opserr << "commitStrain WARNING no active test\n"; + return -1; + } + else if (testType == 1) { + theTestingUniaxialMaterial->commitState(); + } + else if (testType == 2) { + theTestingNDMaterial->commitState(); + } + else if (testType == 3) { + theTestingSection->commitState(); + } +} + +int OPS_getStrain() +{ + if (testType == 0) { + opserr << "getStrain WARNING no active test\n"; + return -1; + } + else if (testType == 1) { + double strain = theTestingUniaxialMaterial->getStrain(); + } + else if (testType == 2) { + double strain = theTestingNDMaterial->getStrain(); + } + else if (testType == 3) { + double strain = theTestingSection->getStrain(); + } + + double strain = material->getStrain(); + + int numData = 1; + + if (OPS_SetDoubleOutput(&numData, &strain, true) < 0) { + opserr << "failed to set strain\n"; + return -1; + } + + return 0; +} + +int OPS_getStress() +{ + UniaxialMaterial* material = theTestingUniaxialMaterial; + if (material == 0) { + opserr << "getStrain WARNING no active UniaxialMaterial - use testUniaxialMaterial command.\n"; + return -1; + } + + double stress = material->getStress(); + + int numData = 1; + + if (OPS_SetDoubleOutput(&numData, &stress, true) < 0) { + opserr << "failed to set stress\n"; + return -1; + } + + return 0; +} + +int OPS_getTangent() +{ + UniaxialMaterial* material = theTestingUniaxialMaterial; + if (material == 0) { + opserr << "getStrain WARNING no active UniaxialMaterial - use testUniaxialMaterial command.\n"; + return -1; + } + + double tangent = material->getTangent(); + + int numData = 1; + + if (OPS_SetDoubleOutput(&numData, &tangent, true) < 0) { + opserr << "failed to set tangent\n"; + return -1; + } + + return 0; +} + +int OPS_getDampTangent() +{ + UniaxialMaterial* material = theTestingUniaxialMaterial; + if (material == 0) { + opserr << "getStrain WARNING no active UniaxialMaterial - use testUniaxialMaterial command.\n"; + return -1; + } + + double tangent = material->getDampTangent(); + + int numData = 1; + + if (OPS_SetDoubleOutput(&numData, &tangent, true) < 0) { + opserr << "failed to set damp tangent\n"; + return -1; + } + + return 0; +} \ No newline at end of file From 770aab4362fb0414fd6ac0b4534dec858ae28faa Mon Sep 17 00:00:00 2001 From: ambaker1 Date: Sun, 18 Apr 2021 22:28:46 -0400 Subject: [PATCH 044/207] Update MaterialTest.cpp Rough draft. Does not compile yet. Each set/get function switches for test type. Some require dynamic arrays. Not sure how to implement into OpenSees from here. --- SRC/material/MaterialTest.cpp | 221 +++++++++++++++++++++++++--------- 1 file changed, 163 insertions(+), 58 deletions(-) diff --git a/SRC/material/MaterialTest.cpp b/SRC/material/MaterialTest.cpp index 1265bfc73..1607e138b 100644 --- a/SRC/material/MaterialTest.cpp +++ b/SRC/material/MaterialTest.cpp @@ -118,7 +118,7 @@ int OPS_testSection() return -1; } - SectionForceDeformation* mat = OPS_getNDMaterial(tag); + SectionForceDeformation* mat = OPS_getSectionForceDeformation(tag); if (mat == 0) { opserr << "testSection - Section Not Found.\n"; @@ -133,38 +133,53 @@ int OPS_testSection() int OPS_setStrain() { + // check if test is active if (testType == 0) { opserr << "setStrain WARNING no active test\n"; return -1; } - OPS_setTrialStrain() - OPS_commitStrain() + // check if any input values + if (OPS_GetNumRemainingInputArgs() == 0) { + opserr << "setStrain WARNING must provide strain values.\n"; + return -1; + } + // call sub-routines + OPS_setTrialStrain(); + OPS_commitStrain(); } int OPS_setTrialStrain() { + // check if test is active if (testType == 0) { opserr << "setTrialStrain WARNING no active test\n"; return -1; } - else if (testType == 1) { - if (OPS_GetNumRemainingInputArgs() != 1) { - opserr << "testUniaxialMaterial - You must provide a strain value.\n"; - return -1; - } - double strain; - int numData = 1; - if (OPS_GetDoubleInput(&numData, &strain) < 0) { - opserr << "invalid double value\n"; + // check if any input values + if (OPS_GetNumRemainingInputArgs() == 0) { + opserr << "setTrialStrain WARNING must provide strain values.\n"; + return -1; + } + // get strain values from input + double strain; + int numData = OPS_GetNumRemainingInputArgs(); + if (OPS_GetDoubleInput(&numData, &strain) < 0) { + opserr << "invalid double value\n"; + return -1; + } + // switch for test type + if (testType == 1) { + if (numData != 1) { + opserr << "setTrialStrain WARNING wrong number of arguments.\n"; return -1; } theTestingUniaxialMaterial->setTrialStrain(strain); } else if (testType == 2) { - opserr << "nDMaterial test - not implemented yet\n"; + theTestingNDMaterial->setTrialStrain(strain); } else if (testType == 3) { - opserr << "section test - not implemented yet\n"; + theTestingSection->setTrialSectionDeformation(strain); } return 0; @@ -172,6 +187,7 @@ int OPS_setTrialStrain() int OPS_commitStrain() { + // switch for test type if (testType == 0) { opserr << "commitStrain WARNING no active test\n"; return -1; @@ -189,27 +205,47 @@ int OPS_commitStrain() int OPS_getStrain() { + // switch for test type if (testType == 0) { opserr << "getStrain WARNING no active test\n"; return -1; } else if (testType == 1) { double strain = theTestingUniaxialMaterial->getStrain(); + int numData = 1; + // set output + if (OPS_SetDoubleOutput(&numData, &strain, true) < 0) { + opserr << "failed to get strain\n"; + return -1; + } } else if (testType == 2) { - double strain = theTestingNDMaterial->getStrain(); + const Vector& strain = theTestingNDMaterial->getStrain(); + int numData = strain.Size(); + // convert to double + double* data = new double[numData]; + for (int i = 0; i < numData; i++) + data[i] = strain(i); + // set output + if (OPS_SetDoubleOutput(&numData, data, true) < 0) { + opserr << "failed to get strain\n"; + return -1; + } + delete[] data; } else if (testType == 3) { - double strain = theTestingSection->getStrain(); - } - - double strain = material->getStrain(); - - int numData = 1; - - if (OPS_SetDoubleOutput(&numData, &strain, true) < 0) { - opserr << "failed to set strain\n"; - return -1; + const Vector& strain = theTestingSection->getSectionDeformation(); + int numData = strain.Size(); + // convert to double + double* data = new double[numData]; + for (int i = 0; i < numData; i++) + data[i] = strain(i); + // set output + if (OPS_SetDoubleOutput(&numData, data, true) < 0) { + opserr << "failed to get strain\n"; + return -1; + } + delete[] data; } return 0; @@ -217,19 +253,47 @@ int OPS_getStrain() int OPS_getStress() { - UniaxialMaterial* material = theTestingUniaxialMaterial; - if (material == 0) { - opserr << "getStrain WARNING no active UniaxialMaterial - use testUniaxialMaterial command.\n"; + // switch for test type + if (testType == 0) { + opserr << "getStress WARNING no active test\n"; return -1; } - - double stress = material->getStress(); - - int numData = 1; - - if (OPS_SetDoubleOutput(&numData, &stress, true) < 0) { - opserr << "failed to set stress\n"; - return -1; + else if (testType == 1) { + double stress = theTestingUniaxialMaterial->getStress(); + int numData = 1; + // set output + if (OPS_SetDoubleOutput(&numData, &stress, true) < 0) { + opserr << "failed to get stress\n"; + return -1; + } + } + else if (testType == 2) { + const Vector& stress = theTestingNDMaterial->getStress(); + int numData = stress.Size(); + // convert to double + double* data = new double[numData]; + for (int i = 0; i < numData; i++) + data[i] = stress(i); + // set output + if (OPS_SetDoubleOutput(&numData, data, true) < 0) { + opserr << "failed to get stress\n"; + return -1; + } + delete[] data; + } + else if (testType == 3) { + const Vector& stress = theTestingSection->getStressResultant(); + int numData = stress.Size(); + // convert to double + double* data = new double[numData]; + for (int i = 0; i < numData; i++) + data[i] = stress(i); + // set output + if (OPS_SetDoubleOutput(&numData, data, true) < 0) { + opserr << "failed to get stress\n"; + return -1; + } + delete[] data; } return 0; @@ -237,19 +301,55 @@ int OPS_getStress() int OPS_getTangent() { - UniaxialMaterial* material = theTestingUniaxialMaterial; - if (material == 0) { - opserr << "getStrain WARNING no active UniaxialMaterial - use testUniaxialMaterial command.\n"; + // switch for test type + if (testType == 0) { + opserr << "getTangent WARNING no active test\n"; return -1; } - - double tangent = material->getTangent(); - - int numData = 1; - - if (OPS_SetDoubleOutput(&numData, &tangent, true) < 0) { - opserr << "failed to set tangent\n"; - return -1; + else if (testType == 1) { + double tangent = theTestingUniaxialMaterial->getTangent(); + int numData = 1; + // set output + if (OPS_SetDoubleOutput(&numData, &tangent, true) < 0) { + opserr << "failed to get tangent\n"; + return -1; + } + } + else if (testType == 2) { + const Matrix& tangent = theTestingNDMaterial->getTangent(); + int numData = tangent.noCols() * tangent.noRows(); + // convert to double + double* data = new double[numData]; + int k = 0; + for (int i = 0; i < tangent.noRows(); i++) + for (int j = 0; j < tangent.noCols(); j++) { + data[k] = tangent(i, j); + k++; + } + // set output + if (OPS_SetDoubleOutput(&numData, data, true) < 0) { + opserr << "failed to get tangent\n"; + return -1; + } + delete[] data; + } + else if (testType == 3) { + const Matrix& tangent = theTestingSection->getSectionTangent(); + int numData = tangent.noCols() * tangent.noRows(); + // convert to double + double* data = new double[numData]; + int k = 0; + for (int i = 0; i < tangent.noRows(); i++) + for (int j = 0; j < tangent.noCols(); j++) { + data[k] = tangent(i, j); + k++; + } + // set output + if (OPS_SetDoubleOutput(&numData, data, true) < 0) { + opserr << "failed to get tangent\n"; + return -1; + } + delete[] data; } return 0; @@ -257,19 +357,24 @@ int OPS_getTangent() int OPS_getDampTangent() { - UniaxialMaterial* material = theTestingUniaxialMaterial; - if (material == 0) { - opserr << "getStrain WARNING no active UniaxialMaterial - use testUniaxialMaterial command.\n"; + // switch for test type + if (testType == 0) { + opserr << "getDampTangent WARNING no active test\n"; return -1; } - - double tangent = material->getDampTangent(); - - int numData = 1; - - if (OPS_SetDoubleOutput(&numData, &tangent, true) < 0) { - opserr << "failed to set damp tangent\n"; - return -1; + else if (testType == 1) { + double dampTangent = theTestingUniaxialMaterial->getDampTangent(); + int numData = 1; + if (OPS_SetDoubleOutput(&numData, &dampTangent, true) < 0) { + opserr << "failed to get damping tangent\n"; + return -1; + } + } + else if (testType == 2) { + opserr << "damping tangent not implemented for nDMaterials\n"; + } + else if (testType == 3) { + opserr << "damping tangent not implemented for sections\n"; } return 0; From 2acc27bcd53207444fcf5e2aec9a24d51de43c08 Mon Sep 17 00:00:00 2001 From: ambaker1 Date: Sun, 18 Apr 2021 22:43:36 -0400 Subject: [PATCH 045/207] Moved file to SRC/interpreter Maybe better suited here. Need to figure out how the interpreter cpp files add commands to Tcl. (they currently don't) --- .../OpenSeesMaterialTestCommands.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename SRC/{material/MaterialTest.cpp => interpreter/OpenSeesMaterialTestCommands.cpp} (100%) diff --git a/SRC/material/MaterialTest.cpp b/SRC/interpreter/OpenSeesMaterialTestCommands.cpp similarity index 100% rename from SRC/material/MaterialTest.cpp rename to SRC/interpreter/OpenSeesMaterialTestCommands.cpp From 4954ba2371c74cb7bde341445fad77a0d353be69 Mon Sep 17 00:00:00 2001 From: Seweryn Kokot Date: Tue, 27 Apr 2021 09:54:22 +0200 Subject: [PATCH 046/207] fix commands.cpp due to CRLF issue - stage 1 --- SRC/tcl/commands.cpp | 20779 +++++++++++++++++++++-------------------- 1 file changed, 10482 insertions(+), 10297 deletions(-) diff --git a/SRC/tcl/commands.cpp b/SRC/tcl/commands.cpp index 35ae786b0..d22be31f9 100644 --- a/SRC/tcl/commands.cpp +++ b/SRC/tcl/commands.cpp @@ -1,10297 +1,10482 @@ -/* ****************************************************************** ** -** OpenSees System for Earthquake Engineering Simulation ** -** Pacific Earthquake Engineering Research Center ** -** ** -** ** -** (C) Copyright 1999, The Regents of the University of California ** -** All Rights Reserved. ** -** ** -** Commercial use of this program without express permission of the ** -** University of California, Berkeley, is strictly prohibited. See ** -** file 'COPYRIGHT' in main directory for information on usage and ** -** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. ** -** ** -** Developed by: ** -** Frank McKenna (fmckenna@ce.berkeley.edu) ** -** Gregory L. Fenves (fenves@ce.berkeley.edu) ** -** Filip C. Filippou (filippou@ce.berkeley.edu) ** -** ** -** ****************************************************************** */ - -// $Revision$ -// $Date$ -// $URL$ - - -// Written: fmk -// Created: 04/98 -// -// Description: This file contains the functions that will be called by -// the interpreter when the appropriate command name is specified, -// see tkAppInit.C for command names. - -#include - -#include - -#ifdef _PARALLEL_PROCESSING -#include -#elif _PARALLEL_INTERPRETERS -#include -#endif - -extern "C" { -#include -} - -#include -#include -#include - -extern void OPS_clearAllUniaxialMaterial(void); -extern void OPS_clearAllNDMaterial(void); -extern void OPS_clearAllSectionForceDeformation(void); - -extern void OPS_clearAllHystereticBackbone(void); -extern void OPS_clearAllStiffnessDegradation(void); -extern void OPS_clearAllStrengthDegradation(void); -extern void OPS_clearAllUnloadingRule(void); - -// the following is a little kludgy but it works! -#ifdef _USING_STL_STREAMS - -#include -using std::ios; -#include -using std::ofstream; - -#else - -#include -#include -#include - -bool OPS_suppressOpenSeesOutput = false; -StandardStream sserr; -OPS_Stream *opserrPtr = &sserr; - -#endif - - -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include "commands.h" - -// domain - #ifdef _PARALLEL_PROCESSING -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include //Joey UC Davis -#include //Joey UC Davis -#include -#include -#include -#include -#include - -// analysis model -#include - -// convergence tests -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// soln algorithms -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// accelerators -#include -#include -#include -#include -#include -#include -//#include - -// line searches -#include -#include -#include -#include - -// constraint handlers -#include -#include -//#include -#include -#include - -// numberers -#include -#include - -// integrators -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include //Abbas - -// recorders -#include //SAJalali - -extern void *OPS_NewtonRaphsonAlgorithm(void); -extern void *OPS_ModifiedNewton(void); -extern void *OPS_NewtonHallM(void); - -extern void *OPS_Newmark(void); -extern void *OPS_StagedNewmark(void); -extern void *OPS_GimmeMCK(void); -extern void *OPS_AlphaOS(void); -extern void *OPS_AlphaOS_TP(void); -extern void *OPS_AlphaOSGeneralized(void); -extern void *OPS_AlphaOSGeneralized_TP(void); -extern void *OPS_CentralDifference(void); -extern void *OPS_CentralDifferenceAlternative(void); -extern void *OPS_CentralDifferenceNoDamping(void); -extern void *OPS_Collocation(void); -extern void *OPS_CollocationHSFixedNumIter(void); -extern void *OPS_CollocationHSIncrLimit(void); -extern void *OPS_CollocationHSIncrReduct(void); -extern void *OPS_GeneralizedAlpha(void); -extern void *OPS_HHT(void); -extern void *OPS_HHT_TP(void); -extern void *OPS_HHTExplicit(void); -extern void *OPS_HHTExplicit_TP(void); -extern void *OPS_HHTGeneralized(void); -extern void *OPS_HHTGeneralized_TP(void); -extern void *OPS_HHTGeneralizedExplicit(void); -extern void *OPS_HHTGeneralizedExplicit_TP(void); -extern void *OPS_HHTHSFixedNumIter(void); -extern void *OPS_HHTHSFixedNumIter_TP(void); -extern void *OPS_HHTHSIncrLimit(void); -extern void *OPS_HHTHSIncrLimit_TP(void); -extern void *OPS_HHTHSIncrReduct(void); -extern void *OPS_HHTHSIncrReduct_TP(void); -extern void *OPS_KRAlphaExplicit(void); -extern void *OPS_KRAlphaExplicit_TP(void); -extern void *OPS_NewmarkExplicit(void); -extern void *OPS_NewmarkHSFixedNumIter(void); -extern void *OPS_NewmarkHSIncrLimit(void); -extern void *OPS_NewmarkHSIncrReduct(void); -extern void *OPS_WilsonTheta(void); - -// for response spectrum analysis -extern void OPS_DomainModalProperties(void); -extern void OPS_ResponseSpectrumAnalysis(void); - -#include -#include -#include -#include -#include -#include -#include -#include - -// analysis -#include -#include -#include -#include - -// system of eqn and solvers -#include -#include - -#include -#include - -#include - -#ifdef _ITPACK -//#include -//#include -#endif - -#include -#include - -#include -#include -#include -#include - -#include -#include - -// #include -// #include -// #include -// #include - -#include -#include -#include -#include -#include -#include -#ifdef _MUMPS -#include -#include -#endif - -#ifdef _THREADS -#include -#else -#include -#endif - -#ifdef _CUSP -#include -#endif - -#ifdef _CULAS4 -#include -#endif - -#ifdef _CULAS5 -#include -#endif - -#ifdef _MUMPS -#ifdef _PARALLEL_PROCESSING -#include -#include -#elif _PARALLEL_INTERPRETERS -#include -#include -#else -#include -#include -#endif -#endif - -#ifdef _PETSC -#include -#include -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _CUDA -#include -#include -#endif - - -// graph -#include -#include - -#include -#include - -#ifdef _NOGRAPHICS - -#else -#include -#endif - -#include - -#ifdef _RELIABILITY -// AddingSensitivity:BEGIN ///////////////////////////////////////////////// -#include -#include -// #include -// #include -//#include -// #include -// #include -// #include -// #include -//#include -//#include -//#include -//#include -// AddingSensitivity:END ///////////////////////////////////////////////// -#include - -int reliability(ClientData, Tcl_Interp *, int, TCL_Char **); -int wipeReliability(ClientData, Tcl_Interp *, int, TCL_Char **); -int optimization(ClientData, Tcl_Interp *, int, TCL_Char **); //Quan (2) - -#endif - -const char * getInterpPWD(Tcl_Interp *interp); - -#include - - -#include - -ModelBuilder *theBuilder =0; - -// some global variables -#ifdef _PARALLEL_PROCESSING - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// parallel analysis -#include -#include -#include - -// parallel soe & solvers -#include -#include -#include -#include -#include -#include - -#define MPIPP_H -#include -#include - -//MachineBroker *theMachineBroker = 0; -PartitionedDomain theDomain; -int OPS_PARALLEL_PROCESSING =0; -int OPS_NUM_SUBDOMAINS =0; -bool OPS_PARTITIONED =false; -bool OPS_USING_MAIN_DOMAIN = false; -int OPS_MAIN_DOMAIN_PARTITION_ID =0; - -DomainPartitioner *OPS_DOMAIN_PARTITIONER =0; -GraphPartitioner *OPS_GRAPH_PARTITIONER =0; -LoadBalancer *OPS_BALANCER = 0; -FEM_ObjectBroker *OPS_OBJECT_BROKER =0; -MachineBroker *OPS_MACHINE =0; -Channel **OPS_theChannels = 0; - -bool setMPIDSOEFlag = false; - -#elif _PARALLEL_INTERPRETERS - -bool setMPIDSOEFlag = false; - -// parallel analysis -#include -#include - -// parallel soe & solvers -#include -#include -#include - - -#include -#include -#include -#include -#include -#define MPIPP_H -#include -#include - -Domain theDomain; - -#else - -Domain theDomain; - -#endif - -#include - -MachineBroker *theMachineBroker =0; -Channel **theChannels =0; -int numChannels =0; -int OPS_rank =0; -int OPS_np =0; - - -typedef struct parameterValues { - char *value; - struct parameterValues *next; -} OpenSeesTcl_ParameterValues; - - -typedef struct parameter { - char *name; - OpenSeesTcl_ParameterValues *values; - struct parameter *next; -} OpenSeesTcl_Parameter; - - -static OpenSeesTcl_Parameter *theParameters = NULL; -static OpenSeesTcl_Parameter *endParameters = NULL; - -static int numParam = 0; -static char **paramNames =0; -static char **paramValues =0; - -AnalysisModel *theAnalysisModel =0; -EquiSolnAlgo *theAlgorithm =0; -ConstraintHandler *theHandler =0; -DOF_Numberer *theNumberer =0; -LinearSOE *theSOE =0; -EigenSOE *theEigenSOE =0; -StaticAnalysis *theStaticAnalysis = 0; -DirectIntegrationAnalysis *theTransientAnalysis = 0; -VariableTimeStepDirectIntegrationAnalysis *theVariableTimeStepTransientAnalysis = 0; -int numEigen = 0; - -static PFEMAnalysis* thePFEMAnalysis = 0; - -// AddingSensitivity:BEGIN ///////////////////////////////////////////// -#ifdef _RELIABILITY -static TclReliabilityBuilder *theReliabilityBuilder = 0; - -Integrator *theSensitivityAlgorithm = 0; -Integrator *theSensitivityIntegrator = 0; -//FMK RELIABILITY ReliabilityStaticAnalysis *theReliabilityStaticAnalysis = 0; -//FMK RELIABILITY ReliabilityDirectIntegrationAnalysis *theReliabilityTransientAnalysis = 0; - -// static NewmarkSensitivityIntegrator *theNSI = 0; -// static NewNewmarkSensitivityIntegrator *theNNSI = 0; -// static PFEMSensitivityIntegrator* thePFEMSI = 0; - -//static SensitivityIntegrator *theSensitivityIntegrator = 0; -//static NewmarkSensitivityIntegrator *theNSI = 0; - -#include -static TclOptimizationBuilder *theOptimizationBuilder = 0; // Quan March 2010 (3) - -#endif -// AddingSensitivity:END /////////////////////////////////////////////// - - -StaticIntegrator *theStaticIntegrator =0; -TransientIntegrator *theTransientIntegrator =0; -ConvergenceTest *theTest =0; -bool builtModel = false; - -static char *resDataPtr = 0; -static int resDataSize = 0; -static Timer *theTimer = 0; - -#include -#include -SimulationInformation simulationInfo; -SimulationInformation *theSimulationInfoPtr = 0; - -char *simulationInfoOutputFilename = 0; - - -FE_Datastore *theDatabase =0; -FEM_ObjectBrokerAllClasses theBroker; - -// init the global variabled defined in OPS_Globals.h -// double ops_Dt = 1.0; -// Element *ops_TheActiveElement = 0; -// bool ops_InitialStateAnalysis = false; // McGann, U.Washington - -#ifdef _NOGRAPHICS - -#else -TclVideoPlayer *theTclVideoPlayer =0; -#endif - -// g3AppInit() is the method called by tkAppInit() when the -// interpreter is being set up .. this is where all the -// commands defined in this file are registered with the interpreter. - - -int -printModelGID(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -printB(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -setPrecision(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -logFile(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -version(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -getPID(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -getNP(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -opsBarrier(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -domainChange(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -record(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -opsSend(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -opsRecv(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -opsPartition(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - - -int -peerNGA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -defaultUnits(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -stripOpenSeesXML(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -setParameter(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -//extern -int OpenSeesExit(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -extern int myCommands(Tcl_Interp *interp); - -//extern "C" int Tcl_InterpObjCmd(ClientData clientData, -// Tcl_Interp *interp, -// int objc, -// Tcl_Obj *const objv[]); - -int -convertBinaryToText(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -convertTextToBinary(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - -int -maxOpenFiles(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv); - - - -// pointer for old putsCommand - -static Tcl_ObjCmdProc *Tcl_putsCommand = 0; - -// -// revised puts command to send to cerr! -// - -int OpenSees_putsCommand(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) -{ - Tcl_Channel chan; /* The channel to puts on. */ - Tcl_Obj *string; /* String to write. */ - Tcl_Obj *chanObjPtr = NULL; /* channel object. */ - int newline; /* Add a newline at end? */ - - switch (objc) { - case 2: /* [puts $x] */ - string = objv[1]; - newline = 1; - break; - - case 3: /* [puts -nonewline $x] or [puts $chan $x] */ - if (strcmp(Tcl_GetString(objv[1]), "-nonewline") == 0) { - newline = 0; - } else { - newline = 1; - chanObjPtr = objv[1]; - } - string = objv[2]; - break; - - case 4: /* [puts -nonewline $chan $x] or [puts $chan $x nonewline] */ - newline = 0; - if (strcmp(Tcl_GetString(objv[1]), "-nonewline") == 0) { - chanObjPtr = objv[2]; - string = objv[3]; - break; - } else if (strcmp(Tcl_GetString(objv[3]), "nonewline") == 0) { - /* - * The code below provides backwards compatibility with an old - * form of the command that is no longer recommended or - * documented. See also [Bug #3151675]. Will be removed in Tcl 9, - * maybe even earlier. - */ - - chanObjPtr = objv[1]; - string = objv[2]; - break; - } - /* Fall through */ - default: - /* [puts] or [puts some bad number of arguments...] */ - Tcl_WrongNumArgs(interp, 1, objv, "?-nonewline? ?channelId? string"); - return TCL_ERROR; - } - - if (chanObjPtr == NULL) { - if (newline == 0) - opserr << Tcl_GetString(string); - else - opserr << Tcl_GetString(string) << endln; - return TCL_OK; - } else { - if (Tcl_putsCommand != 0) { - return Tcl_putsCommand(dummy, interp, objc, objv); - } else { - std::cerr << "MEARD! commands.cpp .. old puts command not found or set!\n"; - return TCL_ERROR; - } - return TCL_OK; - } -} - - -int Tcl_InterpOpenSeesObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) -{ - int index; - static TCL_Char *options[] = { - "alias", "aliases", "create", "delete", - "eval", "exists", "expose", "hide", - "hidden", "issafe", "invokehidden", "marktrusted", - "recursionlimit", "slaves", "share", - "target", "transfer", - NULL - }; - enum option { - OPT_ALIAS, OPT_ALIASES, OPT_CREATE, OPT_DELETE, - OPT_EVAL, OPT_EXISTS, OPT_EXPOSE, OPT_HIDE, - OPT_HIDDEN, OPT_ISSAFE, OPT_INVOKEHID, OPT_MARKTRUSTED, - OPT_RECLIMIT, OPT_SLAVES, OPT_SHARE, - OPT_TARGET, OPT_TRANSFER - }; - - int ok = TCL_OK; - //int ok = Tcl_InterpObjCmd(clientData, interp, objc, objv); - //if (ok != TCL_OK) - //return ok; - - if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &index) != TCL_OK) { - return TCL_ERROR; - } - - switch ((enum option) index) { - case OPT_CREATE: { - TCL_Char *theInterpreterName = Tcl_GetStringResult(interp); - Tcl_Interp *secondaryInterp = Tcl_GetSlave(interp, theInterpreterName); - ok = OpenSeesAppInit(secondaryInterp); - return ok; - break; - } - default: - return ok; - } - - return ok; -} - - -int OpenSeesAppInit(Tcl_Interp *interp) { - - ops_TheActiveDomain = &theDomain; - - // - // redo puts command so we can capture puts into std:cerr - // - - if (OPS_suppressOpenSeesOutput == false) { - // get a handle on puts procedure - Tcl_CmdInfo putsCommandInfo; - Tcl_GetCommandInfo(interp, "puts", &putsCommandInfo); - Tcl_putsCommand = putsCommandInfo.objProc; - // if handle, use ouur procedure as opposed to theirs - if (Tcl_putsCommand != 0) { - Tcl_CreateObjCommand(interp, "oldputs", Tcl_putsCommand, NULL, NULL); - Tcl_CreateObjCommand(interp, "puts", OpenSees_putsCommand, NULL, NULL); - } - } - - theSimulationInfoPtr = &simulationInfo; - -#ifndef _LINUX - opserr.setFloatField(SCIENTIFIC); - opserr.setFloatField(FIXEDD); -#endif - - //Tcl_CreateObjCommand(interp, "interp", Tcl_InterpOpenSeesObjCmd, NULL, NULL); - - Tcl_CreateCommand(interp, "recorderValue", &OPS_recorderValue, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); //by SAJalali - - Tcl_CreateObjCommand(interp, "pset", &OPS_SetObjCmd, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateObjCommand(interp, "source", &OPS_SourceCmd, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "wipe", &wipeModel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "wipeAnalysis", &wipeAnalysis, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "reset", &resetModel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "initialize", &initializeAnalysis, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "loadConst", &setLoadConst, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "setCreep", &setCreep, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "setTime", &setTime, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "getTime", &getTime, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "getLoadFactor", &getLoadFactor, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "build", &buildModel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "analyze", &analyzeModel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "print", &printModel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "printModel", &printModel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "printA", &printA, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "printB", &printB, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - // Talledo Start - Tcl_CreateCommand(interp, "printGID", &printModelGID, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - // Talledo End - Tcl_CreateCommand(interp, "analysis", &specifyAnalysis, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "system", &specifySOE, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "numberer", &specifyNumberer, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "constraints", &specifyConstraintHandler, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "algorithm", &specifyAlgorithm, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "test", &specifyCTest, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "testNorms", &getCTestNorms, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "testIter", &getCTestIter, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "integrator", &specifyIntegrator, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "recorder", &addRecorder, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "algorithmRecorder", &addAlgoRecorder, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "database", &addDatabase, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "eigen", &eigenAnalysis, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "modalProperties", &modalProperties, - (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); - Tcl_CreateCommand(interp, "responseSpectrum", &responseSpectrum, - (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); - Tcl_CreateCommand(interp, "video", &videoPlayer, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "remove", &removeObject, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "eleForce", &eleForce, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "localForce", &localForce, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "eleDynamicalForce", &eleDynamicalForce, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "eleResponse", &eleResponse, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodeDisp", &nodeDisp, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "setNodeDisp", &setNodeDisp, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodeReaction", &nodeReaction, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodeUnbalance", &nodeUnbalance, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodeEigenvector", &nodeEigenvector, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodeVel", &nodeVel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "setNodeVel", &setNodeVel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodeAccel", &nodeAccel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "setNodeAccel", &setNodeAccel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodeResponse", &nodeResponse, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "reactions", &calculateNodalReactions, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodeDOFs", &nodeDOFs, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodeCoord", &nodeCoord, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "setNodeCoord", &setNodeCoord, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "updateElementDomain", &updateElementDomain, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "eleNodes", &eleNodes, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodeMass", &nodeMass, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodePressure", &nodePressure, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "nodeBounds", &nodeBounds, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "start", &startTimer, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "stop", &stopTimer, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "rayleigh", &rayleighDamping, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "modalDamping", &modalDamping, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "modalDampingQ", &modalDampingQ, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "setElementRayleighDampingFactors", - &setElementRayleighDampingFactors, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "region", &addRegion, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "logFile", &logFile, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "setPrecision", &setPrecision, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "exit", &OpenSeesExit, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "quit", &OpenSeesExit, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "findNodeWithID", &findID, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "getNP", &getNP, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "getPID", &getPID, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "barrier", &opsBarrier, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "send", &opsSend, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "recv", &opsRecv, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "partition", &opsPartition, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "searchPeerNGA", &peerNGA, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "domainChange", &domainChange,(ClientData)NULL, NULL); - - Tcl_CreateCommand(interp, "record", &record,(ClientData)NULL, NULL); - - Tcl_CreateCommand(interp, "defaultUnits", &defaultUnits,(ClientData)NULL, NULL); - Tcl_CreateCommand(interp, "stripXML", &stripOpenSeesXML,(ClientData)NULL, NULL); - Tcl_CreateCommand(interp, "convertBinaryToText", &convertBinaryToText,(ClientData)NULL, NULL); - Tcl_CreateCommand(interp, "convertTextToBinary", &convertTextToBinary,(ClientData)NULL, NULL); - - Tcl_CreateCommand(interp, "getEleTags", &getEleTags, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "getNodeTags", &getNodeTags, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "getParamTags", &getParamTags, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "getParamValue", &getParamValue, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "getNumElements", &getNumElements, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "getEleClassTags", &getEleClassTags, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "getEleLoadClassTags", &getEleLoadClassTags, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "getEleLoadTags", &getEleLoadTags, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "getEleLoadData", &getEleLoadData, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "sdfResponse", &sdfResponse, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "sectionForce", §ionForce, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sectionDeformation", §ionDeformation, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sectionStiffness", §ionStiffness, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sectionFlexibility", §ionFlexibility, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sectionLocation", §ionLocation, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sectionWeight", §ionWeight, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "basicDeformation", &basicDeformation, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "basicForce", &basicForce, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "basicStiffness", &basicStiffness, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - // command added for initial state analysis for nDMaterials - // Chris McGann, U.Washington - Tcl_CreateCommand(interp, "InitialStateAnalysis", &InitialStateAnalysis, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "totalCPU", &totalCPU, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "solveCPU", &solveCPU, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "accelCPU", &accelCPU, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "numFact", &numFact, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "numIter", &numIter, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "systemSize", &systemSize, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "version", &version, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "setParameter", &setParameter, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - Tcl_CreateCommand(interp, "setMaxOpenFiles", &maxOpenFiles, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - -#ifdef _RELIABILITY - Tcl_CreateCommand(interp, "wipeReliability", wipeReliability, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "reliability", reliability, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - theReliabilityBuilder = 0; -// AddingSensitivity:BEGIN ////////////////////////////////// - Tcl_CreateCommand(interp, "computeGradients", &computeGradients, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sensitivityAlgorithm", &sensitivityAlgorithm, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sensitivityIntegrator", &sensitivityIntegrator, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sensNodeDisp", &sensNodeDisp, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sensLambda", &sensLambda, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); //Abbas - Tcl_CreateCommand(interp, "sensNodeVel", &sensNodeVel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sensNodeAccel", &sensNodeAccel, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sensSectionForce", &sensSectionForce, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - Tcl_CreateCommand(interp, "sensNodePressure", &sensNodePressure, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); - - - theSensitivityAlgorithm =0; - theSensitivityIntegrator =0; - //FMK RELIABILITY theReliabilityStaticAnalysis =0; - //FMK RELIABILITY theReliabilityTransientAnalysis =0; - // AddingSensitivity:END ////////////////////////////////// - - theOptimizationBuilder = 0; - - // --- Quan March 2010 (4) - Tcl_CreateCommand(interp, "optimization", &optimization, - (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); -#endif - - theAlgorithm =0; - theHandler =0; - theNumberer =0; - theAnalysisModel =0; - theSOE =0; - theStaticIntegrator =0; - theTransientIntegrator =0; - theStaticAnalysis =0; - theTransientAnalysis =0; - theVariableTimeStepTransientAnalysis =0; - theTest = 0; - - // create an error handler - -#ifdef _NOGRAPHICS - -#else - theTclVideoPlayer = 0; -#endif - - return myCommands(interp); -} - - - -int -OPS_SetObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]) -{ - - if (objc > 2) - simulationInfo.addParameter(Tcl_GetString(objv[1]), Tcl_GetString(objv[2])); - - Tcl_Obj *varValueObj; - - if (objc == 2) { - varValueObj = Tcl_ObjGetVar2(interp, objv[1], NULL,TCL_LEAVE_ERR_MSG); - if (varValueObj == NULL) { - return TCL_ERROR; - } - Tcl_SetObjResult(interp, varValueObj); - return TCL_OK; - } else if (objc == 3) { - varValueObj = Tcl_ObjSetVar2(interp, objv[1], NULL, objv[2], - TCL_LEAVE_ERR_MSG); - if (varValueObj == NULL) { - return TCL_ERROR; - } - Tcl_SetObjResult(interp, varValueObj); - return TCL_OK; - } else { - Tcl_WrongNumArgs(interp, 1, objv, "varName ?newValue?"); - return TCL_ERROR; - } - - // Tcl_SetObjCmd(clientData, interp, objc, objv); - return 0; -} - -int -OPS_SourceCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ -{ - CONST char *encodingName = NULL; - Tcl_Obj *fileName; - - if (objc != 2 && objc !=4) { - Tcl_WrongNumArgs(interp, 1, objv, "?-encoding name? fileName"); - return TCL_ERROR; - } - - fileName = objv[objc-1]; - - if (objc == 4) { - static CONST char *options[] = { - "-encoding", NULL - }; - int index; - - if (TCL_ERROR == Tcl_GetIndexFromObj(interp, objv[1], options, - "option", TCL_EXACT, &index)) { - return TCL_ERROR; - } - encodingName = Tcl_GetString(objv[2]); - } - - const char *pwd = getInterpPWD(interp); - const char *fileN = Tcl_GetString(fileName); - - simulationInfo.addInputFile(fileN, pwd); - -#ifndef _TCL85 - return Tcl_EvalFile(interp, fileN); -#else - return Tcl_FSEvalFileEx(interp, fileName, encodingName); -#endif -} - -#ifdef _RELIABILITY - -// -- optimization Quan March 2010 (5) -int -optimization(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - - if (theOptimizationBuilder == 0) { - - theOptimizationBuilder = new TclOptimizationBuilder(theDomain , interp); - - - return TCL_OK; - } - else - return TCL_ERROR; -} - - -int -reliability(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - if (theReliabilityBuilder == 0) { - - theReliabilityBuilder = new TclReliabilityBuilder(theDomain,interp); - return TCL_OK; - } - else - return TCL_ERROR; -} - - - - -int -wipeReliability(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - if (theReliabilityBuilder != 0) { - delete theReliabilityBuilder; - theReliabilityBuilder = 0; - } - return TCL_OK; - -} - -int -sensitivityIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - // Does nothing, but keeping command for backward compatibility - return TCL_OK; -} - -int -sensitivityAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - bool withRespectToRVs = true; - bool newalgorithm = false; - int analysisTypeTag = 1; - if(theStaticIntegrator != 0) { - theSensitivityIntegrator = theStaticIntegrator; - } else if(theTransientIntegrator != 0) { - theSensitivityIntegrator = theTransientIntegrator; - } - // 1: compute at each step (default); 2: compute by command - - if (argc < 2) { - opserr << "ERROR: Wrong number of parameters to sensitivity algorithm." << endln; - return TCL_ERROR; - } - if (theReliabilityBuilder == 0) { - opserr << "The command 'reliability' needs to be issued before " << endln - << " the sensitivity algorithm can be created." << endln; - return TCL_ERROR; - } - else if (theSensitivityIntegrator == 0) { - opserr << "The sensitivity integrator needs to be instantiated before " << endln - << " the sensitivity algorithm can be created." << endln; - return TCL_ERROR; - } - - if (strcmp(argv[1],"-computeAtEachStep") == 0) - analysisTypeTag = 1; - else if (strcmp(argv[1],"-computeByCommand") == 0) - analysisTypeTag = 2; - else { - opserr << "Unknown sensitivity algorithm option: " << argv[1] << endln; - return TCL_ERROR; - } - - ReliabilityDomain *theReliabilityDomain; - theReliabilityDomain = theReliabilityBuilder->getReliabilityDomain(); - if(newalgorithm){ - // theSensitivityAlgorithm = new - // NewSensitivityAlgorithm(theReliabilityDomain, - // &theDomain, - // theAlgorithm, - // theSensitivityIntegrator, - // analysisTypeTag); - } else { - // theSensitivityAlgorithm = new - // SensitivityAlgorithm(&theDomain, - // theAlgorithm, - // theSensitivityIntegrator, - // analysisTypeTag); - - - IncrementalIntegrator *theIntegrator = 0; - - if (theStaticAnalysis != 0 && theStaticIntegrator != 0) { - theIntegrator = theStaticIntegrator; - - theIntegrator->setComputeType(analysisTypeTag); - theIntegrator->activateSensitivityKey(); - - } else if (theTransientAnalysis != 0 && theTransientIntegrator != 0) { - - theIntegrator = theTransientIntegrator; - theIntegrator->setComputeType(analysisTypeTag); - theIntegrator->activateSensitivityKey(); - - } - - if (theIntegrator == 0) { - opserr << "ERROR: Could not create theSensitivityAlgorithm. " << endln; - return TCL_ERROR; - } - // ---- by Quan 2009 for recover the previous framework --- - - if (theIntegrator->shouldComputeAtEachStep()) { - - //if (theStaticAnalysis !=0) - //theStaticAnalysis->setSensitivityAlgorithm(theIntegrator); - //else if (theTransientAnalysis !=0) - //theTransientAnalysis->setSensitivityAlgorithm(theIntegrator); - //else if (theVariableTimeStepTransientAnalysis !=0) - //theVariableTimeStepTransientAnalysis->setSensitivityAlgorithm(theIntegrator); - // else { - // // do nothing - // } - - - } - } - - return TCL_OK; -} - -// AddingSensitivity:END ///////////////////////////////////////////////// - -#endif - - -int -wipeModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - wipeAnalysis(clientData, interp, argc, argv); - - /* - // to build the model make sure the ModelBuilder has been constructed - // and that the model has not already been constructed - if (theBuilder != 0) { - delete theBuilder; - builtModel = false; - theBuilder = 0; - } - - if (theStaticAnalysis != 0) { - theStaticAnalysis->clearAll(); - delete theStaticAnalysis; - } - - if (theTransientAnalysis != 0) { - theTransientAnalysis->clearAll(); - delete theTransientAnalysis; - } - */ - - // NOTE : DON'T do the above on theVariableTimeStepAnalysis - // as it and theTansientAnalysis are one in the same - if (theDatabase != 0) - delete theDatabase; - - theDomain.clearAll(); - OPS_clearAllUniaxialMaterial(); - OPS_clearAllNDMaterial(); - OPS_clearAllSectionForceDeformation(); - - OPS_clearAllHystereticBackbone(); - OPS_clearAllStiffnessDegradation(); - OPS_clearAllStrengthDegradation(); - OPS_clearAllUnloadingRule(); - - ops_Dt = 0.0; - - -#ifdef _PARALLEL_PROCESSING - OPS_PARTITIONED = false; -#endif - -#ifdef _NOGRAPHICS - -#else - if (theTclVideoPlayer != 0) { - delete theTclVideoPlayer; - theTclVideoPlayer = 0; - } -#endif - - theAlgorithm =0; - theHandler =0; - theNumberer =0; - theAnalysisModel =0; - theSOE =0; - theStaticIntegrator =0; - theTransientIntegrator =0; - theStaticAnalysis =0; - theTransientAnalysis =0; - theVariableTimeStepTransientAnalysis =0; - - theTest = 0; - theDatabase = 0; - -// AddingSensitivity:BEGIN ///////////////////////////////////////////////// -#ifdef _RELIABILITY - //theSensitivityAlgorithm =0; - theSensitivityIntegrator =0; -#endif -// AddingSensitivity:END ///////////////////////////////////////////////// - - // the domain deletes the record objects, - // just have to delete the private array - return TCL_OK; -} - -int -wipeAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - -#ifdef _PARALLEL_PROCESSING - if (OPS_PARTITIONED == true && OPS_NUM_SUBDOMAINS > 1) { - SubdomainIter &theSubdomains = theDomain.getSubdomains(); - Subdomain *theSub =0; - - // create the appropriate domain decomposition analysis - while ((theSub = theSubdomains()) != 0) - theSub->wipeAnalysis(); - } -#endif - - if (theStaticAnalysis != 0) { - theStaticAnalysis->clearAll(); - delete theStaticAnalysis; - } - - if (theTransientAnalysis != 0) { - theTransientAnalysis->clearAll(); - delete theTransientAnalysis; - } - - // NOTE : DON'T do the above on theVariableTimeStepAnalysis - // as it and theTansientAnalysis are one in the same - - theAlgorithm =0; - theHandler =0; - theNumberer =0; - theAnalysisModel =0; - theSOE =0; - theEigenSOE =0; - theStaticIntegrator =0; - theTransientIntegrator =0; - theStaticAnalysis =0; - theTransientAnalysis =0; - theVariableTimeStepTransientAnalysis =0; - // theSensitivityAlgorithm=0; - thePFEMAnalysis = 0; - theTest = 0; - -// AddingSensitivity:BEGIN ///////////////////////////////////////////////// -#ifdef _RELIABILITY - theSensitivityAlgorithm =0; - theSensitivityIntegrator =0; -#endif -// AddingSensitivity:END ///////////////////////////////////////////////// - // the domain deletes the record objects, - // just have to delete the private array - - return TCL_OK; -} - -// by SAJalali -int OPS_recorderValue(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - // make sure at least one other argument to contain type of system - - // clmnID starts from 1 - if (argc < 3) { - opserr << "WARNING want - recorderValue recorderTag clmnID <-reset>\n"; - return TCL_ERROR; - } - - int tag, rowOffset; - int dof = -1; - - if (Tcl_GetInt(interp, argv[1], &tag) != TCL_OK) { - opserr << "WARNING recorderValue recorderTag? clmnID <-reset> could not read recorderTag \n"; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[2], &dof) != TCL_OK) { - opserr << "WARNING recorderValue recorderTag? clmnID - could not read clmnID \n"; - return TCL_ERROR; - } - dof--; - rowOffset = 0; - int curArg = 3; - if (argc > curArg) - { - if (Tcl_GetInt(interp, argv[curArg], &rowOffset) != TCL_OK) { - opserr << "WARNING recorderValue recorderTag? clmnID <-reset> could not read rowOffset \n"; - return TCL_ERROR; - } - curArg++; - } - bool reset = false; - if (argc > curArg) - { - if (strcmp(argv[curArg], "-reset") == 0) - reset = true; - curArg++; - } - Recorder* theRecorder = theDomain.getRecorder(tag); - double res = theRecorder->getRecordedValue(dof, rowOffset, reset); - // now we copy the value to the tcl string that is returned - //sprintf(interp->result, "%35.8f ", res); - char buffer [40]; - sprintf(buffer,"%35.8f", res); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - - return TCL_OK; -} - -int -resetModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - theDomain.revertToStart(); - - if (theTransientIntegrator != 0) { - theTransientIntegrator->revertToStart(); - } - - return TCL_OK; -} - -int -initializeAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - if (theTransientAnalysis != 0) - theTransientAnalysis->initialize(); - else if (theStaticAnalysis != 0) - theStaticAnalysis->initialize(); - - theDomain.initialize(); - - return TCL_OK; -} - - -int -setLoadConst(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - theDomain.setLoadConstant(); - if (argc == 3) { - if( strcmp(argv[1],"-time") == 0) { - double newTime; - if (Tcl_GetDouble(interp, argv[2], &newTime) != TCL_OK) { - opserr << "WARNING readingvalue - loadConst -time value \n"; - return TCL_ERROR; - } else { - theDomain.setCurrentTime(newTime); - theDomain.setCommittedTime(newTime); - } - } - } - - return TCL_OK; -} - -int -setCreep(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - if (argc < 2) { - opserr << "WARNING illegal command - setCreep value? \n"; - return TCL_ERROR; - } - int newFlag; - if (Tcl_GetInt(interp, argv[1], &newFlag) != TCL_OK) { - opserr << "WARNING reading creep value - setCreep newFlag? \n"; - return TCL_ERROR; - } else { - theDomain.setCreep(newFlag); - } - return TCL_OK; -} - -int -setTime(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - if (argc < 2) { - opserr << "WARNING illegal command - time pseudoTime? \n"; - return TCL_ERROR; - } - double newTime; - if (Tcl_GetDouble(interp, argv[1], &newTime) != TCL_OK) { - opserr << "WARNING reading time value - time pseudoTime? \n"; - return TCL_ERROR; - } else { - theDomain.setCurrentTime(newTime); - theDomain.setCommittedTime(newTime); - } - return TCL_OK; -} - -int -getTime(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - double time = theDomain.getCurrentTime(); - - // get the display format - char format[80]; - if (argc == 1) { - // strcpy(format,"%f"); - sprintf(format,"%f",time); - } else if (argc == 2) { - // strcpy(format,argv[1]); - sprintf(format,argv[1],time); - } - - // now we copy the value to the tcl string that is returned - // sprintf(interp->result,format,time); - Tcl_SetResult(interp, format, TCL_VOLATILE); - return TCL_OK; -} - -int -getLoadFactor(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - if (argc < 2) { - opserr << "WARNING no load pattern supplied -- getLoadFactor\n"; - return TCL_ERROR; - } - - int pattern; - if (Tcl_GetInt(interp, argv[1], &pattern) != TCL_OK) { - opserr << "ERROR reading load pattern tag -- getLoadFactor\n"; - return TCL_ERROR; - } - - LoadPattern *thePattern = theDomain.getLoadPattern(pattern); - if (thePattern == 0) { - opserr << "ERROR load pattern with tag " << pattern << " not found in domain -- getLoadFactor\n"; - return TCL_ERROR; - } - - double factor = thePattern->getLoadFactor(); - - // sprintf(interp->result,"%f",factor); - - char buffer [40]; - sprintf(buffer,"%35.20f", factor); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - - return TCL_OK; -} - -////////////////////////////////////////////////Abbas////////////////////////////// - -int -sensLambda(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv ) -{ - if (argc < 3) { - opserr << "WARNING no load pattern supplied -- getLoadFactor\n"; - return TCL_ERROR; - } - - int pattern, paramTag; - if (Tcl_GetInt(interp, argv[1], &pattern) != TCL_OK) { - opserr << "ERROR reading load pattern tag -- getLoadFactor\n"; - return TCL_ERROR; - } - - LoadPattern *thePattern = theDomain.getLoadPattern(pattern); - if (thePattern == 0) { - opserr << "ERROR load pattern with tag " << pattern << " not found in domain -- getLoadFactor\n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[2], ¶mTag) != TCL_OK) { - opserr << "WARNING sensLambda patternTag? paramTag?- could not read paramTag? "; - return TCL_ERROR; - } - Parameter *theParam = theDomain.getParameter(paramTag); - if (theParam == 0) { - opserr << "sensLambda: parameter " << paramTag << " not found" << endln; - return TCL_ERROR; - } - - IncrementalIntegrator *theIntegrator = 0; - - if (theStaticAnalysis != 0 && theStaticIntegrator != 0) { - theIntegrator = theStaticIntegrator; - // opserr<<" commands.cpp: calling static integrator"<getGradIndex(); - // double factor = thePattern->getSensLambda(theIntegrator); - //double factor = theIntegrator->dLambdadh(gradIndex); - double factor = thePattern->getLoadFactorSensitivity(gradIndex); - - char buffer[40]; - sprintf(buffer,"%35.20f",factor); - - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - - return TCL_OK; -} - - - -//////////////////////////////////////////////Abbas/////////////////////////////////////// - - -// command invoked to build the model, i.e. to invoke buildFE_Model() -// on the ModelBuilder - -int -buildModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - // to build the model make sure the ModelBuilder has been constructed - // and that the model has not already been constructed - if (theBuilder != 0 && builtModel == false) { - builtModel = true; - return theBuilder->buildFE_Model(); - } else if (theBuilder != 0 && builtModel == true) { - opserr << "WARNING Model has already been built - not built again \n"; - return TCL_ERROR; - } - else { - opserr << "WARNING No ModelBuilder type has been specified \n"; - return TCL_ERROR; - } -} - - - - -#ifdef _PARALLEL_PROCESSING - -int -partitionModel(int eleTag) -{ - if (OPS_PARTITIONED == true) - return 0; - - int result = 0; - - if (OPS_theChannels != 0) - delete [] OPS_theChannels; - - OPS_theChannels = new Channel *[OPS_NUM_SUBDOMAINS]; - - // create some subdomains - for (int i=1; i<=OPS_NUM_SUBDOMAINS; i++) { - if (i != OPS_MAIN_DOMAIN_PARTITION_ID) { - ShadowSubdomain *theSubdomain = new ShadowSubdomain(i, *OPS_MACHINE, *OPS_OBJECT_BROKER); - theDomain.addSubdomain(theSubdomain); - OPS_theChannels[i-1] = theSubdomain->getChannelPtr(); - } - } - - // create a partitioner & partition the domain - if (OPS_DOMAIN_PARTITIONER == 0) { - // OPS_BALANCER = new ShedHeaviest(); - OPS_GRAPH_PARTITIONER = new Metis; - //OPS_DOMAIN_PARTITIONER = new DomainPartitioner(*OPS_GRAPH_PARTITIONER, *OPS_BALANCER); - OPS_DOMAIN_PARTITIONER = new DomainPartitioner(*OPS_GRAPH_PARTITIONER); - theDomain.setPartitioner(OPS_DOMAIN_PARTITIONER); - } - - // opserr << "commands.cpp - partition numPartitions: " << OPS_NUM_SUBDOMAINS << endln; - - result = theDomain.partition(OPS_NUM_SUBDOMAINS, OPS_USING_MAIN_DOMAIN, OPS_MAIN_DOMAIN_PARTITION_ID, eleTag); - - if (result < 0) - return result; - - OPS_PARTITIONED = true; - - DomainDecompositionAnalysis *theSubAnalysis; - SubdomainIter &theSubdomains = theDomain.getSubdomains(); - Subdomain *theSub =0; - - // create the appropriate domain decomposition analysis - while ((theSub = theSubdomains()) != 0) { - if (theStaticAnalysis != 0) { - theSubAnalysis = new StaticDomainDecompositionAnalysis(*theSub, - *theHandler, - *theNumberer, - *theAnalysisModel, - *theAlgorithm, - *theSOE, - *theStaticIntegrator, - theTest, - false); - - } else { - theSubAnalysis = new TransientDomainDecompositionAnalysis(*theSub, - *theHandler, - *theNumberer, - *theAnalysisModel, - *theAlgorithm, - *theSOE, - *theTransientIntegrator, - theTest, - false); - } - theSub->setDomainDecompAnalysis(*theSubAnalysis); - // delete theSubAnalysis; - } - - return result; -} - -#endif - - -int -opsPartition(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ -#ifdef _PARALLEL_PROCESSING - int eleTag; - if (argc == 2) { - if (Tcl_GetInt(interp, argv[1], &eleTag) != TCL_OK) { - ; - } - } - partitionModel(eleTag); -#endif - return TCL_OK; -} - -// -// command invoked to build the model, i.e. to invoke analyze() -// on the Analysis object -// -int -analyzeModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - int result = 0; - -#ifdef _PARALLEL_PROCESSING - if (OPS_PARTITIONED == false && OPS_NUM_SUBDOMAINS > 1) { - if (partitionModel(0) < 0) { - opserr << "WARNING before analysis; partition failed - too few elements\n"; - OpenSeesExit(clientData, interp, argc, argv); - return TCL_ERROR; - } - } -#endif - - if (theStaticAnalysis != 0) { - if (argc < 2) { - opserr << "WARNING static analysis: analysis numIncr?\n"; - return TCL_ERROR; - } - int numIncr; - - if (Tcl_GetInt(interp, argv[1], &numIncr) != TCL_OK) - return TCL_ERROR; - - result = theStaticAnalysis->analyze(numIncr); - - } else if(thePFEMAnalysis != 0) { - result = thePFEMAnalysis->analyze(); - - } else if (theTransientAnalysis != 0) { - if (argc < 3) { - opserr << "WARNING transient analysis: analysis numIncr? deltaT?\n"; - return TCL_ERROR; - } - int numIncr; - if (Tcl_GetInt(interp, argv[1], &numIncr) != TCL_OK) - return TCL_ERROR; - double dT; - if (Tcl_GetDouble(interp, argv[2], &dT) != TCL_OK) - return TCL_ERROR; - - // Set global timestep variable - ops_Dt = dT; - - if (argc == 6) { - int Jd; - double dtMin, dtMax; - if (Tcl_GetDouble(interp, argv[3], &dtMin) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[4], &dtMax) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[5], &Jd) != TCL_OK) - return TCL_ERROR; - - if (theVariableTimeStepTransientAnalysis != 0) - result = theVariableTimeStepTransientAnalysis->analyze(numIncr, dT, dtMin, dtMax, Jd); - else { - opserr << "WARNING analyze - no variable time step transient analysis object constructed\n"; - return TCL_ERROR; - } - - } else { - result = theTransientAnalysis->analyze(numIncr, dT); - } - - } else { - opserr << "WARNING No Analysis type has been specified \n"; - return TCL_ERROR; - } - - if (result < 0) { - opserr << "OpenSees > analyze failed, returned: " << result << " error flag\n"; - } - - char buffer [10]; - sprintf(buffer,"%d", result); - Tcl_SetResult(interp, buffer, TCL_VOLATILE); - - // sprintf(interp->result,"%d",result); - - return TCL_OK; - -} - -int -printElement(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv, OPS_Stream &output); - - -int -printNode(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv, OPS_Stream &output); - -int -printIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv, OPS_Stream &output); - -int -printAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv, OPS_Stream &output); - - -int -printModel(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - int currentArg = 1; - int res = 0; - - int flag = OPS_PRINT_CURRENTSTATE; - - FileStream outputFile; - OPS_Stream *output = &opserr; - bool done = false; - - // if just 'print' then print out the entire domain - if (argc == currentArg) { - opserr << theDomain; - return TCL_OK; - } - - while(done == false) { - // if 'print ele i j k..' print out some elements - if ((strcmp(argv[currentArg],"-ele") == 0) || (strcmp(argv[currentArg],"ele") == 0)) { - currentArg++; - res = printElement(clientData, interp, argc-currentArg, argv+currentArg, *output); - done = true; - } - // if 'print node i j k ..' print out some nodes - else if ((strcmp(argv[currentArg],"-node") == 0) || (strcmp(argv[currentArg],"node") == 0)) { - currentArg++; - res = printNode(clientData, interp, argc-currentArg, argv+currentArg, *output); - done = true; - } - - // if 'print integrator flag' print out the integrator - else if ((strcmp(argv[currentArg],"integrator") == 0) || - (strcmp(argv[currentArg],"-integrator") == 0)) { - currentArg++; - res = printIntegrator(clientData, interp, argc-currentArg, argv+currentArg, *output); - done = true; - } - - // if 'print algorithm flag' print out the algorithm - else if ((strcmp(argv[currentArg],"algorithm") == 0) || - (strcmp(argv[currentArg],"-algorithm") == 0)) { - currentArg++; - res = printAlgorithm(clientData, interp, argc-currentArg, argv+currentArg, *output); - done = true; - } - - else if ((strcmp(argv[currentArg],"-JSON") == 0)) { - currentArg++; - flag = OPS_PRINT_PRINTMODEL_JSON; - } - - else { - - if ((strcmp(argv[currentArg],"file") == 0) || - (strcmp(argv[currentArg],"-file") == 0)) - currentArg++; - - openMode mode = APPEND; - if (flag == OPS_PRINT_PRINTMODEL_JSON) - mode = OVERWRITE; - if (outputFile.setFile(argv[currentArg], mode) != 0) { - opserr << "print .. - failed to open file: " << argv[currentArg] << endln; - return TCL_ERROR; - } - currentArg++; - - // if just 'print ' then print out the entire domain to eof - if (argc == currentArg) { - if (flag == OPS_PRINT_PRINTMODEL_JSON) - simulationInfo.Print(outputFile, flag); - - theDomain.Print(outputFile, flag); - return TCL_OK; - } - - output = &outputFile; - - } - } - - // close the output file - outputFile.close(); - return res; -} - - - -// printNode(): -// function to print out the nodal information conatined in line -// print node -// input: nodeArg: integer equal to arg count to node plus 1 -// output: output stream to which the results are sent -// -int -printNode(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv, OPS_Stream &output) -{ - int flag = 0; // default flag sent to a nodes Print() method - int nodeArg = 0; - - // if just 'print node' print all the nodes - no flag - if (argc == 0) { - NodeIter &theNodes = theDomain.getNodes(); - Node *theNode; - while ((theNode = theNodes()) != 0) - theNode->Print(output); - return TCL_OK; - } - - // if 'print node flag int ' get the flag - if ((strcmp(argv[0],"flag") == 0) || - (strcmp(argv[0],"-flag") == 0)) { - // get the specified flag - if (argc <= nodeArg) { - opserr << "WARNING print node no int specified \n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[1], &flag) != TCL_OK) { - opserr << "WARNING print node failed to get integer flag: \n"; - opserr << argv[nodeArg] << endln; - return TCL_ERROR; - } - nodeArg += 2; - } - - // now print the nodes with the specified flag, 0 by default - - // if 'print node flag' - // print out all the nodes in the domain with flag - if (nodeArg == argc) { - NodeIter &theNodes = theDomain.getNodes(); - Node *theNode; - while ((theNode = theNodes()) != 0) - theNode->Print(output, flag); - return TCL_OK; - } else { - // otherwise print out the specified nodes i j k .. with flag - int numNodes = argc-nodeArg; - ID *theNodes = new ID(numNodes); - for (int i= 0; i node' print all the nodes - no flag - if (argc == 0) { - ElementIter &theElements = theDomain.getElements(); - Element *theElement; - while ((theElement = theElements()) != 0) - theElement->Print(output); - return TCL_OK; - } - - // if 'print Element flag int ' get the flag - if ((strcmp(argv[0],"flag") == 0) || - (strcmp(argv[0],"-flag")) == 0) { // get the specified flag - if (argc < 2) { - opserr << "WARNING print ele no int specified \n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[1], &flag) != TCL_OK) { - opserr << "WARNING print ele failed to get integer flag: \n"; - opserr << argv[eleArg] << endln; - return TCL_ERROR; - } - eleArg += 2; - } - - // now print the Elements with the specified flag, 0 by default - if (argc == eleArg) { - ElementIter &theElements = theDomain.getElements(); - Element *theElement; - while ((theElement = theElements()) != 0) - theElement->Print(output, flag); - return TCL_OK; - } else { - - // otherwise print out the specified nodes i j k .. with flag - int numEle = argc-eleArg; - ID *theEle = new ID(numEle); - for (int i= 0; i algorithm'- no flag - if (argc == 0) { - theAlgorithm->Print(output); - return TCL_OK; - } - - // if 'print Algorithm flag' get the flag - int flag; - if (Tcl_GetInt(interp, argv[eleArg], &flag) != TCL_OK) { - opserr << "WARNING print algorithm failed to get integer flag: \n"; - opserr << argv[eleArg] << endln; - return TCL_ERROR; - } - theAlgorithm->Print(output,flag); - return TCL_OK; -} - - -int -printIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv, OPS_Stream &output) -{ - int eleArg = 0; - if (theStaticIntegrator == 0 && theTransientIntegrator == 0) - return TCL_OK; - - IncrementalIntegrator *theIntegrator; - if (theStaticIntegrator != 0) - theIntegrator = theStaticIntegrator; - else - theIntegrator = theTransientIntegrator; - - // if just 'print algorithm'- no flag - if (argc == 0) { - theIntegrator->Print(output); - return TCL_OK; - } - - // if 'print Algorithm flag' get the flag - int flag; - if (Tcl_GetInt(interp, argv[eleArg], &flag) != TCL_OK) { - opserr << "WARNING print algorithm failed to get integer flag: \n"; - opserr << argv[eleArg] << endln; - return TCL_ERROR; - } - theIntegrator->Print(output,flag); - return TCL_OK; -} - - -int -printA(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - int res = 0; - - FileStream outputFile; - OPS_Stream *output = &opserr; - - int currentArg = 1; - - if (argc > 2) { - if ((strcmp(argv[currentArg],"file") == 0) || - (strcmp(argv[currentArg],"-file") == 0)) { - currentArg++; - - if (outputFile.setFile(argv[currentArg]) != 0) { - opserr << "print .. - failed to open file: " << argv[currentArg] << endln; - return TCL_ERROR; - } - output = &outputFile; - } - } - if (theSOE != 0) { - if (theStaticIntegrator != 0) - theStaticIntegrator->formTangent(); - else if (theTransientIntegrator != 0) - theTransientIntegrator->formTangent(0); - - const Matrix *A = theSOE->getA(); - if (A != 0) { - *output << *A; - } - } - - // close the output file - outputFile.close(); - - return res; -} - -int -printB(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - int res = 0; - - FileStream outputFile; - OPS_Stream *output = &opserr; - // bool done = false; - - int currentArg = 1; - - if (argc > 2) { - if ((strcmp(argv[currentArg],"file") == 0) || - (strcmp(argv[currentArg],"-file") == 0)) { - currentArg++; - - if (outputFile.setFile(argv[currentArg]) != 0) { - opserr << "print .. - failed to open file: " << argv[currentArg] << endln; - return TCL_ERROR; - } - output = &outputFile; - } - } - if (theSOE != 0) { - if (theStaticIntegrator != 0) - theStaticIntegrator->formUnbalance(); - else if (theTransientIntegrator != 0) - theTransientIntegrator->formUnbalance(); - - const Vector &b = theSOE->getB(); - *output << b; - } - - // close the output file - outputFile.close(); - - return res; -} - -// -// command invoked to allow the Analysis object to be built -// -int -specifyAnalysis(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv) -{ - // make sure at least one other argument to contain type of system - if (argc < 2) { - opserr << "WARNING need to specify an analysis type (Static, Transient)\n"; - return TCL_ERROR; - } - - // - // do nothing if request is for the same analysis type! - // - - if ((strcmp(argv[1],"Static") == 0) && (theStaticAnalysis != 0)) - return TCL_OK; - - if (((strcmp(argv[1],"VariableTimeStepTransient") == 0) || - (strcmp(argv[1],"TransientWithVariableTimeStep") == 0) || - (strcmp(argv[1],"VariableTransient") == 0)) && - (theVariableTimeStepTransientAnalysis != 0)) - return TCL_OK; - - if ((strcmp(argv[1],"Transient") == 0) && (theTransientAnalysis != 0)) - return TCL_OK; - - // - // analysis changing .. delete the old analysis - // - - if (theStaticAnalysis != 0) { - delete theStaticAnalysis; - theStaticAnalysis = 0; - opserr << "WARNING: analysis .. StaticAnalysis already exists => wipeAnalysis not invoked, problems may arise\n"; - } - - if (theTransientAnalysis != 0) { - delete theTransientAnalysis; - theTransientAnalysis = 0; - theVariableTimeStepTransientAnalysis = 0; - opserr << "WARNING: analysis .. TransientAnalysis already exists => wipeAnalysis not invoked, problems may arise\n"; - } - - // check argv[1] for type of SOE and create it - if (strcmp(argv[1],"Static") == 0) { - // make sure all the components have been built, - // otherwise print a warning and use some defaults - if (theAnalysisModel == 0) - theAnalysisModel = new AnalysisModel(); - - if (theTest == 0) - theTest = new CTestNormUnbalance(1.0e-6,25,0); - - if (theAlgorithm == 0) { - opserr << "WARNING analysis Static - no Algorithm yet specified, \n"; - opserr << " NewtonRaphson default will be used\n"; - - theAlgorithm = new NewtonRaphson(*theTest); - } - if (theHandler == 0) { - opserr << "WARNING analysis Static - no ConstraintHandler yet specified, \n"; - opserr << " PlainHandler default will be used\n"; - theHandler = new PlainHandler(); - } - if (theNumberer == 0) { - opserr << "WARNING analysis Static - no Numberer specified, \n"; - opserr << " RCM default will be used\n"; - RCM *theRCM = new RCM(false); - theNumberer = new DOF_Numberer(*theRCM); - } - if (theStaticIntegrator == 0) { - opserr << "WARNING analysis Static - no Integrator specified, \n"; - opserr << " StaticIntegrator default will be used\n"; - theStaticIntegrator = new LoadControl(1, 1, 1, 1); - } - if (theSOE == 0) { - opserr << "WARNING analysis Static - no LinearSOE specified, \n"; - opserr << " ProfileSPDLinSOE default will be used\n"; - ProfileSPDLinSolver *theSolver; - theSolver = new ProfileSPDLinDirectSolver(); -#ifdef _PARALLEL_PROCESSING - theSOE = new DistributedProfileSPDLinSOE(*theSolver); -#else - theSOE = new ProfileSPDLinSOE(*theSolver); -#endif - } - - theStaticAnalysis = new StaticAnalysis(theDomain, - *theHandler, - *theNumberer, - *theAnalysisModel, - *theAlgorithm, - *theSOE, - *theStaticIntegrator, - theTest); - - #ifdef _PARALLEL_INTERPRETERS - if (setMPIDSOEFlag) { - ((MPIDiagonalSOE*) theSOE)->setAnalysisModel(*theAnalysisModel); - } -#endif - -// AddingSensitivity:BEGIN /////////////////////////////// -#ifdef _RELIABILITY - if (theSensitivityAlgorithm != 0 && theSensitivityAlgorithm->shouldComputeAtEachStep()) { - //theStaticAnalysis->setSensitivityAlgorithm(theSensitivityAlgorithm); - } -#endif -// AddingSensitivity:END ///////////////////////////////// - } else if(strcmp(argv[1], "PFEM") == 0) { - - if(argc < 5) { - opserr<<"WARNING: wrong no of args -- analysis PFEM dtmax dtmin gravity \n"; - return TCL_ERROR; - } - double dtmax, dtmin, gravity, ratio=0.5; - if(Tcl_GetDouble(interp, argv[2], &dtmax) != TCL_OK) { - opserr<<"WARNING: invalid dtmax "< 5) { - if(Tcl_GetDouble(interp, argv[5], &ratio) != TCL_OK) { - opserr<<"WARNING: invalid ratio "<setAnalysisModel(*theAnalysisModel); - } -#endif - -// AddingSensitivity:BEGIN /////////////////////////////// -#ifdef _RELIABILITY - if (theSensitivityAlgorithm != 0 && theSensitivityAlgorithm->shouldComputeAtEachStep()) { - - /* This if-statement cannot possibly stay in the code -- MHS - if(theSensitivityAlgorithm->newAlgorithm()){ - opserr << "WARNING original sensitivity algorothm needs to be specified \n"; - opserr << "for static analysis \n"; - return TCL_ERROR; - } - */ - - //theTransientAnalysis->setSensitivityAlgorithm(theSensitivityAlgorithm); - } -#endif -// AddingSensitivity:END ///////////////////////////////// - - } else if ((strcmp(argv[1],"VariableTimeStepTransient") == 0) || - (strcmp(argv[1],"TransientWithVariableTimeStep") == 0) || - (strcmp(argv[1],"VariableTransient") == 0)) { - // make sure all the components have been built, - // otherwise print a warning and use some defaults - if (theAnalysisModel == 0) - theAnalysisModel = new AnalysisModel(); - - if (theTest == 0) - theTest = new CTestNormUnbalance(1.0e-6,25,0); - - if (theAlgorithm == 0) { - opserr << "WARNING analysis Transient - no Algorithm yet specified, \n"; - opserr << " NewtonRaphson default will be used\n"; - theAlgorithm = new NewtonRaphson(*theTest); - } - - if (theHandler == 0) { - opserr << "WARNING analysis Transient dt tFinal - no ConstraintHandler\n"; - opserr << " yet specified, PlainHandler default will be used\n"; - theHandler = new PlainHandler(); - } - - if (theNumberer == 0) { - opserr << "WARNING analysis Transient dt tFinal - no Numberer specified, \n"; - opserr << " RCM default will be used\n"; - RCM *theRCM = new RCM(false); - theNumberer = new DOF_Numberer(*theRCM); - } - - if (theTransientIntegrator == 0) { - opserr << "WARNING analysis Transient dt tFinal - no Integrator specified, \n"; - opserr << " Newmark(.5,.25) default will be used\n"; - theTransientIntegrator = new Newmark(0.5,0.25); - } - - if (theSOE == 0) { - opserr << "WARNING analysis Transient dt tFinal - no LinearSOE specified, \n"; - opserr << " ProfileSPDLinSOE default will be used\n"; - ProfileSPDLinSolver *theSolver; - theSolver = new ProfileSPDLinDirectSolver(); -#ifdef _PARALLEL_PROCESSING - theSOE = new DistributedProfileSPDLinSOE(*theSolver); -#else - theSOE = new ProfileSPDLinSOE(*theSolver); -#endif - } - - theVariableTimeStepTransientAnalysis = new VariableTimeStepDirectIntegrationAnalysis - (theDomain, - *theHandler, - *theNumberer, - *theAnalysisModel, - *theAlgorithm, - *theSOE, - *theTransientIntegrator, - theTest); - - // set the pointer for variabble time step analysis - theTransientAnalysis = theVariableTimeStepTransientAnalysis; - - #ifdef _RELIABILITY - - ////////////////////////////////// - ////// added by K Fujimura /////// - - //FMK RELIABILITY - /* - } else if (strcmp(argv[1],"ReliabilityStatic") == 0) { - // make sure all the components have been built, - // otherwise print a warning and use some defaults - if (theAnalysisModel == 0) - theAnalysisModel = new AnalysisModel(); - if (theTest == 0) - theTest = new CTestNormUnbalance(1.0e-6,25,0); - if (theAlgorithm == 0) { - opserr << "WARNING analysis Static - no Algorithm yet specified, \n"; - opserr << " NewtonRaphson default will be used\n"; - theAlgorithm = new NewtonRaphson(*theTest); } - if (theHandler == 0) { - opserr << "WARNING analysis Static - no ConstraintHandler yet specified, \n"; - opserr << " PlainHandler default will be used\n"; - theHandler = new PlainHandler(); } - if (theNumberer == 0) { - opserr << "WARNING analysis Static - no Numberer specified, \n"; - opserr << " RCM default will be used\n"; - RCM *theRCM = new RCM(false); - theNumberer = new DOF_Numberer(*theRCM); } - if (theStaticIntegrator == 0) { - opserr << "Fatal ! theStaticIntegrator must be defined before defining\n"; - opserr << "ReliabilityStaticAnalysis by NewStaticSensitivity\n"; - return TCL_ERROR; - } - if (theSOE == 0) { - opserr << "WARNING analysis Static - no LinearSOE specified, \n"; - opserr << " ProfileSPDLinSOE default will be used\n"; - ProfileSPDLinSolver *theSolver; - theSolver = new ProfileSPDLinDirectSolver(); - theSOE = new ProfileSPDLinSOE(*theSolver); } - - theReliabilityStaticAnalysis = new ReliabilityStaticAnalysis(theDomain, - *theHandler, - *theNumberer, - *theAnalysisModel, - *theAlgorithm, - *theSOE, - *theStaticIntegrator, - theTest); - - if (theSensitivityAlgorithm != 0 && theSensitivityAlgorithm->shouldComputeAtEachStep()) { - - //This if-statement cannot stay -- MHS - //if(!theSensitivityAlgorithm->newAlgorithm()){ - // opserr << "WARNING new sensitivity algorothm needs to be specified \n"; - // opserr << "for reliability static analysis \n"; - // return TCL_ERROR; - //} - - - //theStaticAnalysis->setSensitivityAlgorithm(theSensitivityAlgorithm); - } else { - opserr << "Faltal SensitivityAlgorithm must be definde before defining \n"; - opserr << "ReliabilityStaticAnalysis with computeateachstep\n"; - return TCL_ERROR; - } - - } else if (strcmp(argv[1],"ReliabilityTransient") == 0) { - // make sure all the components have been built, - // otherwise print a warning and use some defaults - if (theAnalysisModel == 0) - theAnalysisModel = new AnalysisModel(); - if (theTest == 0) - theTest = new CTestNormUnbalance(1.0e-6,25,0); - if (theAlgorithm == 0) { - opserr << "WARNING analysis Transient - no Algorithm yet specified, \n"; - opserr << " NewtonRaphson default will be used\n"; - theAlgorithm = new NewtonRaphson(*theTest); - } - if (theHandler == 0) { - opserr << "WARNING analysis Transient dt tFinal - no ConstraintHandler\n"; - opserr << " yet specified, PlainHandler default will be used\n"; - theHandler = new PlainHandler(); - } - if (theNumberer == 0) { - opserr << "WARNING analysis Transient dt tFinal - no Numberer specified, \n"; - opserr << " RCM default will be used\n"; - RCM *theRCM = new RCM(false); - theNumberer = new DOF_Numberer(*theRCM); - } - if (theTransientIntegrator == 0) { - opserr << "Fatal ! theTransientIntegrator must be defined before defining\n"; - opserr << "ReliabilityTransientAnalysis by NewNewmarkWithSensitivity\n"; - return TCL_ERROR; - } - if (theSOE == 0) { - opserr << "WARNING analysis Transient dt tFinal - no LinearSOE specified, \n"; - opserr << " ProfileSPDLinSOE default will be used\n"; - ProfileSPDLinSolver *theSolver; - theSolver = new ProfileSPDLinDirectSolver(); - theSOE = new ProfileSPDLinSOE(*theSolver); - } - - theReliabilityTransientAnalysis = new ReliabilityDirectIntegrationAnalysis(theDomain, - *theHandler, - *theNumberer, - *theAnalysisModel, - *theAlgorithm, - *theSOE, - *theTransientIntegrator, - theTest); - - if (theSensitivityAlgorithm != 0 && theSensitivityAlgorithm->shouldComputeAtEachStep()) { - - //This if-statement must go -- MHS - //if(!theSensitivityAlgorithm->newAlgorithm()){ - // opserr << "WARNING new sensitivity algorothm needs to be specified \n"; - // opserr << "for reliability static analysis \n"; - // return TCL_ERROR; - //} - - - theReliabilityTransientAnalysis->setSensitivityAlgorithm(theSensitivityAlgorithm); - }else{ - opserr << "Faltal SensitivityAlgorithm must be definde before defining \n"; - opserr << "ReliabilityStaticAnalysis with computeateachstep\n"; - return TCL_ERROR; - } - FMK RELIABILITY - *************************/ -// AddingSensitivity:END ///////////////////////////////// -#endif - - } else { - opserr << "WARNING No Analysis type exists (Static Transient only) \n"; - return TCL_ERROR; - } - - -#ifdef _PARALLEL_PROCESSING - if (OPS_PARTITIONED == true && OPS_NUM_SUBDOMAINS > 1) { - DomainDecompositionAnalysis *theSubAnalysis; - SubdomainIter &theSubdomains = theDomain.getSubdomains(); - Subdomain *theSub =0; - // create the appropriate domain decomposition analysis - while ((theSub = theSubdomains()) != 0) { - if (theStaticAnalysis != 0) { - theSubAnalysis = new StaticDomainDecompositionAnalysis(*theSub, - *theHandler, - *theNumberer, - *theAnalysisModel, - *theAlgorithm, - *theSOE, - *theStaticIntegrator, - theTest, - false); - - } else { - theSubAnalysis = new TransientDomainDecompositionAnalysis(*theSub, - *theHandler, - *theNumberer, - *theAnalysisModel, - *theAlgorithm, - *theSOE, - *theTransientIntegrator, - theTest, - false); - } - - theSub->setDomainDecompAnalysis(*theSubAnalysis); - // delete theSubAnalysis; - } - } -#endif - - if (theEigenSOE != 0) { - if (theStaticAnalysis != 0) { - theStaticAnalysis->setEigenSOE(*theEigenSOE); - } else if (theTransientAnalysis != 0) { - theTransientAnalysis->setEigenSOE(*theEigenSOE); - } - } - - - return TCL_OK; -} - - -typedef struct externalClassFunction { - char *funcName; - void *(*funcPtr)(); - struct externalClassFunction *next; -} ExternalClassFunction; - -static ExternalClassFunction *theExternalSolverCommands = NULL; -static ExternalClassFunction *theExternalStaticIntegratorCommands = NULL; -static ExternalClassFunction *theExternalTransientIntegratorCommands = NULL; -static ExternalClassFunction *theExternalAlgorithmCommands = NULL; - -int -specifySOE(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - // make sure at least one other argument to contain type of system - if (argc < 2) { - opserr << "WARNING need to specify a model type \n"; - return TCL_ERROR; - } - - // check argv[1] for type of SOE and create it - // BAND GENERAL SOE & SOLVER - if ((strcmp(argv[1],"BandGeneral") == 0) || (strcmp(argv[1],"BandGEN") == 0) - || (strcmp(argv[1],"BandGen") == 0)){ - BandGenLinSolver *theSolver = new BandGenLinLapackSolver(); -#ifdef _PARALLEL_PROCESSING - theSOE = new DistributedBandGenLinSOE(*theSolver); -#else - theSOE = new BandGenLinSOE(*theSolver); -#endif - } - -#ifdef _CUDA - else if ((strcmp(argv[1],"BandGeneral_Single") == 0) || (strcmp(argv[1],"BandGEN_Single") == 0) - || (strcmp(argv[1],"BandGen_Single") == 0)){ - BandGenLinLapackSolver_Single *theSolver = new BandGenLinLapackSolver_Single(); - theSOE = new BandGenLinSOE_Single(*theSolver); - } -#endif - - // BAND SPD SOE & SOLVER - else if (strcmp(argv[1],"BandSPD") == 0) { - BandSPDLinSolver *theSolver = new BandSPDLinLapackSolver(); -#ifdef _PARALLEL_PROCESSING - theSOE = new DistributedBandSPDLinSOE(*theSolver); -#else - theSOE = new BandSPDLinSOE(*theSolver); -#endif - - } - - // Diagonal SOE & SOLVER - else if (strcmp(argv[1],"Diagonal") == 0) { -#ifdef _PARALLEL_PROCESSING - DistributedDiagonalSolver *theSolver = new DistributedDiagonalSolver(); - theSOE = new DistributedDiagonalSOE(*theSolver); -#else - DiagonalSolver *theSolver = new DiagonalDirectSolver(); - theSOE = new DiagonalSOE(*theSolver); -#endif - - - } - // Diagonal SOE & SOLVER - else if (strcmp(argv[1],"MPIDiagonal") == 0) { -#ifdef _PARALLEL_INTERPRETERS - MPIDiagonalSolver *theSolver = new MPIDiagonalSolver(); - theSOE = new MPIDiagonalSOE(*theSolver); - setMPIDSOEFlag = true; -#else - DiagonalSolver *theSolver = new DiagonalDirectSolver(); - theSOE = new DiagonalSOE(*theSolver); -#endif - } - - - // PROFILE SPD SOE * SOLVER - else if (strcmp(argv[1],"SProfileSPD") == 0) { - // now must determine the type of solver to create from rest of args - SProfileSPDLinSolver *theSolver = new SProfileSPDLinSolver(); - theSOE = new SProfileSPDLinSOE(*theSolver); - } - - else if (strcmp(argv[1],"ProfileSPD") == 0) { - // now must determine the type of solver to create from rest of args - ProfileSPDLinSolver *theSolver = new ProfileSPDLinDirectSolver(); - - /* *********** Some misc solvers i play with ****************** - else if (strcmp(argv[2],"Normal") == 0) { - theSolver = new ProfileSPDLinDirectSolver(); - } - - else if (strcmp(argv[2],"Block") == 0) { - int blockSize = 4; - if (argc == 4) { - if (Tcl_GetInt(interp, argv[3], &blockSize) != TCL_OK) - return TCL_ERROR; - } - theSolver = theSolver = new ProfileSPDLinDirectBlockSolver(1.0e-12,blockSize); - } - - - int blockSize = 4; - int numThreads = 1; - if (argc == 5) { - if (Tcl_GetInt(interp, argv[3], &blockSize) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &numThreads) != TCL_OK) - return TCL_ERROR; - } - theSolver = new ProfileSPDLinDirectThreadSolver(numThreads,blockSize,1.0e-12); - } else if (strcmp(argv[2],"Thread") == 0) { - int blockSize = 4; - int numThreads = 1; - if (argc == 5) { - if (Tcl_GetInt(interp, argv[3], &blockSize) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &numThreads) != TCL_OK) - return TCL_ERROR; - } - theSolver = new ProfileSPDLinDirectThreadSolver(numThreads,blockSize,1.0e-12); - } - else if (strcmp(argv[2],"Skypack") == 0) { - if (argc == 5) { - int mCols, mRows; - if (Tcl_GetInt(interp, argv[3], &mCols) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &mRows) != TCL_OK) - return TCL_ERROR; - theSolver = new ProfileSPDLinDirectSkypackSolver(mCols, mRows); - } else - theSolver = new ProfileSPDLinDirectSkypackSolver(); - } - else - theSolver = new ProfileSPDLinDirectSolver(); - *************************************************************** */ - -#ifdef _PARALLEL_PROCESSING - theSOE = new DistributedProfileSPDLinSOE(*theSolver); -#else - theSOE = new ProfileSPDLinSOE(*theSolver); -#endif - } - -#ifdef _PARALLEL_INTERPRETERS - else if (strcmp(argv[1],"ParallelProfileSPD") == 0) { - ProfileSPDLinSolver *theSolver = new ProfileSPDLinDirectSolver(); - DistributedProfileSPDLinSOE *theParallelSOE = new DistributedProfileSPDLinSOE(*theSolver); - theSOE = theParallelSOE; - theParallelSOE->setProcessID(OPS_rank); - theParallelSOE->setChannels(numChannels, theChannels); - } -#endif - - else if(strcmp(argv[1], "PFEM") == 0) { - if(argc <= 2) { - PFEMSolver* theSolver = new PFEMSolver(); - theSOE = new PFEMLinSOE(*theSolver); - } else if(strcmp(argv[2], "-quasi") == 0) { - PFEMCompressibleSolver* theSolver = new PFEMCompressibleSolver(); - theSOE = new PFEMCompressibleLinSOE(*theSolver); - } else if (strcmp(argv[2],"-mumps") ==0) { -#ifdef _PARALLEL_INTERPRETERS - int relax = 20; - if (argc > 3) { - if (Tcl_GetInt(interp, argv[3], &relax) != TCL_OK) { - opserr<<"WARNING: failed to read relax\n"; - return TCL_ERROR; - } - } - PFEMSolver_Mumps* theSolver = new PFEMSolver_Mumps(relax,0,0,0); - theSOE = new PFEMLinSOE(*theSolver); -#endif - } else if (strcmp(argv[2],"-quasi-mumps")==0) { -#ifdef _PARALLEL_INTERPRETERS - int relax = 20; - if (argc > 3) { - if (Tcl_GetInt(interp, argv[3], &relax) != TCL_OK) { - opserr<<"WARNING: failed to read relax\n"; - return TCL_ERROR; - } - } - PFEMCompressibleSolver_Mumps* theSolver = new PFEMCompressibleSolver_Mumps(relax,0,0); - theSOE = new PFEMCompressibleLinSOE(*theSolver); -#endif - } - } - -#ifdef _CUSP - else if ((_stricmp(argv[1],"CuSP")==0)) { - - - double relTol=1e-6; - int maxInteration=100000; - int preCond=1; //diagonal - int solver=0; //Bicg - int count = 2; - - - while (count < argc) { - - if (_stricmp(argv[count],"-rTol") == 0) { - count++; - if (count < argc) - if (Tcl_GetDouble(interp, argv[count], &relTol) != TCL_OK) - return TCL_ERROR; - } - else if ((_stricmp(argv[count],"-mInt") == 0) ) { - count++; - if (count < argc) - if (Tcl_GetInt(interp, argv[count], &maxInteration) != TCL_OK) - return TCL_ERROR; - } - else if ((_stricmp(argv[count],"-pre") == 0) ) { - count++; - if (count < argc) - if ((_stricmp(argv[count],"none") == 0)) - preCond=0; - else if ((_stricmp(argv[count],"diagonal") == 0)) - preCond=1; - else if ((_stricmp(argv[count],"ainv") == 0)) - preCond=2; - else - return TCL_ERROR; - } else if ((_stricmp(argv[count],"-solver") == 0)) { - count++; - if (count < argc) - if ((_stricmp(argv[count],"bicg") == 0)) - solver=0; - else if ((_stricmp(argv[count],"bicgstab") == 0)) - solver=1; - else if ((_stricmp(argv[count],"cg") == 0)) - solver=2; - else if ((_stricmp(argv[count],"gmres") == 0)) - solver=3; - else - return TCL_ERROR; - } - count++; - } - - CuSPSolver* theSolver = new CuSPSolver(maxInteration,relTol,preCond,solver); - theSOE = new SparseGenRowLinSOE(* theSolver); - - } -#endif - -#if defined(_CULAS4) || defined(_CULAS5) - // CULA SPARSE - else if ((strcmp(argv[1],"CulaSparse")==0)) - { - double absTol = 1.0e-6; - double relTol=1e-6; - - int maxInteration=100000; - - int preCond=5; //fainv -#ifdef _CULAS4 - preCond = 1; -#endif - int solver=0; //cg - int count = 2; - int single=0; - int host=0; - - while (count < argc) { - - if (strcmp(argv[count],"-rTol") == 0) { - count++; - if (count < argc) - if (Tcl_GetDouble(interp, argv[count], &relTol) != TCL_OK) - return TCL_ERROR; - } - else if ((strcmp(argv[count],"-mInt") == 0) ) { - count++; - if (count < argc) - if (Tcl_GetInt(interp, argv[count], &maxInteration) != TCL_OK) - return TCL_ERROR; - } - else if ((strcmp(argv[count],"-pre") == 0) ) { - count++; - if (count < argc) - if ((strcmp(argv[count],"none") == 0)) - preCond=0; - else if ((strcmp(argv[count],"jacobi") == 0)) - preCond=1; - else if ((strcmp(argv[count],"blockjacobi") == 0)) - preCond=2; - else if ((strcmp(argv[count],"ilu0") == 0)) - preCond=3; - else if ((strcmp(argv[count],"ainv") == 0)) - preCond=4; - else if ((strcmp(argv[count],"fainv") == 0)) - preCond=5; - else - return TCL_ERROR; - } else if ((strcmp(argv[count],"-solver") == 0)) { - count++; - if (count < argc) - if ((strcmp(argv[count],"cg") == 0)) - solver=0; - else if ((strcmp(argv[count],"bicg") == 0)) - solver=1; - else if ((strcmp(argv[count],"blockstab") == 0)) - solver=2; - else if ((strcmp(argv[count],"blockstabl") == 0)) - solver=3; - else if ((strcmp(argv[count],"gmres") == 0)) - solver=4; - else if ((strcmp(argv[count],"minres") == 0)) - solver=5; - else - return TCL_ERROR; - } - else if ((strcmp(argv[count],"-single") == 0)) { - single=1; - } - else if ((strcmp(argv[count],"-host") == 0)) { - host=1; - } - count++; - } - -#ifdef _CULAS5 - CulaSparseSolverS5* theSolver = new CulaSparseSolverS5(relTol, - maxInteration, - preCond, - solver, - single, - host); -#else - CulaSparseSolverS4* theSolver = new CulaSparseSolverS4(relTol, - maxInteration, - preCond, - solver); -#endif - - theSOE = new SparseGenRowLinSOE(*theSolver); - - } -#endif - - // SPARSE GENERAL SOE * SOLVER - else if ((strcmp(argv[1],"SparseGeneral") == 0) || (strcmp(argv[1],"SuperLU") == 0) || - (strcmp(argv[1],"SparseGEN") == 0)) { - - SparseGenColLinSolver *theSolver =0; - int count = 2; - double thresh = 0.0; - int npRow = 1; - int npCol = 1; - int np = 1; - - // defaults for threaded SuperLU - - while (count < argc) { - - if ((strcmp(argv[count],"p") == 0) || (strcmp(argv[count],"piv") == 0)|| - (strcmp(argv[count],"-piv") == 0)) { - thresh = 1.0; - } - else if ((strcmp(argv[count],"-np") == 0) || (strcmp(argv[count],"np") == 0)) { - count++; - if (count < argc) - if (Tcl_GetInt(interp, argv[count], &np) != TCL_OK) - return TCL_ERROR; - } - else if ((strcmp(argv[count],"npRow") == 0) || (strcmp(argv[count],"-npRow") ==0)) { - count++; - if (count < argc) - if (Tcl_GetInt(interp, argv[count], &npRow) != TCL_OK) - return TCL_ERROR; - } else if ((strcmp(argv[count],"npCol") == 0) || (strcmp(argv[count],"-npCol") ==0)) { - count++; - if (count < argc) - if (Tcl_GetInt(interp, argv[count], &npCol) != TCL_OK) - return TCL_ERROR; - } - count++; - } - - int permSpec = 0; - int panelSize = 6; - int relax = 6; - - -#ifdef _THREADS - if (np != 0) - theSolver = new ThreadedSuperLU(np, permSpec, panelSize, relax, thresh); -#endif - -#ifdef _PARALLEL_PROCESSING - if (theSolver != 0) - delete theSolver; - theSolver = 0; - - if (npRow != 0 && npCol != 0) { - theSolver = new DistributedSuperLU(npRow, npCol); - opserr << "commands.cpp: DistributedSuperLU\n"; - } -#else - - char symmetric = 'N'; - double drop_tol = 0.0; - - while (count < argc) { - if (strcmp(argv[count],"s") == 0 || strcmp(argv[count],"symmetric") || - strcmp(argv[count],"-symm")) { - symmetric = 'Y'; - } - count++; - } - - theSolver = new SuperLU(permSpec, drop_tol, panelSize, relax, symmetric); - -#endif - -#ifdef _PARALLEL_PROCESSING - opserr << "commands.cpp: DistributedSparseGenColLinSOE\n"; - - theSOE = new DistributedSparseGenColLinSOE(*theSolver); -#else - theSOE = new SparseGenColLinSOE(*theSolver); -#endif - } - - - else if ((strcmp(argv[1],"SparseSPD") == 0) || (strcmp(argv[1],"SparseSYM") == 0)) { - // now must determine the type of solver to create from rest of args - - // now determine ordering scheme - // 1 -- MMD - // 2 -- ND - // 3 -- RCM - int lSparse = 1; - if (argc == 3) { - if (Tcl_GetInt(interp, argv[2], &lSparse) != TCL_OK) - return TCL_ERROR; - } - - SymSparseLinSolver *theSolver = new SymSparseLinSolver(); - theSOE = new SymSparseLinSOE(*theSolver, lSparse); - } - - 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 - int factLVALUE = 10; - int factorOnce=0; - int printTime = 0; - int count = 2; - - while (count < argc) { - if ((strcmp(argv[count],"-lValueFact") == 0) || (strcmp(argv[count],"-lvalueFact") == 0) || (strcmp(argv[count],"-LVALUE") == 0)) { - if (Tcl_GetInt(interp, argv[count+1], &factLVALUE) != TCL_OK) - return TCL_ERROR; - count++; - } else if ((strcmp(argv[count],"-factorOnce") == 0) || (strcmp(argv[count],"-FactorOnce") ==0 )) { - factorOnce = 1; - } else if ((strcmp(argv[count],"-printTime") == 0) || (strcmp(argv[count],"-time") ==0 )) { - printTime = 1; - } - count++; - } - - UmfpackGenLinSolver *theSolver = new UmfpackGenLinSolver(); - // theSOE = new UmfpackGenLinSOE(*theSolver, factLVALUE, factorOnce, printTime); - theSOE = new UmfpackGenLinSOE(*theSolver); - } - -#ifdef _ITPACK -// else if (strcmp(argv[1],"Itpack") == 0) { -// -// // now must determine the type of solver to create from rest of args -// int method = 1; -// if (argc == 3) { -// if (Tcl_GetInt(interp, argv[2], &method) != TCL_OK) -// return TCL_ERROR; -// } -// ItpackLinSolver *theSolver = new ItpackLinSolver(method); -// theSOE = new ItpackLinSOE(*theSolver); -// } -#endif - else if (strcmp(argv[1],"FullGeneral") == 0) { - // now must determine the type of solver to create from rest of args - FullGenLinLapackSolver *theSolver = new FullGenLinLapackSolver(); - theSOE = new FullGenLinSOE(*theSolver); - } - -#ifdef _PETSC - - else if (strcmp(argv[1],"Petsc") == 0) { - // now must determine the type of solver to create from rest of args - KSPType method = KSPCG; // KSPCG KSPGMRES - PCType preconditioner = PCJACOBI; // PCJACOBI PCILU PCBJACOBI - int matType = 0; - - double rTol = 1.0e-5; - double aTol = 1.0e-50; - double dTol = 1.0e5; - int maxIts = 100000; - int count = 2; - while (count < argc-1) { - if (strcmp(argv[count],"-matrixType") == 0 || strcmp(argv[count],"-matrix")){ - if (strcmp(argv[count+1],"sparse") == 0) - matType = 1; - } - else if (strcmp(argv[count],"-rTol") == 0 || strcmp(argv[count],"-relTol") || - strcmp(argv[count],"-relativeTolerance")) { - if (Tcl_GetDouble(interp, argv[count+1], &rTol) != TCL_OK) - return TCL_ERROR; - } else if (strcmp(argv[count],"-aTol") == 0 || strcmp(argv[count],"-absTol") || - strcmp(argv[count],"-absoluteTolerance")) { - if (Tcl_GetDouble(interp, argv[count+1], &aTol) != TCL_OK) - return TCL_ERROR; - } else if (strcmp(argv[count],"-dTol") == 0 || strcmp(argv[count],"-divTol") || - strcmp(argv[count],"-divergenceTolerance")) { - if (Tcl_GetDouble(interp, argv[count+1], &dTol) != TCL_OK) - return TCL_ERROR; - } else if (strcmp(argv[count],"-mIts") == 0 || strcmp(argv[count],"-maxIts") || - strcmp(argv[count],"-maxIterations")) { - if (Tcl_GetInt(interp, argv[count+1], &maxIts) != TCL_OK) - return TCL_ERROR; - } else if (strcmp(argv[count],"-KSP") == 0 || strcmp(argv[count],"-KSPType")){ - if (strcmp(argv[count+1],"KSPCG") == 0) - method = KSPCG; - else if (strcmp(argv[count+1],"KSPBICG") == 0) - method = KSPBICG; - else if (strcmp(argv[count+1],"KSPRICHARDSON") == 0) - method = KSPRICHARDSON; - else if (strcmp(argv[count+1],"KSPCHEBYSHEV") == 0) - method = KSPCHEBYSHEV; - else if (strcmp(argv[count+1],"KSPGMRES") == 0) - method = KSPGMRES; - } else if (strcmp(argv[count],"-PC") == 0 || strcmp(argv[count],"-PCType")){ - if ((strcmp(argv[count+1],"PCJACOBI") == 0) || (strcmp(argv[count+1],"JACOBI") == 0)) - preconditioner = PCJACOBI; - else if ((strcmp(argv[count+1],"PCILU") == 0) || (strcmp(argv[count+1],"ILU") == 0)) - preconditioner = PCILU; - else if ((strcmp(argv[count+1],"PCICC") == 0) || (strcmp(argv[count+1],"ICC") == 0)) - preconditioner = PCICC; - else if ((strcmp(argv[count+1],"PCBJACOBI") == 0) || (strcmp(argv[count+1],"BIJACOBI") == 0)) - preconditioner = PCBJACOBI; - else if ((strcmp(argv[count+1],"PCNONE") == 0) || (strcmp(argv[count+1],"NONE") == 0)) - preconditioner = PCNONE; - } - count+=2; - } - - - if (matType == 0) { - // PetscSolver *theSolver = new PetscSolver(method, preconditioner, rTol, aTol, dTol, maxIts); - PetscSolver *theSolver = new PetscSolver(method, preconditioner, rTol, aTol, dTol, maxIts); - theSOE = new PetscSOE(*theSolver); - } else { - // PetscSparseSeqSolver *theSolver = new PetscSparseSeqSolver(method, preconditioner, rTol, aTol, dTol, maxIts); - PetscSparseSeqSolver *theSolver = 0; - theSOE = new SparseGenRowLinSOE(*theSolver); - } - } - - -#endif - - -#ifdef _MUMPS - - else if (strcmp(argv[1],"Mumps") == 0) { - - int icntl14 = 20; - int icntl7 = 7; - int matType = 0; // 0: unsymmetric, 1: symmetric positive definite, 2: symmetric general - - int currentArg = 2; - while (currentArg < argc) { - if (argc > 2) { - if (strcmp(argv[currentArg],"-ICNTL14") == 0) { - if (Tcl_GetInt(interp, argv[currentArg+1], &icntl14) != TCL_OK) - ; - currentArg += 2; - } else if (strcmp(argv[currentArg],"-ICNTL7") == 0) { - if (Tcl_GetInt(interp, argv[currentArg+1], &icntl7) != TCL_OK) - ; - currentArg += 2; - } else if (strcmp(argv[currentArg],"-matrixType") == 0) { - if (Tcl_GetInt(interp, argv[currentArg+1], &matType) != TCL_OK) - opserr << "Mumps Warning: failed to get -matrixType. Unsymmetric matrix assumed\n"; - if (matType < 0 || matType > 2) { - opserr << "Mumps Warning: wrong -matrixType value (" << matType << "). Unsymmetric matrix assumed\n"; - matType = 0; - } - currentArg += 2; - } else - currentArg++; - } - } - -#ifdef _PARALLEL_PROCESSING - MumpsParallelSolver *theSolver = new MumpsParallelSolver(icntl7, icntl14); - theSOE = new MumpsParallelSOE(*theSolver); -#elif _PARALLEL_INTERPRETERS - MumpsParallelSolver *theSolver = new MumpsParallelSolver(icntl7, icntl14); - MumpsParallelSOE *theParallelSOE = new MumpsParallelSOE(*theSolver, matType); - theParallelSOE->setProcessID(OPS_rank); - theParallelSOE->setChannels(numChannels, theChannels); - theSOE = theParallelSOE; -#else - MumpsSolver *theSolver = new MumpsSolver(icntl7, icntl14); - theSOE = new MumpsSOE(*theSolver, matType); -#endif - - } - -#endif - - - else { - - // - // maybe a package - // - - // try existing loaded packages - ExternalClassFunction *solverCommands = theExternalSolverCommands; - bool found = false; - // int result = TCL_ERROR; - while (solverCommands != NULL && found == false) { - - if (strcmp(argv[1], solverCommands->funcName) == 0) { - - OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); - void *theRes = (*(solverCommands->funcPtr))(); - if (theRes != 0) { - - theSOE = (LinearSOE *)theRes; - found = true; - } - } else - solverCommands = solverCommands->next; - } - - // - // if not there try loading package - // - - if (found == false) { - - void *libHandle; - void *(*funcPtr)(); - int solverNameLength = strlen(argv[1]); - char *tclFuncName = new char[solverNameLength+5]; - strcpy(tclFuncName, "OPS_"); - strcpy(&tclFuncName[4], argv[1]); - - int res = getLibraryFunction(argv[1], tclFuncName, &libHandle, (void **)&funcPtr); - - delete [] tclFuncName; - - if (res == 0) { - - char *solverName = new char[solverNameLength+1]; - strcpy(solverName, argv[1]); - ExternalClassFunction *theSolverCommand = new ExternalClassFunction; - theSolverCommand->funcPtr = funcPtr; - theSolverCommand->funcName = solverName; - theSolverCommand->next = theExternalSolverCommands; - theExternalSolverCommands = theSolverCommand; - - OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); - - void *theRes = (*funcPtr)(); - if (theRes != 0) { - theSOE = (LinearSOE *)theRes; - } - } - } - } - - // if the analysis exists - we want to change the SOEif - - if (theSOE != 0) { - if (theStaticAnalysis != 0) - theStaticAnalysis->setLinearSOE(*theSOE); - if (theTransientAnalysis != 0) - theTransientAnalysis->setLinearSOE(*theSOE); - -#ifdef _PARALLEL_PROCESSING - if (theStaticAnalysis != 0 || theTransientAnalysis != 0) { - SubdomainIter &theSubdomains = theDomain.getSubdomains(); - Subdomain *theSub; - while ((theSub = theSubdomains()) != 0) { - theSub->setAnalysisLinearSOE(*theSOE); - } - } -#endif - - return TCL_OK; - } - - return TCL_ERROR; -} - - - -// -// command invoked to allow the Numberer objects to be built -// -int -specifyNumberer(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) -{ - // make sure at least one other argument to contain numberer - if (argc < 2) { - opserr << "WARNING need to specify a Nemberer type \n"; - return TCL_ERROR; - } - -#ifdef _PARALLEL_PROCESSING - // check argv[1] for type of Numberer and create the object - if (strcmp(argv[1],"Plain") == 0) { - theNumberer = new ParallelNumberer(); - } else if (strcmp(argv[1],"RCM") == 0) { - RCM *theRCM = new RCM(false); - theNumberer = new ParallelNumberer(*theRCM); - } else { - opserr << "WARNING No Numberer type exists (Plain, RCM only) \n"; - return TCL_ERROR; - } - -#else - - // check argv[1] for type of Numberer and create the object - if (strcmp(argv[1],"Plain") == 0) { - theNumberer = new PlainNumberer(); - } else if (strcmp(argv[1],"RCM") == 0) { - RCM *theRCM = new RCM(false); - theNumberer = new DOF_Numberer(*theRCM); - } else if (strcmp(argv[1],"AMD") == 0) { - AMD *theAMD = new AMD(); - theNumberer = new DOF_Numberer(*theAMD); - } - -#ifdef _PARALLEL_INTERPRETERS - - else if ((strcmp(argv[1],"ParallelPlain") == 0) || (strcmp(argv[1],"Parallel") == 0)) { - ParallelNumberer *theParallelNumberer = new ParallelNumberer; - theNumberer = theParallelNumberer; - theParallelNumberer->setProcessID(OPS_rank); - theParallelNumberer->setChannels(numChannels, theChannels); - } else if (strcmp(argv[1],"ParallelRCM") == 0) { - RCM *theRCM = new RCM(false); - ParallelNumberer *theParallelNumberer = new ParallelNumberer(*theRCM); - theNumberer = theParallelNumberer; - theParallelNumberer->setProcessID(OPS_rank); - theParallelNumberer->setChannels(numChannels, theChannels); - } - -#endif - - else { - opserr << "WARNING No Numberer type exists (Plain, RCM only) \n"; - return TCL_ERROR; - } -#endif - - return TCL_OK; -} - - - - -// -// command invoked to allow the ConstraintHandler object to be built -// -int -specifyConstraintHandler(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv) -{ - // make sure at least one other argument to contain numberer - if (argc < 2) { - opserr << "WARNING need to specify a Nemberer type \n"; - return TCL_ERROR; - } - - // check argv[1] for type of Numberer and create the object - if (strcmp(argv[1],"Plain") == 0) - theHandler = new PlainHandler(); - - else if (strcmp(argv[1],"Penalty") == 0) { - if (argc < 4) { - opserr << "WARNING: need to specify alpha: handler Penalty alpha \n"; - return TCL_ERROR; - } - double alpha1, alpha2; - if (Tcl_GetDouble(interp, argv[2], &alpha1) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[3], &alpha2) != TCL_OK) - return TCL_ERROR; - theHandler = new PenaltyConstraintHandler(alpha1, alpha2); - } - - /****** adding later - else if (strcmp(argv[1],"PenaltyNoHomoSPMultipliers") == 0) { - if (argc < 4) { - opserr << "WARNING: need to specify alpha: handler Penalty alpha \n"; - return TCL_ERROR; - } - double alpha1, alpha2; - if (Tcl_GetDouble(interp, argv[2], &alpha1) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[3], &alpha2) != TCL_OK) - return TCL_ERROR; - theHandler = new PenaltyHandlerNoHomoSPMultipliers(alpha1, alpha2); - } - ***********************/ - else if (strcmp(argv[1],"Lagrange") == 0) { - double alpha1 = 1.0; - double alpha2 = 1.0; - if (argc == 4) { - if (Tcl_GetDouble(interp, argv[2], &alpha1) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[3], &alpha2) != TCL_OK) - return TCL_ERROR; - } - theHandler = new LagrangeConstraintHandler(alpha1, alpha2); - } - - else if (strcmp(argv[1],"Transformation") == 0) { - theHandler = new TransformationConstraintHandler(); - } - - else { - opserr << "WARNING No ConstraintHandler type exists (Plain, Penalty,\n"; - opserr << " Lagrange, Transformation) only\n"; - return TCL_ERROR; - } - return TCL_OK; -} - - - -// -// command invoked to allow the SolnAlgorithm object to be built -// -int -specifyAlgorithm(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv) -{ - // make sure at least one other argument to contain numberer - if (argc < 2) { - opserr << "WARNING need to specify an Algorithm type \n"; - return TCL_ERROR; - } - EquiSolnAlgo *theNewAlgo = 0; - OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); - - // check argv[1] for type of Algorithm and create the object - if (strcmp(argv[1],"Linear") == 0) { - int formTangent = CURRENT_TANGENT; - int factorOnce = 0; - int count = 2; - while (count < argc) { - if ((strcmp(argv[count],"-secant") == 0) || (strcmp(argv[count],"-Secant") == 0)) { - formTangent = CURRENT_SECANT; - } else if ((strcmp(argv[count],"-initial") == 0) || (strcmp(argv[count],"-Initial") == 0)) { - formTangent = INITIAL_TANGENT; - } else if ((strcmp(argv[count],"-factorOnce") == 0) || (strcmp(argv[count],"-FactorOnce") ==0 )) { - factorOnce = 1; - } - count++; - } - theNewAlgo = new Linear(formTangent, factorOnce); - } - - else if (strcmp(argv[1],"Newton") == 0) { - void *theNewtonAlgo = OPS_NewtonRaphsonAlgorithm(); - if (theNewtonAlgo == 0) - return TCL_ERROR; - - theNewAlgo = (EquiSolnAlgo *)theNewtonAlgo; - if (theTest != 0) - theNewAlgo->setConvergenceTest(theTest); - } - - else if ((strcmp(argv[1],"NewtonHallM") == 0) || (strcmp(argv[1],"NewtonHall") == 0)) { - void *theNewtonAlgo = OPS_NewtonHallM(); - if (theNewtonAlgo == 0) - return TCL_ERROR; - - theNewAlgo = (EquiSolnAlgo *)theNewtonAlgo; - if (theTest != 0) - theNewAlgo->setConvergenceTest(theTest); - } - - else if (strcmp(argv[1],"ModifiedNewton") == 0) { - void *theNewtonAlgo = OPS_ModifiedNewton(); - if (theNewtonAlgo == 0) - return TCL_ERROR; - - theNewAlgo = (EquiSolnAlgo *)theNewtonAlgo; - if (theTest != 0) - theNewAlgo->setConvergenceTest(theTest); - } - - else if (strcmp(argv[1],"KrylovNewton") == 0) { - int incrementTangent = CURRENT_TANGENT; - int iterateTangent = CURRENT_TANGENT; - int maxDim = 3; - for (int i = 2; i < argc; i++) { - if (strcmp(argv[i],"-iterate") == 0 && i+1 < argc) { - i++; - if (strcmp(argv[i],"current") == 0) - iterateTangent = CURRENT_TANGENT; - if (strcmp(argv[i],"initial") == 0) - iterateTangent = INITIAL_TANGENT; - if (strcmp(argv[i],"noTangent") == 0) - iterateTangent = NO_TANGENT; - } - else if (strcmp(argv[i],"-increment") == 0 && i+1 < argc) { - i++; - if (strcmp(argv[i],"current") == 0) - incrementTangent = CURRENT_TANGENT; - if (strcmp(argv[i],"initial") == 0) - incrementTangent = INITIAL_TANGENT; - if (strcmp(argv[i],"noTangent") == 0) - incrementTangent = NO_TANGENT; - } - else if (strcmp(argv[i],"-maxDim") == 0 && i+1 < argc) { - i++; - maxDim = atoi(argv[i]); - } - } - - if (theTest == 0) { - opserr << "ERROR: No ConvergenceTest yet specified\n"; - return TCL_ERROR; - } - - Accelerator *theAccel; - theAccel = new KrylovAccelerator(maxDim, iterateTangent); - - theNewAlgo = new AcceleratedNewton(*theTest, theAccel, incrementTangent); - } - - else if (strcmp(argv[1],"RaphsonNewton") == 0) { - int incrementTangent = CURRENT_TANGENT; - int iterateTangent = CURRENT_TANGENT; - for (int i = 2; i < argc; i++) { - if (strcmp(argv[i],"-iterate") == 0 && i+1 < argc) { - i++; - if (strcmp(argv[i],"current") == 0) - iterateTangent = CURRENT_TANGENT; - if (strcmp(argv[i],"initial") == 0) - iterateTangent = INITIAL_TANGENT; - if (strcmp(argv[i],"noTangent") == 0) - iterateTangent = NO_TANGENT; - } - else if (strcmp(argv[i],"-increment") == 0 && i+1 < argc) { - i++; - if (strcmp(argv[i],"current") == 0) - incrementTangent = CURRENT_TANGENT; - if (strcmp(argv[i],"initial") == 0) - incrementTangent = INITIAL_TANGENT; - if (strcmp(argv[i],"noTangent") == 0) - incrementTangent = NO_TANGENT; - } - } - - if (theTest == 0) { - opserr << "ERROR: No ConvergenceTest yet specified\n"; - return TCL_ERROR; - } - - Accelerator *theAccel; - theAccel = new RaphsonAccelerator(iterateTangent); - - theNewAlgo = new AcceleratedNewton(*theTest, theAccel, incrementTangent); - } - - else if (strcmp(argv[1],"MillerNewton") == 0) { - int incrementTangent = CURRENT_TANGENT; - int iterateTangent = CURRENT_TANGENT; - int maxDim = 3; - - for (int i = 2; i < argc; i++) { - if (strcmp(argv[i],"-iterate") == 0 && i+1 < argc) { - i++; - if (strcmp(argv[i],"current") == 0) - iterateTangent = CURRENT_TANGENT; - if (strcmp(argv[i],"initial") == 0) - iterateTangent = INITIAL_TANGENT; - if (strcmp(argv[i],"noTangent") == 0) - iterateTangent = NO_TANGENT; - } - else if (strcmp(argv[i],"-increment") == 0 && i+1 < argc) { - i++; - if (strcmp(argv[i],"current") == 0) - incrementTangent = CURRENT_TANGENT; - if (strcmp(argv[i],"initial") == 0) - incrementTangent = INITIAL_TANGENT; - if (strcmp(argv[i],"noTangent") == 0) - incrementTangent = NO_TANGENT; - } - else if (strcmp(argv[i],"-maxDim") == 0 && i+1 < argc) { - i++; - maxDim = atoi(argv[i]); - } - } - - if (theTest == 0) { - opserr << "ERROR: No ConvergenceTest yet specified\n"; - return TCL_ERROR; - } - - Accelerator *theAccel = 0; - //theAccel = new MillerAccelerator(maxDim, 0.01, iterateTangent); - - theNewAlgo = new AcceleratedNewton(*theTest, theAccel, incrementTangent); - } - - else if (strcmp(argv[1],"SecantNewton") == 0) { - int incrementTangent = CURRENT_TANGENT; - int iterateTangent = CURRENT_TANGENT; - int maxDim = 3; - for (int i = 2; i < argc; i++) { - if (strcmp(argv[i],"-iterate") == 0 && i+1 < argc) { - i++; - if (strcmp(argv[i],"current") == 0) - iterateTangent = CURRENT_TANGENT; - if (strcmp(argv[i],"initial") == 0) - iterateTangent = INITIAL_TANGENT; - if (strcmp(argv[i],"noTangent") == 0) - iterateTangent = NO_TANGENT; - } - else if (strcmp(argv[i],"-increment") == 0 && i+1 < argc) { - i++; - if (strcmp(argv[i],"current") == 0) - incrementTangent = CURRENT_TANGENT; - if (strcmp(argv[i],"initial") == 0) - incrementTangent = INITIAL_TANGENT; - if (strcmp(argv[i],"noTangent") == 0) - incrementTangent = NO_TANGENT; - } - else if (strcmp(argv[i],"-maxDim") == 0 && i+1 < argc) { - i++; - maxDim = atoi(argv[i]); - } - } - - if (theTest == 0) { - opserr << "ERROR: No ConvergenceTest yet specified\n"; - return TCL_ERROR; - } - - Accelerator *theAccel; - theAccel = new SecantAccelerator2(maxDim, iterateTangent); - - theNewAlgo = new AcceleratedNewton(*theTest, theAccel, incrementTangent); - } - - else if (strcmp(argv[1],"PeriodicNewton") == 0) { - int incrementTangent = CURRENT_TANGENT; - int iterateTangent = CURRENT_TANGENT; - int maxDim = 3; - for (int i = 2; i < argc; i++) { - if (strcmp(argv[i],"-iterate") == 0 && i+1 < argc) { - i++; - if (strcmp(argv[i],"current") == 0) - iterateTangent = CURRENT_TANGENT; - if (strcmp(argv[i],"initial") == 0) - iterateTangent = INITIAL_TANGENT; - if (strcmp(argv[i],"noTangent") == 0) - iterateTangent = NO_TANGENT; - } - else if (strcmp(argv[i],"-increment") == 0 && i+1 < argc) { - i++; - if (strcmp(argv[i],"current") == 0) - incrementTangent = CURRENT_TANGENT; - if (strcmp(argv[i],"initial") == 0) - incrementTangent = INITIAL_TANGENT; - if (strcmp(argv[i],"noTangent") == 0) - incrementTangent = NO_TANGENT; - } - else if (strcmp(argv[i],"-maxDim") == 0 && i+1 < argc) { - i++; - maxDim = atoi(argv[i]); - } - } - - if (theTest == 0) { - opserr << "ERROR: No ConvergenceTest yet specified\n"; - return TCL_ERROR; - } - - Accelerator *theAccel; - theAccel = new PeriodicAccelerator(maxDim, iterateTangent); - - theNewAlgo = new AcceleratedNewton(*theTest, theAccel, incrementTangent); - } - - else if (strcmp(argv[1],"Broyden") == 0) { - int formTangent = CURRENT_TANGENT; - int count = -1; - - if (theTest == 0) { - opserr << "ERROR: No ConvergenceTest yet specified\n"; - return TCL_ERROR; - } - for (int i = 2; i < argc; i++) { - if (strcmp(argv[i],"-secant") == 0) { - formTangent = CURRENT_SECANT; - } else if (strcmp(argv[i],"-initial") == 0) { - formTangent = INITIAL_TANGENT; - } else if (strcmp(argv[i++],"-count") == 0 && i < argc) { - count = atoi(argv[i]); - } - } - - if (count == -1) - theNewAlgo = new Broyden(*theTest, formTangent); - else - theNewAlgo = new Broyden(*theTest, formTangent, count); - } - - else if (strcmp(argv[1],"BFGS") == 0) { - int formTangent = CURRENT_TANGENT; - int count = -1; - for (int i = 2; i < argc; i++) { - if (strcmp(argv[i],"-secant") == 0) { - formTangent = CURRENT_SECANT; - } else if (strcmp(argv[i],"-initial") == 0) { - formTangent = INITIAL_TANGENT; - } else if (strcmp(argv[i++],"-count") == 0 && i < argc) { - count = atoi(argv[i]); - } - } - - if (theTest == 0) { - opserr << "ERROR: No ConvergenceTest yet specified\n"; - return TCL_ERROR; - } - - if (count == -1) - theNewAlgo = new BFGS(*theTest, formTangent); - else - theNewAlgo = new BFGS(*theTest, formTangent, count); - } - - else if (strcmp(argv[1],"NewtonLineSearch") == 0) { - if (theTest == 0) { - opserr << "ERROR: No ConvergenceTest yet specified\n"; - return TCL_ERROR; - } - - int count = 2; - - // set some default variable - double tol = 0.8; - int maxIter = 10; - double maxEta = 10.0; - double minEta = 0.1; - int pFlag = 1; - int typeSearch = 0; - - while (count < argc) { - if (strcmp(argv[count], "-tol") == 0) { - count++; - if (Tcl_GetDouble(interp, argv[count], &tol) != TCL_OK) - return TCL_ERROR; - count++; - } else if (strcmp(argv[count], "-maxIter") == 0) { - count++; - if (Tcl_GetInt(interp, argv[count], &maxIter) != TCL_OK) - return TCL_ERROR; - count++; - } else if (strcmp(argv[count], "-pFlag") == 0) { - count++; - if (Tcl_GetInt(interp, argv[count], &pFlag) != TCL_OK) - return TCL_ERROR; - count++; - } else if (strcmp(argv[count], "-minEta") == 0) { - count++; - if (Tcl_GetDouble(interp, argv[count], &minEta) != TCL_OK) - return TCL_ERROR; - count++; - } else if (strcmp(argv[count], "-maxEta") == 0) { - count++; - if (Tcl_GetDouble(interp, argv[count], &maxEta) != TCL_OK) - return TCL_ERROR; - count++; - } else if (strcmp(argv[count], "-type") == 0) { - count++; - if (strcmp(argv[count], "Bisection") == 0) - typeSearch = 1; - else if (strcmp(argv[count], "Secant") == 0) - typeSearch = 2; - else if (strcmp(argv[count], "RegulaFalsi") == 0) - typeSearch = 3; - else if (strcmp(argv[count], "LinearInterpolated") == 0) - typeSearch = 3; - else if (strcmp(argv[count], "InitialInterpolated") == 0) - typeSearch = 0; - count++; - } else - count++; - } - - LineSearch *theLineSearch = 0; - if (typeSearch == 0) - theLineSearch = new InitialInterpolatedLineSearch(tol, maxIter, minEta, maxEta, pFlag); - - else if (typeSearch == 1) - theLineSearch = new BisectionLineSearch(tol, maxIter, minEta, maxEta, pFlag); - else if (typeSearch == 2) - theLineSearch = new SecantLineSearch(tol, maxIter, minEta, maxEta, pFlag); - else if (typeSearch == 3) - theLineSearch = new RegulaFalsiLineSearch(tol, maxIter, minEta, maxEta, pFlag); - - theNewAlgo = new NewtonLineSearch(*theTest, theLineSearch); - } - - else if (strcmp(argv[1],"ExpressNewton") == 0) { - int nIter = 2, factorOnce = 0, formTangent = CURRENT_TANGENT; - double kMultiplier = 1.0; - if (argc >= 3 && Tcl_GetInt(interp, argv[2], &nIter) != TCL_OK) - return TCL_ERROR; - if (argc >= 4 && Tcl_GetDouble(interp, argv[3], &kMultiplier) != TCL_OK) - return TCL_ERROR; - int count = 4; - while (argc > count) { - if ((strcmp(argv[count],"-initialTangent") == 0) || (strcmp(argv[count],"-InitialTangent") == 0)) { - formTangent = INITIAL_TANGENT; - } else if ((strcmp(argv[count],"-currentTangent") == 0) || (strcmp(argv[count],"-CurrentTangent") ==0 )) { - formTangent = CURRENT_TANGENT; - } else if ((strcmp(argv[count],"-factorOnce") == 0) || (strcmp(argv[count],"-FactorOnce") ==0 )) { - factorOnce = 1; - } - count++; - } - theNewAlgo = new ExpressNewton(nIter,kMultiplier,formTangent,factorOnce); - } - - else { - opserr << "WARNING No EquiSolnAlgo type " << argv[1] << " exists\n"; - return TCL_ERROR; - } - - - if (theNewAlgo != 0) { - theAlgorithm = theNewAlgo; - - // if the analysis exists - we want to change the SOE - if (theStaticAnalysis != 0) - theStaticAnalysis->setAlgorithm(*theAlgorithm); - else if (theTransientAnalysis != 0) - theTransientAnalysis->setAlgorithm(*theAlgorithm); - -#ifdef _PARALLEL_PROCESSING - if (theStaticAnalysis != 0 || theTransientAnalysis != 0) { - SubdomainIter &theSubdomains = theDomain.getSubdomains(); - Subdomain *theSub; - while ((theSub = theSubdomains()) != 0) { - theSub->setAnalysisAlgorithm(*theAlgorithm); - } - } -#endif - } - - return TCL_OK; -} - - -// -// command invoked to allow the SolnAlgorithm object to be built -// -int -specifyCTest(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv) -{ - // make sure at least one other argument to contain numberer - if (argc < 2) { - opserr << "WARNING need to specify a ConvergenceTest Type type \n"; - return TCL_ERROR; - } - - // get the tolerence first - double tol = 0.0; - double tol2 = 0.0; - double tolp = 0.0; - double tolp2 = 0.0; - double tolrel = 0.0; - double tolprel = 0.0; - double maxTol = OPS_MAXTOL; - - int numIter = 0; - int printIt = 0; - int normType = 2; - int maxIncr = -1; - - if ((strcmp(argv[1],"NormDispAndUnbalance") == 0) || - (strcmp(argv[1],"NormDispOrUnbalance") == 0)) { - if (argc == 5) { - if (Tcl_GetDouble(interp, argv[2], &tol) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[3], &tol2) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &numIter) != TCL_OK) - return TCL_ERROR; - } else if (argc == 6) { - if (Tcl_GetDouble(interp, argv[2], &tol) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[3], &tol2) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[5], &printIt) != TCL_OK) - return TCL_ERROR; - } else if (argc == 7) { - if (Tcl_GetDouble(interp, argv[2], &tol) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[3], &tol2) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[5], &printIt) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[6], &normType) != TCL_OK) - return TCL_ERROR; - } else if (argc == 8) { - if (Tcl_GetDouble(interp, argv[2], &tol) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[3], &tol2) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[5], &printIt) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[6], &normType) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[7], &maxIncr) != TCL_OK) - return TCL_ERROR; - } - - } else if (strcmp(argv[1],"PFEM") == 0) { - if(argc > 8) { - if(Tcl_GetDouble(interp, argv[2], &tol) != TCL_OK) - return TCL_ERROR; - if(Tcl_GetDouble(interp, argv[3], &tolp) != TCL_OK) - return TCL_ERROR; - if(Tcl_GetDouble(interp, argv[4], &tol2) != TCL_OK) - return TCL_ERROR; - if(Tcl_GetDouble(interp, argv[5], &tolp2) != TCL_OK) - return TCL_ERROR; - if(Tcl_GetDouble(interp, argv[6], &tolrel) != TCL_OK) - return TCL_ERROR; - if(Tcl_GetDouble(interp, argv[7], &tolprel) != TCL_OK) - return TCL_ERROR; - if(Tcl_GetInt(interp, argv[8], &numIter) != TCL_OK) - return TCL_ERROR; - } - if(argc > 9) { - if(Tcl_GetInt(interp, argv[9], &maxIncr) != TCL_OK) - return TCL_ERROR; - } - if(argc > 10) { - if(Tcl_GetInt(interp, argv[10], &printIt) != TCL_OK) - return TCL_ERROR; - } - if(argc > 11) { - if(Tcl_GetInt(interp, argv[11], &normType) != TCL_OK) - return TCL_ERROR; - } - - } else if (strcmp(argv[1],"FixedNumIter") == 0) { - - if (argc == 3) { - if (Tcl_GetInt(interp, argv[2], &numIter) != TCL_OK) - return TCL_ERROR; - } else if (argc == 4) { - if (Tcl_GetInt(interp, argv[2], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[3], &printIt) != TCL_OK) - return TCL_ERROR; - } else if (argc == 5) { - if (Tcl_GetInt(interp, argv[2], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[3], &printIt) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &normType) != TCL_OK) - return TCL_ERROR; - } else if (argc == 6) { - if (Tcl_GetInt(interp, argv[2], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[3], &printIt) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &normType) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[5], &maxTol) != TCL_OK) - return TCL_ERROR; - } - - } else { - if (argc == 4) { - if (Tcl_GetDouble(interp, argv[2], &tol) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[3], &numIter) != TCL_OK) - return TCL_ERROR; - } else if (argc == 5) { - if (Tcl_GetDouble(interp, argv[2], &tol) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[3], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &printIt) != TCL_OK) - return TCL_ERROR; - } else if (argc == 6) { - if (Tcl_GetDouble(interp, argv[2], &tol) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[3], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &printIt) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[5], &normType) != TCL_OK) - return TCL_ERROR; - } else if (argc == 7) { - if (Tcl_GetDouble(interp, argv[2], &tol) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[3], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[4], &printIt) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[5], &normType) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[6], &maxTol) != TCL_OK) - return TCL_ERROR; - } - } - - - ConvergenceTest *theNewTest = 0; - - if (numIter == 0) { - opserr << "ERROR: no numIter specified in test command\n"; - return TCL_ERROR; - } - - if (strcmp(argv[1],"FixedNumIter") == 0) - theNewTest = new CTestFixedNumIter(numIter,printIt,normType); - else { - if (tol == 0.0) { - opserr << "ERROR: no tolerance specified in test command\n"; - return TCL_ERROR; - } - if (strcmp(argv[1],"NormUnbalance") == 0) - theNewTest = new CTestNormUnbalance(tol,numIter,printIt,normType,maxIncr, maxTol); - else if (strcmp(argv[1],"NormDispIncr") == 0) - theNewTest = new CTestNormDispIncr(tol,numIter,printIt,normType, maxTol); - else if (strcmp(argv[1],"NormDispAndUnbalance") == 0) - theNewTest = new NormDispAndUnbalance(tol,tol2, numIter,printIt,normType,maxIncr); - else if (strcmp(argv[1],"NormDispOrUnbalance") == 0) - theNewTest = new NormDispOrUnbalance(tol,tol2, numIter,printIt,normType,maxIncr); - else if (strcmp(argv[1],"EnergyIncr") == 0) - theNewTest = new CTestEnergyIncr(tol,numIter,printIt,normType, maxTol); - else if (strcmp(argv[1],"RelativeNormUnbalance") == 0) - theNewTest = new CTestRelativeNormUnbalance(tol,numIter,printIt,normType); - else if (strcmp(argv[1],"RelativeNormDispIncr") == 0) - theNewTest = new CTestRelativeNormDispIncr(tol,numIter,printIt,normType); - else if (strcmp(argv[1],"RelativeEnergyIncr") == 0) - theNewTest = new CTestRelativeEnergyIncr(tol,numIter,printIt,normType); - else if (strcmp(argv[1],"RelativeTotalNormDispIncr") == 0) - theNewTest = new CTestRelativeTotalNormDispIncr(tol,numIter,printIt,normType); - else if (strcmp(argv[1],"PFEM") == 0) - theNewTest = new CTestPFEM(tol,tolp,tol2,tolp2,tolrel,tolprel,numIter,maxIncr,printIt,normType); - else { - opserr << "WARNING No ConvergenceTest type (NormUnbalance, NormDispIncr, EnergyIncr, \n"; - opserr << "RelativeNormUnbalance, RelativeNormDispIncr, RelativeEnergyIncr, \n"; - opserr << "RelativeTotalNormDispIncr, FixedNumIter)\n"; - return TCL_ERROR; - } - } - - if (theNewTest != 0) { - theTest = theNewTest; - - // if the analysis exists - we want to change the Test - if (theStaticAnalysis != 0) - theStaticAnalysis->setConvergenceTest(*theTest); - - else if (theTransientAnalysis != 0) - theTransientAnalysis->setConvergenceTest(*theTest); - -#ifdef _PARALLEL_PROCESSING - if (theStaticAnalysis != 0 || theTransientAnalysis != 0) { - SubdomainIter &theSubdomains = theDomain.getSubdomains(); - Subdomain *theSub; - while ((theSub = theSubdomains()) != 0) { - theSub->setAnalysisConvergenceTest(*theTest);; - } - } -#endif - } - - return TCL_OK; -} - - - -// -// command invoked to allow the Integrator object to be built -// -int -specifyIntegrator(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv) -{ - - OPS_ResetInputNoBuilder(clientData, interp, 2, argc, argv, &theDomain); - - // make sure at least one other argument to contain integrator - if (argc < 2) { - opserr << "WARNING need to specify an Integrator type \n"; - return TCL_ERROR; - } - - // check argv[1] for type of Numberer and create the object - if (strcmp(argv[1],"LoadControl") == 0) { - double dLambda; - double minIncr, maxIncr; - int numIter; - if (argc < 3) { - opserr << "WARNING incorrect # args - integrator LoadControl dlam \n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[2], &dLambda) != TCL_OK) - return TCL_ERROR; - if (argc > 5) { - if (Tcl_GetInt(interp, argv[3], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[4], &minIncr) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[5], &maxIncr) != TCL_OK) - return TCL_ERROR; - } - else { - minIncr = dLambda; - maxIncr = dLambda; - numIter = 1; - } - theStaticIntegrator = new LoadControl(dLambda, numIter, minIncr, maxIncr); - - // if the analysis exists - we want to change the Integrator - if (theStaticAnalysis != 0) - theStaticAnalysis->setIntegrator(*theStaticIntegrator); - } else if (strcmp(argv[1],"StagedLoadControl") == 0) { - double dLambda; - double minIncr, maxIncr; - int numIter; - if (argc < 3) { - opserr << "WARNING incorrect # args - integrator StagedLoadControl dlam \n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[2], &dLambda) != TCL_OK) - return TCL_ERROR; - if (argc > 5) { - if (Tcl_GetInt(interp, argv[3], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[4], &minIncr) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[5], &maxIncr) != TCL_OK) - return TCL_ERROR; - } - else { - minIncr = dLambda; - maxIncr = dLambda; - numIter = 1; - } - theStaticIntegrator = new StagedLoadControl(dLambda, numIter, minIncr, maxIncr); - - - if (theStaticAnalysis != 0) - theStaticAnalysis->setIntegrator(*theStaticIntegrator); - } - - else if (strcmp(argv[1],"ArcLength") == 0) { - double arcLength; - double alpha; - if (argc != 4) { - opserr << "WARNING integrator ArcLength arcLength alpha \n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[2], &arcLength) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[3], &alpha) != TCL_OK) - return TCL_ERROR; - theStaticIntegrator = new ArcLength(arcLength,alpha); - - // if the analysis exists - we want to change the Integrator - if (theStaticAnalysis != 0) - theStaticAnalysis->setIntegrator(*theStaticIntegrator); - } - - else if (strcmp(argv[1],"ArcLength1") == 0) { - double arcLength; - double alpha; - if (argc != 4) { - opserr << "WARNING integrator ArcLength1 arcLength alpha \n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[2], &arcLength) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[3], &alpha) != TCL_OK) - return TCL_ERROR; - theStaticIntegrator = new ArcLength1(arcLength,alpha); - - // if the analysis exists - we want to change the Integrator - if (theStaticAnalysis != 0) - theStaticAnalysis->setIntegrator(*theStaticIntegrator); - } - /************************added for HSConstraint*************************************/ - - else if (strcmp(argv[1],"HSConstraint") == 0) { - double arcLength; - double psi_u; - double psi_f; - double u_ref; - if (argc < 3) { - opserr << "WARNING integrator HSConstraint \n"; - return TCL_ERROR; - } - if (argc >= 3 && Tcl_GetDouble(interp, argv[2], &arcLength) != TCL_OK) - return TCL_ERROR; - if (argc>=4 && Tcl_GetDouble(interp, argv[3], &psi_u) != TCL_OK) - return TCL_ERROR; - if (argc>=5 && Tcl_GetDouble(interp, argv[4], &psi_f) != TCL_OK) - return TCL_ERROR; - if (argc==6 && Tcl_GetDouble(interp, argv[5], &u_ref) != TCL_OK) - return TCL_ERROR; - - switch(argc) - { - case 3: - theStaticIntegrator = new HSConstraint(arcLength); - case 4: - theStaticIntegrator = new HSConstraint(arcLength, psi_u); - case 5: - theStaticIntegrator = new HSConstraint(arcLength, psi_u, psi_f); - case 6: - theStaticIntegrator = new HSConstraint(arcLength, psi_u, psi_f, u_ref); - } - // if the analysis exists - we want to change the Integrator - if (theStaticAnalysis != 0) - theStaticAnalysis->setIntegrator(*theStaticIntegrator); - } - /*********************************************************************************/ - - else if (strcmp(argv[1],"MinUnbalDispNorm") == 0) { - double lambda11, minlambda, maxlambda; - int numIter; - if (argc < 3) { - opserr << "WARNING integrator MinUnbalDispNorm lambda11 \n"; - return TCL_ERROR; - } - if (Tcl_GetDouble(interp, argv[2], &lambda11) != TCL_OK) - return TCL_ERROR; - if (argc > 5) { - if (Tcl_GetInt(interp, argv[3], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[4], &minlambda) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[5], &maxlambda) != TCL_OK) - return TCL_ERROR; - } - else { - minlambda = lambda11; - maxlambda = lambda11; - numIter = 1; - argc += 3; - } - - int signFirstStepMethod = SIGN_LAST_STEP; - if (argc == 7) - if ((strcmp(argv[argc-1],"-determinant") == 0) || - (strcmp(argv[argc-1],"-det") == 0)) - signFirstStepMethod = CHANGE_DETERMINANT; - - theStaticIntegrator = new MinUnbalDispNorm(lambda11,numIter,minlambda,maxlambda,signFirstStepMethod); - - // if the analysis exists - we want to change the Integrator - if (theStaticAnalysis != 0) - theStaticAnalysis->setIntegrator(*theStaticIntegrator); - } - - else if (strcmp(argv[1], "EQPath") == 0) { - double arcLength; - int type; - int numIter; - if (argc != 4) { - opserr << "WARNING integrator EQPath $arc_length $type \n"; - opserr << "REFS : \n"; - opserr << " https://doi.org/10.12989/sem.2013.48.6.849 \n"; - opserr << " https://doi.org/10.12989/sem.2013.48.6.879 \n"; - return TCL_ERROR; - } - - if (Tcl_GetDouble(interp, argv[2], &arcLength) != TCL_OK) - { - opserr << "WARNING integrator EQPath $arc_length $type \n"; - opserr << " https://doi.org/10.12989/sem.2013.48.6.849 \n"; - opserr << " https://doi.org/10.12989/sem.2013.48.6.879 \n"; - return TCL_ERROR; - return TCL_ERROR; - } - - if (Tcl_GetInt(interp, argv[3], &type) != TCL_OK) - { - opserr << "WARNING integrator $arc_length $type \n"; - opserr << "$type = 1 Minimum Residual Displacement \n"; - opserr << "$type = 2 Normal Plain \n"; - opserr << "$type = 3 Update Normal Plain \n"; - opserr << "$type = 4 Cylindrical Arc-Length \n"; - - return TCL_ERROR; - } - - theStaticIntegrator = new EQPath(arcLength, type); - - // if the analysis exists - we want to change the Integrator - if (theStaticAnalysis != 0) - theStaticAnalysis->setIntegrator(*theStaticIntegrator); - } - - else if (strcmp(argv[1],"DisplacementControl") == 0) { - int node; - int dof; - double increment, minIncr, maxIncr; - int numIter; - if (argc < 5) { - opserr << "WARNING integrator DisplacementControl node dof dU \n"; - opserr << "\n"; - return TCL_ERROR; - } - int tangFlag = 0; - - if (Tcl_GetInt(interp, argv[2], &node) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[3], &dof) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[4], &increment) != TCL_OK) - return TCL_ERROR; - - if (argc == 6 || argc == 9) - if (argc == 6) { - if (strcmp(argv[5],"-initial") == 0) - tangFlag = 1; - } else if (strcmp(argv[8],"-initial") == 0) - tangFlag = 1; - - if (argc > 6) { - if (Tcl_GetInt(interp, argv[5], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[6], &minIncr) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[7], &maxIncr) != TCL_OK) - return TCL_ERROR; - } - else { - minIncr = increment; - maxIncr = increment; - numIter = 1; - } - - - -#ifdef _PARALLEL_PROCESSING - - theStaticIntegrator = new DistributedDisplacementControl(node,dof-1,increment, - numIter, minIncr, maxIncr); -#else - Node *theNode = theDomain.getNode(node); - if (theNode == 0) { - opserr << "WARNING integrator DisplacementControl node dof dU : Node does not exist\n"; - return TCL_ERROR; - } - - - int numDOF = theNode->getNumberDOF(); - if (dof <= 0 || dof > numDOF) { - opserr << "WARNING integrator DisplacementControl node dof dU : invalid dof given\n"; - return TCL_ERROR; - } - - theStaticIntegrator = new DisplacementControl(node, dof-1, increment, &theDomain, - numIter, minIncr, maxIncr, tangFlag); -#endif - - // if the analysis exists - we want to change the Integrator - if (theStaticAnalysis != 0) - theStaticAnalysis->setIntegrator(*theStaticIntegrator); - } - - -#ifdef _PARALLEL_INTERPRETERS - - else if ((strcmp(argv[1],"ParallelDisplacementControl") == 0) || (strcmp(argv[1],"ParallelDisplacementControl") == 0)) { - int node; - int dof; - double increment, minIncr, maxIncr; - int numIter; - if (argc < 5) { - opserr << "WARNING integrator DisplacementControl node dof dU \n"; - opserr << "\n"; - return TCL_ERROR; - } - if (Tcl_GetInt(interp, argv[2], &node) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetInt(interp, argv[3], &dof) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[4], &increment) != TCL_OK) - return TCL_ERROR; - if (argc > 7) { - if (Tcl_GetInt(interp, argv[5], &numIter) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[6], &minIncr) != TCL_OK) - return TCL_ERROR; - if (Tcl_GetDouble(interp, argv[7], &maxIncr) != TCL_OK) - return TCL_ERROR; - } - else { - minIncr = increment; - maxIncr = increment; - numIter = 1; - } - - - DistributedDisplacementControl *theDDC = new DistributedDisplacementControl(node,dof-1,increment, - numIter, minIncr, maxIncr); - - theDDC->setProcessID(OPS_rank); - theDDC->setChannels(numChannels, theChannels); - theStaticIntegrator = theDDC; - - // if the analysis exists - we want to change the Integrator - if (theStaticAnalysis != 0) - theStaticAnalysis->setIntegrator(*theStaticIntegrator); - } -#endif - - else if ((strcmp(argv[1],"TRBDF2") == 0) || (strcmp(argv[1],"Bathe") == 0)) { - theTransientIntegrator = new TRBDF2(); - } - - else if ((strcmp(argv[1],"TRBDF3") == 0) || (strcmp(argv[1],"Bathe3") == 0)) { - theTransientIntegrator = new TRBDF3(); - } - - else if (strcmp(argv[1],"Houbolt") == 0) { - theTransientIntegrator = new Houbolt(); - } - - /*else if (strcmp(argv[1],"ParkLMS3") == 0) { - theTransientIntegrator = new ParkLMS3(); - }*/ - - else if (strcmp(argv[1],"BackwardEuler") == 0) { - int optn = 0; - if (argc == 3) { - if (Tcl_GetInt(interp, argv[2], &optn) != TCL_OK) { - opserr << "WARNING integrator BackwardEuler