![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
00001 /************************************************************************ 00002 * MechSys - Open Library for Mechanical Systems * 00003 * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand * 00004 * Copyright (C) 2009 Sergio Galindo * 00005 * * 00006 * This program is free software: you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation, either version 3 of the License, or * 00009 * any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> * 00018 ************************************************************************/ 00019 00020 #ifndef MECHSYS_SMPINVS_H 00021 #define MECHSYS_SMPINVS_H 00022 00023 // Std Lib 00024 #include <iostream> 00025 #include <fstream> 00026 00027 // MechSys 00028 #include <mechsys/util/maps.h> 00029 #include <mechsys/util/fatal.h> 00030 #include <mechsys/linalg/matvec.h> 00031 #include <mechsys/linalg/jacobirot.h> 00032 00033 class SMPInvs 00034 { 00035 public: 00036 SMPInvs () : b(0.5), Tol(1.0e-8) {} 00037 00038 // Methods 00039 void Calc (Vec_t const & Sig, bool WithDerivs=false); 00040 00041 // Variables 00042 double b; 00043 double Tol; 00044 00045 // Data 00046 static double sp, sq; 00047 static Vec3_t N, Nu; 00048 static Vec3_t L; 00049 static Vec3_t v0,v1,v2; 00050 static Vec_t P0,P1,P2; 00051 static Vec3_t t, p, q; 00052 static Mat3_t P; 00053 00054 // Data for derivatives 00055 static Vec_t E0, E1, E2; 00056 static Mat3_t dNdL, dNudN, dNudL; 00057 static Mat3_t mL, NN, dtdL; 00058 static Vec3_t vTmp; 00059 static Mat3_t pTmp; 00060 static Mat3_t mTmp, dpdL, dqdL; 00061 static Vec3_t dspdL, dsqdL; 00062 static Vec_t dspdSig, dsqdSig; 00063 00064 #ifdef USE_BOOST_PYTHON 00065 BPy::tuple PyCalc (BPy::list const & Sig, bool WithDerivs=false) 00066 { 00067 Vec_t sig; 00068 List2Vec (Sig, sig); 00069 Calc (sig, WithDerivs); 00070 if (WithDerivs) 00071 { 00072 BPy::list dspdsig, dsqdsig; 00073 Vec2List (SMPInvs::dspdSig, dspdsig); 00074 Vec2List (SMPInvs::dsqdSig, dsqdsig); 00075 return BPy::make_tuple (SMPInvs::sp, SMPInvs::sq, dspdsig, dsqdsig); 00076 } 00077 else return BPy::make_tuple (SMPInvs::sp, SMPInvs::sq); 00078 } 00079 #endif 00080 }; 00081 00082 // Data 00083 double SMPInvs::sp; double SMPInvs::sq; 00084 Vec3_t SMPInvs::N; Vec3_t SMPInvs::Nu; 00085 Vec3_t SMPInvs::L; 00086 Vec3_t SMPInvs::v0; Vec3_t SMPInvs::v1; Vec3_t SMPInvs::v2; 00087 Vec3_t SMPInvs::t; Vec3_t SMPInvs::p; Vec3_t SMPInvs::q; 00088 Mat3_t SMPInvs::P; 00089 00090 // Derivs 00091 Vec_t SMPInvs::E0; Vec_t SMPInvs::E1; Vec_t SMPInvs::E2; 00092 Mat3_t SMPInvs::dNdL; Mat3_t SMPInvs::dNudN; Mat3_t SMPInvs::dNudL; 00093 Mat3_t SMPInvs::mL; Mat3_t SMPInvs::dtdL; 00094 Vec3_t SMPInvs::vTmp; Mat3_t SMPInvs::pTmp; 00095 Mat3_t SMPInvs::mTmp; Mat3_t SMPInvs::dpdL; Mat3_t SMPInvs::dqdL; 00096 Vec3_t SMPInvs::dspdL; Vec3_t SMPInvs::dsqdL; 00097 Vec_t SMPInvs::dspdSig; Vec_t SMPInvs::dsqdSig; 00098 00099 00101 00102 00103 inline void SMPInvs::Calc (Vec_t const & Sig, bool WithDerivs) 00104 { 00105 if (WithDerivs) EigenProj (Sig, L, v0, v1, v2, E0, E1, E2); 00106 else Eig (Sig, L, v0, v1, v2); 00107 //if (L(0)>0.0 || L(1)>0.0 || L(2)>0.0) throw new Fatal("SMPInvs::Calc: This method only works when all principal values are negative (compression octant). L=[%g,%g,%g]",L(0),L(1),L(2)); 00108 00109 // normal vector 00110 bool zero = (fabs(L(0))<Tol || fabs(L(1))<Tol || fabs(L(2))<Tol); 00111 if (zero) N = 1.0, 1.0, 1.0; 00112 else N = 1.0/pow(fabs(L(0)),b), 1.0/pow(fabs(L(1)),b), 1.0/pow(fabs(L(2)),b); 00113 Nu = N / Norm(N); 00114 00115 // traction 00116 t(0) = L(0)*Nu(0); 00117 t(1) = L(1)*Nu(1); 00118 t(2) = L(2)*Nu(2); 00119 00120 // P projector 00121 Dyad (Nu, Nu, P); 00122 00123 // invariants 00124 p = product (P, t); 00125 q = t - p; 00126 sp = Norm(p); 00127 sq = Norm(q); 00128 if ((L(0)+L(1)+L(2))>0.0) sp *= (-1.0); 00129 00130 // derivatives 00131 if (WithDerivs) 00132 { 00133 // normal to SMP 00134 if (zero) Identity (dNdL); 00135 else dNdL = -b/(L(0)*pow(fabs(L(0)),b)), 0.0, 0.0, 00136 0.0, -b/(L(1)*pow(fabs(L(1)),b)), 0.0, 00137 0.0, 0.0, -b/(L(2)*pow(fabs(L(2)),b)); 00138 UnitVecDeriv (N, Nu, dNudN, Tol); 00139 dNudL = product (dNudN, dNdL); 00140 00141 // traction 00142 mL = L(0), 0.0, 0.0, 00143 0.0, L(1), 0.0, 00144 0.0, 0.0, L(2); 00145 dtdL = product (mL, dNudL); 00146 dtdL(0,0) += Nu(0); 00147 dtdL(1,1) += Nu(1); 00148 dtdL(2,2) += Nu(2); 00149 00150 // projections 00151 double sc = dot(Nu, t); 00152 Mult (t, dNudL, vTmp); 00153 Dyad (Nu, vTmp, mTmp); 00154 pTmp = product (P, dtdL); 00155 for (size_t i=0; i<3; ++i) 00156 for (size_t j=0; j<3; ++j) 00157 { 00158 dpdL(i,j) = sc*dNudL(i,j) + mTmp(i,j) + pTmp(i,j); 00159 dqdL(i,j) = dtdL(i,j) - dpdL(i,j); 00160 } 00161 00162 // invariants 00163 if (sp>Tol) { Mult (p, dpdL, dspdL); dspdL /= sp; } else dspdL = 0.,0.,0.; 00164 if (sq>Tol) { Mult (q, dqdL, dsqdL); dsqdL /= sq; } else dsqdL = 0.,0.,0.; 00165 00166 // invariants w.r.t Sig 00167 dspdSig = dspdL(0)*E0 + dspdL(1)*E1 + dspdL(2)*E2; 00168 dsqdSig = dsqdL(0)*E0 + dsqdL(1)*E1 + dsqdL(2)*E2; 00169 } 00170 } 00171 00172 std::ostream & operator<< (std::ostream & os, SMPInvs const & SI) 00173 { 00174 os << "SMP Invariants\n"; 00175 os << "sp" << SMPInvs::sp; 00176 os << "sq" << SMPInvs::sq; 00177 os << "N" << PrintVector(SMPInvs::N); 00178 os << "Nu" << PrintVector(SMPInvs::Nu); 00179 os << "L" << PrintVector(SMPInvs::L); 00180 os << "v0" << PrintVector(SMPInvs::v0); 00181 os << "v1" << PrintVector(SMPInvs::v1); 00182 os << "v2" << PrintVector(SMPInvs::v2); 00183 os << "t" << PrintVector(SMPInvs::t); 00184 os << "p" << PrintVector(SMPInvs::p); 00185 os << "q" << PrintVector(SMPInvs::q); 00186 os << "P" << PrintMatrix(SMPInvs::P); 00187 00188 os << "\nSMP Derivatives\n"; 00189 os << "E0" << PrintVector(SMPInvs::E0); 00190 os << "E1" << PrintVector(SMPInvs::E1); 00191 os << "E2" << PrintVector(SMPInvs::E2); 00192 os << "dNdL" << PrintMatrix(SMPInvs::dNdL); 00193 os << "dNudN" << PrintMatrix(SMPInvs::dNudN); 00194 os << "dNudL" << PrintMatrix(SMPInvs::dNudL); 00195 os << "dtdL" << PrintMatrix(SMPInvs::dtdL); 00196 os << "dpdL" << PrintMatrix(SMPInvs::dpdL); 00197 os << "dqdL" << PrintMatrix(SMPInvs::dqdL); 00198 os << "dspdL" << PrintVector(SMPInvs::dspdL); 00199 os << "dsqdL" << PrintVector(SMPInvs::dsqdL); 00200 os << "dspdSig" << PrintVector(SMPInvs::dspdSig); 00201 os << "dsqdSig" << PrintVector(SMPInvs::dsqdSig); 00202 00203 return os; 00204 } 00205 00206 00207 #endif // MECHSYS_SMPINVS_H