MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
membrane.cc
Go to the documentation of this file.
1 /*
2  * MBDyn (C) is a multibody analysis code.
3  * http://www.mbdyn.org
4  *
5  * Copyright (C) 2011-2017
6  *
7  * Marco Morandini <morandini@aero.polimi.it>
8  * Riccardo Vescovini <vescovini@aero.polimi.it>
9  * Tommaso Solcia <solcia@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 /*
33  * Inspired by
34  * Wojciech Witkowski
35  * "4-Node combined shell element with semi-EAS-ANS strain interpolations
36  * in 6-parameter shell theories with drilling degrees of freedom"
37  * Comput Mech (2009) 43:307­319 DOI 10.1007/s00466-008-0307-x
38  */
39 
40 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
41 
42 #include "constltp_impl.h"
43 #include "tpldrive_impl.h"
44 #include "membrane.h"
45 #include "mynewmem.h"
46 
47 #if 0
48 #define _GNU_SOURCE 1
49 #include <fenv.h>
50 static void __attribute__ ((constructor))
51 trapfpe ()
52 {
53  /* Enable some exceptions. At startup all exceptions are masked. */
54 
55  feenableexcept (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW);
56 }
57 #endif
58 
59 Membrane::Membrane(unsigned uLabel, const DofOwner* pDO, flag fOut)
60 : Elem(uLabel, fOut),
61 ElemGravityOwner(uLabel, fOut),
62 ElemWithDofs(uLabel, pDO, fOut),
63 InitialAssemblyElem(uLabel, fOut)
64 {
65  NO_OP;
66 }
67 
69 {
70  NO_OP;
71 }
72 
73 int
75 {
76  ASSERT(pD.iGetNumRows() == 3);
77  ASSERT(pD.iGetNumCols() == 3);
78 
79  if (HP.IsKeyWord("diag")) {
80  pD.Reset();
81  for (unsigned ir = 1; ir <= 3; ir++) {
82  pD(ir, ir) = HP.GetReal();
83  }
84 
85  } else if (HP.IsKeyWord("sym")) {
86  for (unsigned ir = 1; ir <= 3; ir++) {
87  pD(ir, ir) = HP.GetReal();
88  for (unsigned ic = ir + 1; ic <= 3; ic++) {
89  doublereal d = HP.GetReal();
90  pD(ir, ic) = d;
91  pD(ic, ir) = d;
92  }
93  }
94 
95  } else if (HP.IsKeyWord("isotropic")) {
96  doublereal dE;
97  doublereal dnu;
98  doublereal dG;
99  doublereal dh;
100  bool bGot_E(false);
101  bool bGot_nu(false);
102  bool bGot_G(false);
103  bool bGot_h(false);
104 
105  while (HP.IsArg()) {
106  if (HP.IsKeyWord("E") || HP.IsKeyWord("Young" "modulus")) {
107  if (bGot_E) {
108  silent_cerr("Membrane isotropic constitutive law: Young's modulus already provided at line " << HP.GetLineData() << std::endl);
109  return -1;
110  }
111  bGot_E = true;
112  dE = HP.GetReal();
113  if (dE <= 0.) {
114  silent_cerr("Membrane isotropic constitutive law: invalid Young's modulus " << dE << " at line " << HP.GetLineData() << std::endl);
115  return -1;
116  }
117 
118  } else if (HP.IsKeyWord("nu") || HP.IsKeyWord("Poisson" "modulus")) {
119  if (bGot_nu) {
120  silent_cerr("Membrane isotropic constitutive law: Poisson's modulus already provided at line " << HP.GetLineData() << std::endl);
121  return -1;
122  }
123  bGot_nu = true;
124  dnu = HP.GetReal();
125  if (dnu < 0. || dnu >= .5) {
126  silent_cerr("Membrane isotropic constitutive law: invalid Poisson's modulus " << dnu << " at line " << HP.GetLineData() << std::endl);
127  return -1;
128  }
129 
130  } else if (HP.IsKeyWord("G") || HP.IsKeyWord("shear" "modulus")) {
131  if (bGot_G) {
132  silent_cerr("Membrane isotropic constitutive law: shear modulus already provided at line " << HP.GetLineData() << std::endl);
133  return -1;
134  }
135  bGot_G = true;
136  dG = HP.GetReal();
137  if (dG <= 0.) {
138  silent_cerr("Membrane isotropic constitutive law: invalid shear modulus " << dG << " at line " << HP.GetLineData() << std::endl);
139  return -1;
140  }
141 
142  } else if (HP.IsKeyWord("thickness")) {
143  if (bGot_h) {
144  silent_cerr("Membrane isotropic constitutive law: thickness already provided at line " << HP.GetLineData() << std::endl);
145  return -1;
146  }
147  bGot_h = true;
148  dh = HP.GetReal();
149  if (dh <= 0.) {
150  silent_cerr("Membrane isotropic constitutive law: invalid thickness " << dh << " at line " << HP.GetLineData() << std::endl);
151  return -1;
152  }
153 
154  } else {
155  break;
156  }
157  }
158 
159  int got = 0;
160  if (bGot_E) got++;
161  if (bGot_nu) got++;
162  if (bGot_G) got++;
163 
164  if (got < 2) {
165  silent_cerr("Membrane isotropic constitutive law: incomplete material data (need at least two among Young's modulus, Poisson's modulus, shear modulus)" << std::endl);
166  return -1;
167  }
168 
169  if (got > 2) {
170  if (std::abs(dE/(2.*(1 + dnu)) - dG) >
171  std::numeric_limits<doublereal>::epsilon())
172  {
173  silent_cerr("Membrane isotropic constitutive law: inconsistent material data" << std::endl);
174  return -1;
175  }
176  } else {
177  if (!bGot_G) {
178  dG = dE/(2.*(1 + dnu));
179 
180  } else if (!bGot_E) {
181  dE = 2.*(1 + dnu)*dG;
182 
183  } else if (!bGot_nu) {
184  dnu = dE/(2.*dG) - 1.;
185  if (dnu <= 0. || dnu >= .5) {
186  silent_cerr("Membrane isotropic constitutive law: inconsistent material data (computed Poisson's modulus: " << dnu << ")" << std::endl);
187  return -1;
188  }
189  }
190  }
191 
192  if (!bGot_h) {
193  silent_cerr("Membrane isotropic constitutive law: shell thickness missing" << std::endl);
194  return -1;
195  }
196 
197  doublereal C = dE/(1. - dnu*dnu)*dh;
198  // doublereal D = C*dh*dh/12;
199  doublereal G = dG*dh;
200  // doublereal F = G*dh*dh/12;
201 
202  pD.Reset();
203 
204  pD(1, 1) = C;
205  pD(2, 2) = C;
206  pD(1, 2) = C*dnu;
207  pD(2, 1) = C*dnu;
208  pD(3, 3) = 2*G;
209 
210 /*
211  pD(1, 1) = C;
212  pD(1, 5) = C*dnu;
213  pD(2, 2) = 2*G;
214  pD(3, 3) = G*das;
215  pD(4, 4) = 2*G;
216  pD(5, 1) = C*dnu;
217  pD(5, 5) = C;
218  pD(6, 6) = G*das;
219 
220  pD(7, 7) = 2*F;
221  pD(8, 8) = D;
222  pD(8, 10) = -D*dnu;
223  pD(9, 9) = F*dat;
224  pD(10, 10) = D;
225  pD(10, 8) = -D*dnu;
226  pD(11, 11) = 2*F;
227  pD(12, 12) = F*dat;
228 */
229 
230  } else {
231  if (HP.IsKeyWord("matr")) {
232  // tolerate it
233  }
234 
235  for (unsigned ir = 1; ir <= 3; ir++) {
236  for (unsigned ic = 1; ic <= 3; ic++) {
237  pD(ir, ic) = HP.GetReal();
238  }
239  }
240  }
241 
242  if (HP.IsKeyWord("prestress")) {
243  ASSERT(PreStress.iGetSize() == 3);
244  for (unsigned ir = 1; ir <= 3; ir++) {
245  PreStress(ir) = HP.GetReal();
246  }
247  }
248 
249  return 0;
250 }
251 
long int flag
Definition: mbdyn.h:43
#define NO_OP
Definition: myassert.h:74
virtual ~Membrane(void)
Definition: membrane.cc:68
int ReadMembraneConstLaw(MBDynParser &HP, Membrane::fmh &pD, Membrane::vh &PreStress)
Definition: membrane.cc:74
virtual integer iGetSize(void) const
Definition: vh.h:255
virtual bool IsKeyWord(const char *sKeyWord)
Definition: parser.cc:910
#define ASSERT(expression)
Definition: colamd.c:977
Membrane(unsigned uLabel, const DofOwner *pDO, flag fOut)
Definition: membrane.cc:59
virtual integer iGetNumCols(void) const
Definition: fullmh.h:229
virtual bool IsArg(void)
Definition: parser.cc:807
Definition: elem.h:75
double doublereal
Definition: colamd.c:52
virtual HighParser::ErrOut GetLineData(void) const
Definition: parsinc.cc:697
virtual integer iGetNumRows(void) const
Definition: fullmh.h:225
void Reset(void)
Definition: fullmh.cc:44
virtual doublereal GetReal(const doublereal &dDefval=0.0)
Definition: parser.cc:1056