![]() |
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_FEM_QUAD8_H 00021 #define MECHSYS_FEM_QUAD8_H 00022 00023 // MechSys 00024 #include <mechsys/fem/node.h> 00025 #include <mechsys/fem/geomelem.h> 00026 00027 namespace FEM 00028 { 00029 00030 class Quad8: public GeomElem 00031 { 00032 public: 00033 // Auxiliar structure to map local face IDs to local node IDs 00034 static const int Face2Node[4][3]; // 4 edges, 3 nodes/edge 00035 00036 // Constructor 00037 Quad8 (int NDim); 00038 00039 // Derived methods 00040 void SetIPs (int TotNIP); 00041 size_t FNode (size_t IdxFace, size_t IdxFNode) const { return Face2Node[IdxFace][IdxFNode]; } 00042 void Shape (double r, double s, double t) const; 00043 void Derivs (double r, double s, double t) const; 00044 void FaceShape (double r, double s) const; 00045 void FaceDerivs (double r, double s) const; 00046 void NatCoords (Mat_t & C) const; 00047 }; 00048 00049 00050 /* Local IDs 00051 Nodes Faces(edges) 00052 y 00053 | 3 6 2 2 00054 +--x @-----@-----@ +-----------+ 00055 | | | | 00056 | | | | 00057 7 @ @ 5 3| |1 00058 | | | | 00059 | | | | 00060 @-----@-----@ +-----------+ 00061 0 4 1 0 00062 */ 00063 const int Quad8::Face2Node[4][3] = {{ 0, 1, 4 }, 00064 { 1, 2, 5 }, 00065 { 2, 3, 6 }, 00066 { 3, 0, 7 }}; // order of nodes is important 00067 00068 00070 00071 00072 inline Quad8::Quad8 (int NDim) 00073 : GeomElem(NDim, /*NN*/8, /*NFN*/3, "Quad8") 00074 { 00075 SetIPs (9); 00076 } 00077 00078 inline void Quad8::SetIPs (int TotNIP) 00079 { 00080 if (TotNIP== 4) IPs = QUAD_IP2; 00081 else if (TotNIP== 9) IPs = QUAD_IP3; 00082 else if (TotNIP==16) IPs = QUAD_IP4; 00083 else if (TotNIP==25) IPs = QUAD_IP5; 00084 else throw new Fatal("Quad8::SetIPs: Total number of integration points = %d is invalid",TotNIP); 00085 00086 NIP = TotNIP; 00087 FIPs = LIN_IP3; 00088 NFIP = 3; 00089 } 00090 00091 inline void Quad8::Shape (double r, double s, double t) const 00092 { 00093 /* 3 6 2 00094 * @---------@----------@ 00095 * | (1,1)| 00096 * | s ^ | 00097 * | | | 00098 * | | | 00099 * 7 @ +----> r @ 5 00100 * | (0,0) | 00101 * | | 00102 * | | 00103 * |(-1,-1) | 00104 * @---------@----------@ 00105 * 0 4 1 00106 */ 00107 double rp1=1.0+r; double rm1=1.0-r; 00108 double sp1=1.0+s; double sm1=1.0-s; 00109 00110 N(0) = 0.25*rm1*sm1*(rm1+sm1-3.0); 00111 N(1) = 0.25*rp1*sm1*(rp1+sm1-3.0); 00112 N(2) = 0.25*rp1*sp1*(rp1+sp1-3.0); 00113 N(3) = 0.25*rm1*sp1*(rm1+sp1-3.0); 00114 N(4) = 0.50*sm1*(1.0-r*r); 00115 N(5) = 0.50*rp1*(1.0-s*s); 00116 N(6) = 0.50*sp1*(1.0-r*r); 00117 N(7) = 0.50*rm1*(1.0-s*s); 00118 } 00119 00120 inline void Quad8::Derivs (double r, double s, double t) const 00121 { 00122 /* _ _ T 00123 * | dNi | 00124 * dNdR = | --- | , where Rj = r, s 00125 * |_ dRj _| 00126 * 00127 * dNdR(j,i), j=>local coordinate and i=>shape function 00128 */ 00129 double rp1=1.0+r; double rm1=1.0-r; 00130 double sp1=1.0+s; double sm1=1.0-s; 00131 00132 dNdR(0,0) = - 0.25 * sm1 * (rm1 + rm1 + sm1 - 3.0); 00133 dNdR(0,1) = 0.25 * sm1 * (rp1 + rp1 + sm1 - 3.0); 00134 dNdR(0,2) = 0.25 * sp1 * (rp1 + rp1 + sp1 - 3.0); 00135 dNdR(0,3) = - 0.25 * sp1 * (rm1 + rm1 + sp1 - 3.0); 00136 dNdR(0,4) = - r * sm1; 00137 dNdR(0,5) = 0.50 * (1.0 - s * s); 00138 dNdR(0,6) = - r * sp1; 00139 dNdR(0,7) = - 0.5 * (1.0 - s * s); 00140 00141 dNdR(1,0) = - 0.25 * rm1 * (sm1 + rm1 + sm1 - 3.0); 00142 dNdR(1,1) = - 0.25 * rp1 * (sm1 + rp1 + sm1 - 3.0); 00143 dNdR(1,2) = 0.25 * rp1 * (sp1 + rp1 + sp1 - 3.0); 00144 dNdR(1,3) = 0.25 * rm1 * (sp1 + rm1 + sp1 - 3.0); 00145 dNdR(1,4) = - 0.50 * (1.0 - r * r); 00146 dNdR(1,5) = - s * rp1; 00147 dNdR(1,6) = 0.50 * (1.0 - r * r); 00148 dNdR(1,7) = - s * rm1; 00149 } 00150 00151 inline void Quad8::FaceShape (double r, double s) const 00152 { 00153 /* 00154 * @-----------@-----------@-> r 00155 * 0 2 1 00156 * | | | 00157 * r=-1 r=0 r=+1 00158 */ 00159 FN(0) = 0.5 * (r*r-r); 00160 FN(1) = 0.5 * (r*r+r); 00161 FN(2) = 1.0 - r*r; 00162 } 00163 00164 inline void Quad8::FaceDerivs (double r, double s) const 00165 { 00166 /* _ _ T 00167 * | dNi | 00168 * FdNdR = | --- | , where Rj = r, s 00169 * |_ dRj _| 00170 * 00171 * FdNdR(j,i), j=>local coordinate and i=>shape function 00172 */ 00173 FdNdR(0,0) = r - 0.5; 00174 FdNdR(0,1) = r + 0.5; 00175 FdNdR(0,2) = -2.0* r; 00176 } 00177 00178 inline void Quad8::NatCoords (Mat_t & C) const 00179 { 00180 C.change_dim(8,3); 00181 C = -1.0, -1.0, 1.0, 00182 +1.0, -1.0, 1.0, 00183 +1.0, +1.0, 1.0, 00184 -1.0, +1.0, 1.0, 00185 0.0, -1.0, 1.0, 00186 +1.0, 0.0, 1.0, 00187 0.0, +1.0, 1.0, 00188 -1.0, +0.0, 1.0; 00189 } 00190 00191 00193 00194 00195 // Allocate a new element 00196 GeomElem * Quad8Maker (int NDim) { return new Quad8(NDim); } 00197 00198 // Register element 00199 int Quad8Register () 00200 { 00201 GeomElemFactory["Quad8"] = Quad8Maker; 00202 GEOM.Set ("Quad8", (double)GEOM.Keys.Size()); 00203 return 0; 00204 } 00205 00206 // Call register 00207 int __Quad8_dummy_int = Quad8Register(); 00208 00209 }; // namespace FEM 00210 00211 #endif // MECHSYS_FEM_QUAD8_H