OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
structuralelementevaluator.C
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
35 #include "../sm/Elements/structuralelementevaluator.h"
36 #include "../sm/Elements/structuralelement.h"
37 #include "../sm/CrossSections/structuralcrosssection.h"
38 #include "../sm/Materials/structuralmaterial.h"
39 #include "../sm/Materials/structuralms.h"
40 #include "floatarray.h"
41 #include "floatmatrix.h"
42 #include "domain.h"
43 #include "node.h"
44 #include "gausspoint.h"
45 #include "gaussintegrationrule.h"
46 #include "matresponsemode.h"
47 #include "mathfem.h"
48 #include "iga/iga.h"
49 
50 namespace oofem {
52 {
53  this->rotationMatrix.clear();
54 }
55 
56 /*
57  * int StructuralElementEvaluator :: giveIntegrationElementCodeNumbers(IntArray &answer, Element *elem,
58  * IntegrationRule *ie) {
59  * int i;
60  * IntArray mask, nodeDofIDMask, nodalArray;
61  *
62  * // first evaluate nonzero basis function mask
63  * if ( elem->giveInterpolation()->hasSubPatchFormulation() ) {
64  * IGAIntegrationElement *ee = static_cast< IGAIntegrationElement * >( ie );
65  * elem->giveInterpolation()->giveKnotSpanBasisFuncMask(* ee->giveKnotSpan(), mask);
66  * // loop over nonzero shape functions and assemble localization array
67  * answer.clear();
68  * for ( i = 1; i <= mask.giveSize(); i++ ) {
69  * elem->giveDofManDofIDMask(mask.at(i), nodeDofIDMask);
70  * elem->giveDofManager( mask.at(i) )->giveLocationArray(nodeDofIDMask, nodalArray);
71  * answer.followedBy(nodalArray);
72  * }
73  *
74  * return 1;
75  * } else {
76  * return 0;
77  * }
78  * }
79  */
80 
82  IntegrationRule *ie)
83 {
84  int nsd;
85  IntArray mask, nodeDofIDMask, nodalArray;
86  int dofmandof;
87 
88  // get number of dofs in node
89  elem->giveDofManDofIDMask(1, nodeDofIDMask);
90  dofmandof = nodeDofIDMask.giveSize();
91 
92  nsd = elem->giveInterpolation()->giveNsd();
93 
94  // first evaluate nonzero basis function mask
95  if ( elem->giveInterpolation()->hasSubPatchFormulation() ) {
96  IGAIntegrationElement *ee = static_cast< IGAIntegrationElement * >(ie);
98  // loop over nonzero shape functions and assemble localization array
99  answer.clear();
100  for ( int i = 1; i <= mask.giveSize(); i++ ) {
101  nodalArray.resize( nodeDofIDMask.giveSize() );
102  for ( int j = 1; j <= nsd; j++ ) {
103  nodalArray.at(j) = dofmandof * ( mask.at(i) - 1 ) + j;
104  }
105 
106  answer.followedBy(nodalArray);
107  }
108 
109  return 1;
110  } else {
111  return 0;
112  }
113 }
114 
115 
117 {
118  if ( type == InternalForcesVector ) {
119  this->giveInternalForcesVector(answer, tStep, false);
120  } else if ( type == LastEquilibratedInternalForcesVector ) {
121  this->giveInternalForcesVector(answer, tStep, true);
122  } else {
123  answer.clear();
124  }
125 }
126 
127 
129  CharType mtrx, TimeStep *tStep)
130 //
131 // returns characteristics matrix of receiver according to mtrx
132 //
133 {
134  if ( mtrx == TangentStiffnessMatrix ) {
135  this->computeStiffnessMatrix(answer, TangentStiffness, tStep);
136  } else if ( mtrx == MassMatrix ) {
137  double mass;
138  this->computeConsistentMassMatrix(answer, tStep, mass);
139  } else if ( mtrx == LumpedMassMatrix ) {
140  this->computeLumpedMassMatrix(answer, tStep);
141  } else {
142  OOFEM_ERROR( "Unknown Type of characteristic mtrx (%s)", __CharTypeToString(mtrx) );
143  }
144 }
145 
146 
148 // Returns the lumped mass matrix of the receiver.
149 {
150  double mass;
151  Element *elem = this->giveElement();
152  int numberOfDofMans = elem->giveNumberOfDofManagers();
153  IntArray nodeDofIDMask, dimFlag(3);
154  int indx = 0, ldofs, dim;
155  double summ;
156 
157  if ( !this->isActivated(tStep) ) {
158  int ndofs = elem->computeNumberOfDofs();
159  answer.resize(ndofs, ndofs);
160  answer.zero();
161  return;
162  }
163 
164  this->computeConsistentMassMatrix(answer, tStep, mass);
165  ldofs = answer.giveNumberOfRows();
166 
167  for ( int i = 1; i <= numberOfDofMans; i++ ) {
168  elem->giveDofManDofIDMask(i, nodeDofIDMask);
169  for ( int j = 1; j <= nodeDofIDMask.giveSize(); j++ ) {
170  indx++;
171  // zero all off-diagonal terms
172  for ( int k = 1; k <= ldofs; k++ ) {
173  if ( k != indx ) {
174  answer.at(indx, k) = 0.;
175  answer.at(k, indx) = 0.;
176  }
177  }
178 
179  if ( ( nodeDofIDMask.at(j) != D_u ) && ( nodeDofIDMask.at(j) != D_v ) && ( nodeDofIDMask.at(j) != D_w ) ) {
180  // zero corresponding diagonal member too <= no displacement dof
181  answer.at(indx, indx) = 0.;
182  } else if ( nodeDofIDMask.at(j) == D_u ) {
183  dimFlag.at(1) = 1;
184  } else if ( nodeDofIDMask.at(j) == D_v ) {
185  dimFlag.at(2) = 1;
186  } else if ( nodeDofIDMask.at(j) == D_w ) {
187  dimFlag.at(3) = 1;
188  }
189  }
190  }
191 
192  if ( indx != ldofs ) {
193  OOFEM_ERROR("internal consistency check failed");
194  }
195 
196  dim = dimFlag.at(1) + dimFlag.at(2) + dimFlag.at(3);
197  summ = 0.;
198  for ( int k = 1; k <= ldofs; k++ ) {
199  summ += answer.at(k, k);
200  }
201 
202  answer.times(dim * mass / summ);
203 }
204 
205 
207 // Computes numerically the consistent (full) mass matrix of the receiver.
208 {
209  //Element *elem = this->giveElement();
210  StructuralElement *elem = static_cast< StructuralElement * >( this->giveElement() );
211  int ndofs = elem->computeNumberOfDofs();
212  FloatMatrix n;
213  IntegrationRule *iRule;
214  IntArray mask;
215 
216  answer.resize(ndofs, ndofs);
217  answer.zero();
218  if ( !this->isActivated(tStep) ) {
219  return;
220  }
221 
222  if ( ( iRule = this->giveMassMtrxIntegrationRule() ) ) {
223  OOFEM_ERROR("no integration rule available");
224  }
225 
226  this->giveMassMtrxIntegrationMask(mask);
227 
228  mass = 0.;
229 
230  for ( GaussPoint *gp: *iRule ) {
231  double density = elem->giveStructuralCrossSection()->give('d', gp);
232  double dV = this->computeVolumeAround(gp);
233  mass += density * dV;
234  this->computeNMatrixAt(n, gp);
235 
236  if ( mask.isEmpty() ) {
237  answer.plusProductSymmUpper(n, n, density * dV);
238  } else {
239  for ( int i = 1; i <= ndofs; i++ ) {
240  for ( int j = i; j <= ndofs; j++ ) {
241  double summ = 0.;
242  for ( int k = 1; k <= n.giveNumberOfRows(); k++ ) {
243  if ( mask.at(k) == 0 ) {
244  continue;
245  }
246 
247  summ += n.at(k, i) * n.at(k, j);
248  }
249 
250  answer.at(i, j) += summ * density * dV;
251  }
252  }
253  }
254  }
255 
256  answer.symmetrized();
257 }
258 
259 
260 void StructuralElementEvaluator :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, bool useUpdatedGpRecord)
261 {
262  Element *elem = this->giveElement();
263  int ndofs = elem->computeNumberOfDofs();
264  FloatMatrix b;
265  FloatArray strain, stress, u, temp;
266  IntArray irlocnum;
267 
268  elem->computeVectorOf(VM_Total, tStep, u);
269 
270  answer.resize(ndofs);
271  answer.zero();
272  FloatArray *m = & answer;
273  if ( elem->giveInterpolation()->hasSubPatchFormulation() ) {
274  m = & temp;
275  }
276 
277  int numberOfIntegrationRules = elem->giveNumberOfIntegrationRules();
278  // loop over individual integration rules
279  for ( int ir = 0; ir < numberOfIntegrationRules; ir++ ) {
280  m->clear();
281  IntegrationRule *iRule = elem->giveIntegrationRule(ir);
282  for ( GaussPoint *gp: *iRule ) {
283  this->computeBMatrixAt(b, gp);
284  if ( useUpdatedGpRecord ) {
285  stress = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveStressVector();
286  } else {
287  this->computeStrainVector(strain, gp, tStep, u);
288  this->computeStressVector(stress, strain, gp, tStep);
289  }
290 
291  if ( stress.giveSize() == 0 ) {
292  break;
293  }
294 
295  // compute nodal representation of internal forces using f = B^T*Sigma dV
296  double dV = this->computeVolumeAround(gp);
297  m->plusProduct(b, stress, dV);
298  }
299  // localize irule contribution into element matrix
300  if ( this->giveIntegrationElementLocalCodeNumbers(irlocnum, elem, iRule) ) {
301  answer.assemble(* m, irlocnum);
302  }
303  } // end loop over irules
304 
305  // if inactive update state, but no contribution to global system
306  if ( !this->isActivated(tStep) ) {
307  answer.zero();
308  }
309 }
310 
311 
313 // Computes the vector containing the strains at the Gauss point gp of
314 // the receiver, at time step tStep. The nature of these strains depends
315 // on the element's type.
316 {
317  FloatMatrix b;
318  FloatArray ur;
319  Element *elem = this->giveElement();
320 
321  if ( !this->isActivated(tStep) ) {
323  answer.zero();
324  return;
325  }
326 
327  this->computeBMatrixAt(b, gp);
328 
329  // get local code numbers corresponding to ir
330  IntArray lc;
332  ur.resize( b.giveNumberOfColumns() );
333  for ( int i = 1; i <= lc.giveSize(); i++ ) {
334  ur.at(i) = u.at( lc.at(i) );
335  }
336 
337  answer.beProductOf(b, ur);
338 }
339 
341 // Updates the receiver at end of step.
342 {
343  FloatArray u;
344  Element *elem = this->giveElement();
345 
346  elem->computeVectorOf(VM_Total, tStep, u);
347 
348 #if 0
349  // subtract initial displacements, if defined
350  if ( initialDisplacements ) {
351  u.subtract(initialDisplacements);
352  }
353 #endif
354 
355  FloatArray strain, stress;
356 
357  // force updating strains & stresses
358  for ( int i = 0; i < elem->giveNumberOfIntegrationRules(); i++ ) {
359 #ifdef __PARALLEL_MODE
360  if ( this->giveElement()->giveKnotSpanParallelMode(i) == Element_remote ) {
361  continue;
362  }
363 #endif
364  for ( GaussPoint *gp: *elem->giveIntegrationRule(i) ) {
365  this->computeStrainVector(strain, gp, tStep, u);
366  this->computeStressVector(stress, strain, gp, tStep);
367  }
368  }
369 }
370 
371 
373 {
374  int numberOfIntegrationRules;
375  FloatMatrix temp, bj, d, dbj;
376  Element *elem = this->giveElement();
377  StructuralCrossSection *cs = static_cast< StructuralCrossSection * >( elem->giveCrossSection() );
378  int ndofs = elem->computeNumberOfDofs();
379  bool matStiffSymmFlag = cs->isCharacteristicMtrxSymmetric(rMode);
380  IntArray irlocnum;
381 
382  answer.resize(ndofs, ndofs);
383  answer.zero();
384 
385  FloatMatrix *m = & answer;
386  if ( elem->giveInterpolation()->hasSubPatchFormulation() ) {
387  m = & temp;
388  }
389 
390  numberOfIntegrationRules = elem->giveNumberOfIntegrationRules();
391  // loop over individual integration rules
392  for ( int ir = 0; ir < numberOfIntegrationRules; ir++ ) {
393 #ifdef __PARALLEL_MODE
394  if ( this->giveElement()->giveKnotSpanParallelMode(ir) == Element_remote ) {
395  continue;
396  }
397  //fprintf (stderr, "[%d] Computing element.knotspan %d.%d\n", elem->giveDomain()->giveEngngModel()->giveRank(), elem->giveNumber(), ir);
398 #endif
399  m->clear();
400  IntegrationRule *iRule = elem->giveIntegrationRule(ir);
401  // loop over individual integration points
402  for ( GaussPoint *gp: *iRule ) {
403  double dV = this->computeVolumeAround(gp);
404  this->computeBMatrixAt(bj, gp);
405  this->computeConstitutiveMatrixAt(d, rMode, gp, tStep);
406 
407  dbj.beProductOf(d, bj);
408  if ( matStiffSymmFlag ) {
409  m->plusProductSymmUpper(bj, dbj, dV);
410  } else {
411  m->plusProductUnsym(bj, dbj, dV);
412  }
413  }
414 
415  if ( matStiffSymmFlag ) {
416  m->symmetrized();
417  }
418 
419  // localize irule contribution into element matrix
420  if ( this->giveIntegrationElementLocalCodeNumbers(irlocnum, elem, iRule) ) {
421  answer.assemble(* m, irlocnum);
422  }
423  } // end loop over irules
424 }
425 } // end namespace oofem
static int giveSizeOfVoigtSymVector(MaterialMode mmode)
Returns the size of symmetric part of a reduced stress/strain vector according to given mode...
CrossSection * giveCrossSection()
Definition: element.C:495
MaterialMode giveMaterialMode()
Returns corresponding material mode of receiver.
Definition: gausspoint.h:191
int giveNumberOfColumns() const
Returns number of columns of receiver.
Definition: floatmatrix.h:158
void subtract(const FloatArray &src)
Subtracts array src to receiver.
Definition: floatarray.C:258
virtual IntegrationRule * giveMassMtrxIntegrationRule()
Returns the integration rule for mass matrices, if relevant.
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Returns local vector of unknowns.
Definition: element.C:86
virtual int computeNumberOfDofs()
Computes or simply returns total number of element&#39;s local DOFs.
Definition: element.h:424
virtual IntegrationRule * giveIntegrationRule(int i)
Definition: element.h:835
virtual void computeNMatrixAt(FloatMatrix &answer, GaussPoint *gp)=0
Computes the matrix for which the unknown field is obtained, typically [N1, 0, N2, 0, ...; 0, N1, 0, N2, ...].
virtual void computeLumpedMassMatrix(FloatMatrix &answer, TimeStep *tStep)
Computes lumped mass matrix of receiver.
bool isEmpty() const
Checks if receiver is empty (i.e., zero sized).
Definition: intarray.h:208
virtual void giveCharacteristicVector(FloatArray &answer, CharType type, ValueModeType mode, TimeStep *tStep)
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
ValueModeType
Type representing the mode of UnknownType or CharType, or similar types.
Definition: valuemodetype.h:78
This class implements a structural material status information.
Definition: structuralms.h:65
void clear()
Clears receiver (zero size).
Definition: floatarray.h:206
virtual void giveDofManDofIDMask(int inode, IntArray &answer) const
Returns dofmanager dof mask for node.
Definition: element.h:476
Abstract base class for all finite elements.
Definition: element.h:145
virtual int giveIntegrationElementLocalCodeNumbers(IntArray &answer, Element *elem, IntegrationRule *ie)
Assembles the local element code numbers of given integration element (sub-patch) This is done by obt...
void computeStrainVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep, FloatArray &u)
Optimized version, allowing to pass element displacements as parameter.
virtual int giveKnotSpanBasisFuncMask(const IntArray &knotSpan, IntArray &mask)
Returns indices (zero based) of nonzero basis functions for given knot span.
Definition: feinterpol.h:444
virtual void computeConsistentMassMatrix(FloatMatrix &answer, TimeStep *tStep, double &mass)
Computes consistent mass matrix of receiver using numerical integration over element volume...
virtual double computeVolumeAround(GaussPoint *gp)
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
MatResponseMode
Describes the character of characteristic material matrix.
virtual int giveNumberOfDofManagers() const
Definition: element.h:656
virtual Element * giveElement()=0
virtual FEInterpolation * giveInterpolation() const
Definition: element.h:629
virtual void computeStressVector(FloatArray &answer, const FloatArray &strain, GaussPoint *gp, TimeStep *tStep)=0
Computes the stress vector.
Abstract base class representing integration rule.
virtual void giveCharacteristicMatrix(FloatMatrix &answer, CharType mtrx, TimeStep *tStep)
int giveNumberOfIntegrationRules()
Definition: element.h:830
void plusProductUnsym(const FloatMatrix &a, const FloatMatrix &b, double dV)
Adds to the receiver the product .
Definition: floatmatrix.C:780
Abstract base class for all "structural" finite elements.
virtual void computeConstitutiveMatrixAt(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep)=0
Computes constitutive matrix of receiver.
virtual bool isCharacteristicMtrxSymmetric(MatResponseMode mode)=0
Check for symmetry of stiffness matrix.
virtual void computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
const IntArray * giveKnotSpan()
Returns receiver sub patch indices (if apply).
Definition: iga.h:88
#define OOFEM_ERROR(...)
Definition: error.h:61
void clear()
Clears the array (zero size).
Definition: intarray.h:177
StructuralCrossSection * giveStructuralCrossSection()
Helper function which returns the structural cross-section for the element.
void times(double f)
Multiplies receiver by factor f.
Definition: floatmatrix.C:1594
const char * __CharTypeToString(CharType _value)
Definition: cltypes.C:339
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
virtual bool hasSubPatchFormulation()
Returns true, if receiver is formulated on sub-patch basis.
Definition: feinterpol.h:453
void plusProductSymmUpper(const FloatMatrix &a, const FloatMatrix &b, double dV)
Adds to the receiver the product .
Definition: floatmatrix.C:698
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
IntegrationRule * giveIntegrationRule()
Returns corresponding integration rule to receiver.
Definition: gausspoint.h:186
virtual void giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, bool useUpdatedGpRecord=false)
Class representing vector of real numbers.
Definition: floatarray.h:82
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
virtual double give(CrossSectionProperty a, GaussPoint *gp)
Returns the value of cross section property at given point.
Definition: crosssection.C:151
void assemble(const FloatArray &fe, const IntArray &loc)
Assembles the array fe (typically, the load vector of a finite element) into the receiver, using loc as location array.
Definition: floatarray.C:551
CharType
Definition: chartype.h:87
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
void followedBy(const IntArray &b, int allocChunk=0)
Appends array b at the end of receiver.
Definition: intarray.C:145
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
virtual void giveMassMtrxIntegrationMask(IntArray &answer)
Returns mask indicating, which unknowns (their type and ordering is the same as element unknown vecto...
virtual elementParallelMode giveKnotSpanParallelMode(int) const
Returns the parallel mode for particular knot span of the receiver.
Definition: element.h:1076
Element in active domain is only mirror of some remote element.
Definition: element.h:102
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
IntegrationElement represent nonzero knot span, derived from Integration Rule.
Definition: iga.h:80
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:337
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
Abstract base class for all structural cross section models.
the oofem namespace is to define a context or scope in which all oofem names are defined.
void assemble(const FloatMatrix &src, const IntArray &loc)
Assembles the contribution using localization array into receiver.
Definition: floatmatrix.C:251
void clear()
Sets size of receiver to be an empty matrix. It will have zero rows and zero columns size...
Definition: floatmatrix.h:516
int giveNumberOfRows() const
Returns number of rows of receiver.
Definition: floatmatrix.h:156
void symmetrized()
Initializes the lower half of the receiver according to the upper half.
Definition: floatmatrix.C:1576
Class representing integration point in finite element program.
Definition: gausspoint.h:93
Class representing solution step.
Definition: timestep.h:80
virtual void computeBMatrixAt(FloatMatrix &answer, GaussPoint *gp)=0
virtual int giveNsd()=0
Returns number of spatial dimensions.
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631
void plusProduct(const FloatMatrix &b, const FloatArray &s, double dV)
Adds the product .
Definition: floatarray.C:226

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:31 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011