OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
quad1mindlinshell3d.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/Shells/quad1mindlinshell3d.h"
36 #include "../sm/Materials/structuralms.h"
37 #include "../sm/CrossSections/structuralcrosssection.h"
38 #include "../sm/Loads/constantpressureload.h"
39 #include "node.h"
40 #include "material.h"
41 #include "crosssection.h"
42 #include "gausspoint.h"
43 #include "gaussintegrationrule.h"
44 #include "floatmatrix.h"
45 #include "floatarray.h"
46 #include "intarray.h"
47 #include "load.h"
48 #include "mathfem.h"
49 #include "fei2dquadlin.h"
50 #include "classfactory.h"
51 
52 namespace oofem {
53 REGISTER_Element(Quad1MindlinShell3D);
54 
55 FEI2dQuadLin Quad1MindlinShell3D :: interp(1, 2);
56 IntArray Quad1MindlinShell3D :: shellOrdering = { 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23};
57 IntArray Quad1MindlinShell3D :: drillOrdering = { 6, 12, 18, 24};
58 
62  lnodes(4)
63 {
65  this->numberOfDofMans = 4;
66  this->reducedIntegrationFlag = false;
67 }
68 
69 
71 {
72 }
73 
74 
77 {
78  return & interp;
79 }
80 
81 
84 {
85  return & interp;
86 }
87 
88 
89 void
91 // Sets up the array containing the four Gauss points of the receiver.
92 {
93  if ( integrationRulesArray.size() == 0 ) {
94  integrationRulesArray.resize( 1 );
95  integrationRulesArray [ 0 ].reset( new GaussIntegrationRule(1, this, 1, 5) );
97  }
99  this->computeLCS();
100 }
101 
102 
103 void
105 {
106  // Only gravity load
107  double dV, density;
108  FloatArray forceX, forceY, forceZ, glob_gravity, gravity, n;
109 
110  if ( ( forLoad->giveBCGeoType() != BodyLoadBGT ) || ( forLoad->giveBCValType() != ForceLoadBVT ) ) {
111  OOFEM_ERROR("unknown load type");
112  }
113 
114  // note: force is assumed to be in global coordinate system.
115  forLoad->computeComponentArrayAt(glob_gravity, tStep, mode);
116  // Transform the load into the local c.s.
117  gravity.beProductOf(this->lcsMatrix, glob_gravity);
118 
119  if ( gravity.giveSize() ) {
120  for ( GaussPoint *gp: *integrationRulesArray [ 0 ] ) {
121 
122  this->interp.evalN( n, gp->giveNaturalCoordinates(), FEIVoidCellGeometry() );
123  dV = this->computeVolumeAround(gp) * this->giveCrossSection()->give(CS_Thickness, gp);
124  density = this->giveStructuralCrossSection()->give('d', gp);
125 
126  forceX.add(density * gravity.at(1) * dV, n);
127  forceY.add(density * gravity.at(2) * dV, n);
128  forceZ.add(density * gravity.at(3) * dV, n);
129  }
130 
131  answer.resize(24);
132  answer.zero();
133 
134  answer.at(1) = forceX.at(1);
135  answer.at(2) = forceY.at(1);
136  answer.at(3) = forceZ.at(1);
137 
138  answer.at(7) = forceX.at(2);
139  answer.at(8) = forceY.at(2);
140  answer.at(9) = forceZ.at(2);
141 
142  answer.at(13) = forceX.at(3);
143  answer.at(14) = forceY.at(3);
144  answer.at(15) = forceZ.at(3);
145 
146  answer.at(19) = forceX.at(4);
147  answer.at(20) = forceY.at(4);
148  answer.at(21) = forceZ.at(4);
149  } else {
150  answer.clear();
151  }
152 }
153 
154 /*
155 void
156 Quad1MindlinShell3D :: computeSurfaceLoadVectorAt(FloatArray &answer, Load *load,
157  int iSurf, TimeStep *tStep, ValueModeType mode)
158 {
159  BoundaryLoad *surfLoad = static_cast< BoundaryLoad * >(load);
160  if ( dynamic_cast< ConstantPressureLoad * >(surfLoad) ) { // Just checking the type of b.c.
161  // EXPERIMENTAL CODE:
162  FloatArray n, gcoords, pressure;
163 
164  answer.resize(24);
165  answer.zero();
166 
167  for ( GaussPoint *gp: *integrationRulesArray [ 0 ] ) {
168  double dV = this->computeVolumeAround(gp);
169  this->interp.evalN( n, gp->giveNaturalCoordinates(), FEIVoidCellGeometry() );
170  this->interp.local2global( gcoords, gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(this) );
171  surfLoad->computeValueAt(pressure, tStep, gcoords, mode);
172 
173  answer.at(3) += n.at(1) * pressure.at(1) * dV;
174  answer.at(9) += n.at(2) * pressure.at(1) * dV;
175  answer.at(15) += n.at(3) * pressure.at(1) * dV;
176  answer.at(21) += n.at(4) * pressure.at(1) * dV;
177  }
178  // Second surface is the outside;
179  if ( iSurf == 2 ) {
180  answer.negated();
181  }
182  } else {
183  OOFEM_ERROR("only supports constant pressure boundary load.");
184  }
185 }
186 */
187 
188 void
190 {
191  FloatArray n, ns;
192  FloatMatrix dn, dns;
193  const FloatArray &localCoords = gp->giveNaturalCoordinates();
194 
195  this->interp.evaldNdx( dn, localCoords, FEIVertexListGeometryWrapper(lnodes) );
196  this->interp.evalN( n, localCoords, FEIVoidCellGeometry() );
197 
198  answer.resize(8, 4 * 5);
199  answer.zero();
200 
201  // enforce one-point reduced integration if requested
202  if ( this->reducedIntegrationFlag ) {
203  FloatArray lc(2);
204  lc.zero(); // set to element center coordinates
205 
207  this->interp.evalN( ns, lc, FEIVoidCellGeometry() );
208  } else {
209  dns = dn;
210  ns = n;
211  }
212 
213 
214  // Note: This is just 5 dofs (sixth column is all zero, torsional stiffness handled separately.)
215  for ( int i = 0; i < 4; ++i ) {
217  // Part related to the membrane (columns represent coefficients for D_u, D_v)
218  answer(0, 0 + i * 5) = dn(i, 0);//eps_x = du/dx
219  answer(1, 1 + i * 5) = dn(i, 1);//eps_y = dv/dy
220  answer(2, 0 + i * 5) = dn(i, 1);//gamma_xy = du/dy+dv/dx
221  answer(2, 1 + i * 5) = dn(i, 0);
222 
223  // Part related to the plate (columns represent the dofs D_w, R_u, R_v)
225  answer(3 + 0, 2 + 2 + i * 5) = dn(i, 0);// kappa_x = d(fi_y)/dx
226  answer(3 + 1, 2 + 1 + i * 5) =-dn(i, 1);// kappa_y = -d(fi_x)/dy
227  answer(3 + 2, 2 + 2 + i * 5) = dn(i, 1);// kappa_xy=d(fi_y)/dy-d(fi_x)/dx
228  answer(3 + 2, 2 + 1 + i * 5) =-dn(i, 0);
229 
230  // shear strains
231  answer(3 + 3, 2 + 0 + i * 5) = dns(i, 0);// gamma_xz = fi_y+dw/dx
232  answer(3 + 3, 2 + 2 + i * 5) = ns(i);
233  answer(3 + 4, 2 + 0 + i * 5) = dns(i, 1);// gamma_yz = -fi_x+dw/dy
234  answer(3 + 4, 2 + 1 + i * 5) = -ns(i);
235  }
236 
237 
238 #if 0
239  // Experimental MITC4 support.
240  // Based on "Short communication A four-node plate bending element based on mindling/reissner plate theory and a mixed interpolation"
241  // KJ Bathe, E Dvorkin
242 
243  double x1, x2, x3, x4;
244  double y1, y2, y3, y4;
245  double Ax, Bx, Cx, Ay, By, Cy;
246 
247  double r = localCoords[0];
248  double s = localCoords[1];
249 
250  x1 = lnodes[0][0];
251  x2 = lnodes[1][0];
252  x3 = lnodes[2][0];
253  x4 = lnodes[3][0];
254 
255  y1 = lnodes[0][1];
256  y2 = lnodes[1][1];
257  y3 = lnodes[2][1];
258  y4 = lnodes[3][1];
259 
260  Ax = x1 - x2 - x3 + x4;
261  Bx = x1 - x2 + x3 - x4;
262  Cx = x1 + x2 - x3 - x4;
263 
264  Ay = y1 - y2 - y3 + y4;
265  By = y1 - y2 + y3 - y4;
266  Cy = y1 + y2 - y3 - y4;
267 
268  FloatMatrix jac;
270  double detJ = jac.giveDeterminant();
271 
272  double rz = sqrt( sqr(Cx + r*Bx) + sqr(Cy + r*By)) / ( 16 * detJ );
273  double sz = sqrt( sqr(Ax + s*Bx) + sqr(Ay + s*By)) / ( 16 * detJ );
274 
275  // TODO: Not sure about this part (the reference is not explicit about these angles. / Mikael
276  // Not sure about the transpose either.
277  OOFEM_WARNING("The MITC4 implementation isn't verified yet. Highly experimental");
278  FloatArray dxdr = {jac(0,0), jac(0,1)};
279  dxdr.normalize();
280  FloatArray dxds = {jac(1,0), jac(1,1)};
281  dxds.normalize();
282 
283  double c_b = dxdr(0); //cos(beta);
284  double s_b = dxdr(1); //sin(beta);
285  double c_a = dxds(0); //cos(alpha);
286  double s_a = dxds(1); //sin(alpha);
287 
288  // gamma_xz = "fi_y+dw/dx" in standard formulation
289  answer(6, 2 + 5*0) = rz * s_b * ( (1+s)) - sz * s_a * ( (1+r));
290  answer(6, 2 + 5*1) = rz * s_b * (-(1+s)) - sz * s_a * ( (1-r));
291  answer(6, 2 + 5*2) = rz * s_b * (-(1-s)) - sz * s_a * (-(1-r));
292  answer(6, 2 + 5*3) = rz * s_b * ( (1-s)) - sz * s_a * (-(1+r));
293 
294  answer(6, 3 + 5*0) = rz * s_b * (y2-y1) * 0.5 * (1+s) - sz * s_a * (y4-y1) * 0.5 * (1+r); // tx1
295  answer(6, 4 + 5*0) = rz * s_b * (x1-x2) * 0.5 * (1+s) - sz * s_a * (x1-x4) * 0.5 * (1+r); // ty1
296 
297  answer(6, 3 + 5*1) = rz * s_b * (y2-y1) * 0.5 * (1+s) - sz * s_a * (y3-x2) * 0.5 * (1+r); // tx2
298  answer(6, 4 + 5*1) = rz * s_b * (x1-x2) * 0.5 * (1+s) - sz * s_a * (x2-x3) * 0.5 * (1+r); // ty2
299 
300  answer(6, 3 + 5*2) = rz * s_b * (y3-y4) * 0.5 * (1-s) - sz * s_a * (y3-y2) * 0.5 * (1-r); // tx3
301  answer(6, 4 + 5*2) = rz * s_b * (x4-x3) * 0.5 * (1-s) - sz * s_a * (x2-x3) * 0.5 * (1-r); // ty3
302 
303  answer(6, 3 + 5*3) = rz * s_b * (y3-y4) * 0.5 * (1-s) - sz * s_a * (y4-y1) * 0.5 * (1-r); // tx4
304  answer(6, 4 + 5*3) = rz * s_b * (x4-x3) * 0.5 * (1-s) - sz * s_a * (x1-x4) * 0.5 * (1-r); // ty4
305 
306  // gamma_yz = -fi_x+dw/dy in standard formulation
307  answer(7, 2 + 5*0) = - rz * c_b * ( (1+s)) + sz * c_a * ( (1+r));
308  answer(7, 2 + 5*1) = - rz * c_b * (-(1+s)) + sz * c_a * ( (1-r));
309  answer(7, 2 + 5*2) = - rz * c_b * (-(1-s)) + sz * c_a * (-(1-r));
310  answer(7, 2 + 5*3) = - rz * c_b * ( (1-s)) + sz * c_a * (-(1+r));
311 
312  answer(7, 3 + 5*0) = - rz * c_b * (y2-y1) * 0.5 * (1+s) + sz * c_a * (y4-y1) * 0.5 * (1+r); // tx1
313  answer(7, 4 + 5*0) = - rz * c_b * (x1-x2) * 0.5 * (1+s) + sz * c_a * (x1-x4) * 0.5 * (1+r); // ty1
314 
315  answer(7, 3 + 5*1) = - rz * c_b * (y2-y1) * 0.5 * (1+s) + sz * c_a * (y3-x2) * 0.5 * (1+r); // tx2
316  answer(7, 4 + 5*1) = - rz * c_b * (x1-x2) * 0.5 * (1+s) + sz * c_a * (x2-x3) * 0.5 * (1+r); // ty2
317 
318  answer(7, 3 + 5*2) = - rz * c_b * (y3-y4) * 0.5 * (1-s) + sz * c_a * (y3-y2) * 0.5 * (1-r); // tx3
319  answer(7, 4 + 5*2) = - rz * c_b * (x4-x3) * 0.5 * (1-s) + sz * c_a * (x2-x3) * 0.5 * (1-r); // ty3
320 
321  answer(7, 3 + 5*3) = - rz * c_b * (y3-y4) * 0.5 * (1-s) + sz * c_a * (y4-y1) * 0.5 * (1-r); // tx4
322  answer(7, 4 + 5*3) = - rz * c_b * (x4-x3) * 0.5 * (1-s) + sz * c_a * (x1-x4) * 0.5 * (1-r); // ty4
323 #endif
324 }
325 
326 
327 void
329 {
330  this->giveStructuralCrossSection()->giveGeneralizedStress_Shell(answer, gp, strain, tStep);
331 }
332 
333 
334 void
336 {
337  this->giveStructuralCrossSection()->give3dShellStiffMtrx(answer, rMode, gp, tStep);
338 }
339 
340 
341 void
343 {
344  FloatArray tmp;
345  this->computeVectorOf(mode, tStep, tmp);
346  shell.beSubArrayOf(tmp, this->shellOrdering);
347  drill.beSubArrayOf(tmp, this->drillOrdering);
348 }
349 
350 
351 void
353 {
354  FloatArray shellUnknowns, tmp;
355  FloatMatrix b;
356  /* Here we do compute only the "traditional" part of shell strain vector, the quasi-strain related to rotations is not computed */
357  this->computeVectorOfUnknowns(VM_Total, tStep, shellUnknowns, tmp);
358 
359  this->computeBmatrixAt(gp, b);
360  answer.beProductOf(b, shellUnknowns);
361 }
362 
363 
364 void
366 {
367  // We need to overload this for practical reasons (this 3d shell has all 9 dofs, but the shell part only cares for the first 8)
368  // This elements adds an additional stiffness for the so called drilling dofs, meaning we need to work with all 9 components.
369  FloatMatrix b;
370  FloatArray n, strain, stress;
371  FloatArray shellUnknowns, drillUnknowns;
372  bool drillCoeffFlag = false;
373 
374  // Split this for practical reasons into normal shell dofs and drilling dofs
375  this->computeVectorOfUnknowns(VM_Total, tStep, shellUnknowns, drillUnknowns);
376 
377  FloatArray shellForces, drillMoment;
379 
380  for ( GaussPoint *gp: *integrationRulesArray [ 0 ] ) {
381  this->computeBmatrixAt(gp, b);
382  double dV = this->computeVolumeAround(gp);
383  double drillCoeff = cs->give(CS_DrillingStiffness, gp);
384 
385  if ( useUpdatedGpRecord ) {
386  stress = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveStressVector();
387  } else {
388  strain.beProductOf(b, shellUnknowns);
389  cs->giveGeneralizedStress_Shell(stress, gp, strain, tStep);
390  }
391  shellForces.plusProduct(b, stress, dV);
392 
393  // Drilling stiffness is here for improved numerical properties
394  if ( drillCoeff > 0. ) {
395  this->interp.evalN( n, gp->giveNaturalCoordinates(), FEIVoidCellGeometry() );
396  for ( int j = 0; j < 4; j++ ) {
397  n(j) -= 0.25;
398  }
399  double dtheta = n.dotProduct(drillUnknowns);
400  drillMoment.add(drillCoeff * dV * dtheta, n);
401  drillCoeffFlag = true;
402  }
403  }
404 
405  answer.resize(24);
406  answer.zero();
407  answer.assemble(shellForces, this->shellOrdering);
408 
409  if ( drillCoeffFlag ) {
410  answer.assemble(drillMoment, this->drillOrdering);
411  }
412 }
413 
414 
415 void
417 {
418  // We need to overload this for practical reasons (this 3d shell has all 9 dofs, but the shell part only cares for the first 8)
419  // This elements adds an additional stiffness for the so called drilling dofs, meaning we need to work with all 9 components.
420  FloatMatrix d, b, db;
421  FloatArray n;
422  bool drillCoeffFlag = false;
423 
424  FloatMatrix shellStiffness, drillStiffness;
425 
426  for ( GaussPoint *gp: *integrationRulesArray [ 0 ] ) {
427  this->computeBmatrixAt(gp, b);
428  double dV = this->computeVolumeAround(gp);
429  double drillCoeff = this->giveStructuralCrossSection()->give(CS_DrillingStiffness, gp);
430 
431  this->computeConstitutiveMatrixAt(d, rMode, gp, tStep);
432 
433  db.beProductOf(d, b);
434  shellStiffness.plusProductSymmUpper(b, db, dV);
435 
436  // Drilling stiffness is here for improved numerical properties
437  if ( drillCoeff > 0. ) {
438  this->interp.evalN( n, gp->giveNaturalCoordinates(), FEIVoidCellGeometry() );
439  for ( int j = 0; j < 4; j++ ) {
440  n(j) -= 0.25;
441  }
442  drillStiffness.plusDyadSymmUpper(n, drillCoeff * dV);
443  drillCoeffFlag = true;
444  }
445  }
446  shellStiffness.symmetrized();
447 
448  answer.resize(24, 24);
449  answer.zero();
450  answer.assemble(shellStiffness, this->shellOrdering);
451 
452  if ( drillCoeffFlag ) {
453  drillStiffness.symmetrized();
454  answer.assemble(drillStiffness, this->drillOrdering);
455  }
456 }
457 
458 
461 {
464 }
465 
466 
467 void
469 {
470  answer = {D_u, D_v, D_w, R_u, R_v, R_w};
471 }
472 
473 
474 void
476 {
477  FloatArray u, v;
478  u.beDifferenceOf( * this->giveNode(2)->giveCoordinates(), * this->giveNode(1)->giveCoordinates() );
479  v.beDifferenceOf( * this->giveNode(3)->giveCoordinates(), * this->giveNode(1)->giveCoordinates() );
480 
481  answer.beVectorProductOf(u, v);
482  answer.normalize();
483 }
484 
485 
486 double
488 {
489  return this->giveLengthInDir(normalToCrackPlane);
490 }
491 
492 
493 double
495 {
496  double detJ, weight;
497 
498  weight = gp->giveWeight();
500  return detJ * weight;
501 }
502 
503 
504 void
506 // Returns the lumped mass matrix of the receiver.
507 {
508  double mass = 0.;
509 
510  for ( GaussPoint *gp: *integrationRulesArray [ 0 ] ) {
511  mass += this->computeVolumeAround(gp) * this->giveStructuralCrossSection()->give('d', gp);
512  }
513 
514  answer.resize(24, 24);
515  answer.zero();
516  for ( int i = 0; i < 4; i++ ) {
517  answer(i * 6 + 0, i * 6 + 0) = mass * 0.25;
518  answer(i * 6 + 1, i * 6 + 1) = mass * 0.25;
519  answer(i * 6 + 2, i * 6 + 2) = mass * 0.25;
520  }
521 }
522 
523 
524 int
526 {
527  FloatArray help;
528  answer.resize(6);
529  if ( type == IST_ShellForceTensor || type == IST_ShellStrainTensor ) {
530  if ( type == IST_ShellForceTensor ) {
531  help = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveStressVector();
532  } else {
533  help = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveStrainVector();
534  }
535  answer.at(1) = help.at(1); // nx
536  answer.at(2) = help.at(2); // ny
537  answer.at(3) = 0.0; // nz
538  answer.at(4) = help.at(8); // vyz
539  answer.at(5) = help.at(7); // vxy
540  answer.at(6) = help.at(3); // vxy
541  return 1;
542  } else if ( type == IST_ShellMomentTensor || type == IST_CurvatureTensor ) {
543  if ( type == IST_ShellMomentTensor ) {
544  help = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveStressVector();
545  } else {
546  help = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveStrainVector();
547  }
548  answer.at(1) = help.at(4); // mx
549  answer.at(2) = help.at(5); // my
550  answer.at(3) = 0.0; // mz
551  answer.at(4) = 0.0; // mzy
552  answer.at(5) = 0.0; // mzx
553  answer.at(6) = help.at(6); // mxy
554  return 1;
555  } else {
556  return NLStructuralElement :: giveIPValue(answer, gp, type, tStep);
557  }
558 }
559 
560 
561 void
563 {
564  if ( iEdge == 1 ) { // edge between nodes 1 2
565  answer = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
566  } else if ( iEdge == 2 ) { // edge between nodes 2 3
567  answer = { 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
568  } else if ( iEdge == 3 ) { // edge between nodes 3 4
569  answer = {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
570  } else if ( iEdge == 4 ) { // edge between nodes 4 1
571  answer = {19, 20, 21, 22, 23, 24, 1, 2, 3, 4, 5, 6};
572  } else {
573  OOFEM_ERROR("wrong edge number");
574  }
575 }
576 
577 
578 double
580 {
582  return detJ *gp->giveWeight();
583 }
584 
585 /*
586 void
587 Quad1MindlinShell3D :: computeEdgeIpGlobalCoords(FloatArray &answer, GaussPoint *gp, int iEdge)
588 {
589  FloatArray local;
590  this->interp.edgeLocal2global( local, iEdge, gp->giveNaturalCoordinates(), FEIVertexListGeometryWrapper(lnodes) );
591  local.resize(3);
592  local.at(3) = 0.;
593  answer.beProductOf(this->lcsMatrix, local);
594 }
595 */
596 
597 int
599 {
600  double dx, dy, length;
601  IntArray edgeNodes;
602  Node *nodeA, *nodeB;
603 
604  answer.resize(3, 3);
605  answer.zero();
606 
607  this->interp.computeLocalEdgeMapping(edgeNodes, iEdge);
608 
609  nodeA = this->giveNode( edgeNodes.at(1) );
610  nodeB = this->giveNode( edgeNodes.at(2) );
611 
612  dx = nodeB->giveCoordinate(1) - nodeA->giveCoordinate(1);
613  dy = nodeB->giveCoordinate(2) - nodeA->giveCoordinate(2);
614  length = sqrt(dx * dx + dy * dy);
615 
617  answer.at(1, 1) = 1.0;
618  answer.at(2, 2) = dx / length;
619  answer.at(2, 3) = -dy / length;
620  answer.at(3, 2) = -answer.at(2, 3);
621  answer.at(3, 3) = answer.at(2, 2);
622 
623  return 1;
624 }
625 
626 
627 void
629 {
630  lcsMatrix.resize(3, 3); // Note! G -> L transformation matrix
631  FloatArray e1, e2, e3, help;
632 
633  // compute e1' = [N2-N1] and help = [N4-N1]
634  e1.beDifferenceOf( * this->giveNode(2)->giveCoordinates(), * this->giveNode(1)->giveCoordinates() );
635  help.beDifferenceOf( * this->giveNode(4)->giveCoordinates(), * this->giveNode(1)->giveCoordinates() );
636  e1.normalize();
637  e3.beVectorProductOf(e1, help);
638  e3.normalize();
639  e2.beVectorProductOf(e3, e1);
640  for ( int i = 1; i <= 3; i++ ) {
641  this->lcsMatrix.at(1, i) = e1.at(i);
642  this->lcsMatrix.at(2, i) = e2.at(i);
643  this->lcsMatrix.at(3, i) = e3.at(i);
644  }
645 
646  for ( int i = 1; i <= 4; i++ ) {
647  this->lnodes [ i - 1 ].beProductOf( this->lcsMatrix, * this->giveNode(i)->giveCoordinates() );
648  }
649 }
650 
651 
652 bool
654 {
655  answer.resize(24, 24);
656  answer.zero();
657 
658  for ( int i = 0; i < 4; i++ ) { // Loops over nodes
659  // In each node, transform global c.s. {D_u, D_v, D_w, R_u, R_v, R_w} into local c.s.
660  answer.setSubMatrix(this->lcsMatrix, 1 + i * 6, 1 + i * 6); // Displacements
661  answer.setSubMatrix(this->lcsMatrix, 1 + i * 6 + 3, 1 + i * 6 + 3); // Rotations
662  }
663 
664  return true;
665 }
666 
667 Interface *
669 {
670  if ( interface == ZZNodalRecoveryModelInterfaceType ) {
671  return static_cast< ZZNodalRecoveryModelInterface * >(this);
672  } else if ( interface == SPRNodalRecoveryModelInterfaceType ) {
673  return static_cast< SPRNodalRecoveryModelInterface * >(this);
674  }
675 
676  return NULL;
677 }
678 
679 
680 
681 void
683 {
684  pap.resize(4);
685  for ( int i = 1; i < 5; i++ ) {
686  pap.at(i) = this->giveNode(i)->giveNumber();
687  }
688 }
689 
690 void
692 {
693  int found = 0;
694  answer.resize(1);
695 
696  for ( int i = 1; i < 5; i++ ) {
697  if ( pap == this->giveNode(i)->giveNumber() ) {
698  found = 1;
699  }
700  }
701 
702  if ( found ) {
703  answer.at(1) = pap;
704  } else {
705  OOFEM_ERROR("node unknown");
706  }
707 }
708 } // end namespace oofem
double giveDeterminant() const
Returns the trace (sum of diagonal components) of the receiver.
Definition: floatmatrix.C:1408
CrossSection * giveCrossSection()
Definition: element.C:495
virtual void computeBodyLoadVectorAt(FloatArray &answer, Load *load, TimeStep *tStep, ValueModeType mode)
Computes the load vector due to body load acting on receiver, at given time step. ...
InternalStateType
Type representing the physical meaning of element or constitutive model internal variable.
virtual void computeConstitutiveMatrixAt(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep)
Computes constitutive matrix of receiver.
The element interface required by ZZNodalRecoveryModel.
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in full form.
virtual double computeVolumeAround(GaussPoint *gp)
Returns volume related to given integration point.
virtual void giveEdgeDofMapping(IntArray &answer, int iEdge) const
Assembles edge dof mapping mask, which provides mapping between edge local DOFs and "global" element ...
void beVectorProductOf(const FloatArray &v1, const FloatArray &v2)
Computes vector product (or cross product) of vectors given as parameters, , and stores the result in...
Definition: floatarray.C:415
Class and object Domain.
Definition: domain.h:115
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Returns local vector of unknowns.
Definition: element.C:86
virtual int computeLoadLEToLRotationMatrix(FloatMatrix &answer, int iEdge, GaussPoint *gp)
Returns transformation matrix from local edge c.s to element local coordinate system of load vector c...
virtual FEInterpolation * giveInterpolation() const
virtual void SPRNodalRecoveryMI_giveDofMansDeterminedByPatch(IntArray &answer, int pap)
virtual double giveTransformationJacobian(const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the determinant of the transformation.
Definition: feinterpol.C:43
virtual Interface * giveInterface(InterfaceType it)
Interface requesting service.
Wrapper around cell with vertex coordinates stored in FloatArray**.
Definition: feinterpol.h:115
The element interface required by ZZNodalRecoveryModel.
Abstract base class for "structural" finite elements with geometrical nonlinearities.
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
static IntArray drillOrdering
Ordering for the drilling dofs (the out-of-plane rotations)
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
virtual double edgeGiveTransformationJacobian(int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the edge Jacobian of transformation between local and global coordinates.
Definition: feinterpol2d.C:175
Penalty stiffness for drilling DOFs.
Definition: crosssection.h:68
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
Computes boundary condition value - its components values at given time.
Definition: load.C:82
virtual void giveDofManDofIDMask(int inode, IntArray &) const
Returns dofmanager dof mask for node.
virtual double giveCoordinate(int i)
Definition: node.C:82
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 void computeMidPlaneNormal(FloatArray &answer, const GaussPoint *gp)
Computes mid-plane normal of receiver at integration point.
Distributed body load.
Definition: bcgeomtype.h:43
bool reducedIntegrationFlag
Flag controlling reduced (one - point) integration for shear.
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Sets receiver to be a - b.
Definition: floatarray.C:341
void setSubMatrix(const FloatMatrix &src, int sr, int sc)
Adds the given matrix as sub-matrix to receiver.
Definition: floatmatrix.C:557
virtual void giveJacobianMatrixAt(FloatMatrix &jacobianMatrix, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Gives the jacobian matrix at the local coordinates.
Definition: feinterpol2d.C:112
double sqr(double x)
Definition: mathfem.h:112
Class representing a general abstraction for finite element interpolation class.
Definition: feinterpol.h:132
virtual void give3dShellStiffMtrx(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)=0
Method for computing 3d shell stiffness matrix.
double dotProduct(const FloatArray &x) const
Computes the dot product (or inner product) of receiver and argument.
Definition: floatarray.C:463
virtual void computeStressVector(FloatArray &answer, const FloatArray &strain, GaussPoint *gp, TimeStep *tStep)
Computes the stress vector of receiver at given integration point, at time step tStep.
virtual void computeLocalEdgeMapping(IntArray &edgeNodes, int iedge)
Definition: fei2dquadlin.C:295
#define OOFEM_ERROR(...)
Definition: error.h:61
REGISTER_Element(LSpace)
DofIDItem
Type representing particular dof type.
Definition: dofiditem.h:86
virtual double giveWeight()
Returns integration weight of receiver.
Definition: gausspoint.h:181
StructuralCrossSection * giveStructuralCrossSection()
Helper function which returns the structural cross-section for the element.
virtual void SPRNodalRecoveryMI_giveSPRAssemblyPoints(IntArray &pap)
virtual bool computeGtoLRotationMatrix(FloatMatrix &answer)
Returns transformation matrix from global c.s.
#define _IFT_Quad1MindlinShell3D_ReducedIntegration
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Receiver becomes the result of the product of aMatrix and anArray.
Definition: floatarray.C:676
void plusProductSymmUpper(const FloatMatrix &a, const FloatMatrix &b, double dV)
Adds to the receiver the product .
Definition: floatmatrix.C:698
virtual void giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord=0)
Evaluates nodal representation of real internal forces.
virtual double giveLengthInDir(const FloatArray &normalToCrackPlane)
Default implementation returns length of element projection into specified direction.
Definition: element.C:1143
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
virtual int setupIntegrationPoints(IntegrationRule &irule, int npoints, Element *element)
Sets up integration rule for the given element.
Definition: crosssection.C:54
int numberOfGaussPoints
Number of integration points as specified by nip.
Definition: element.h:188
Class representing vector of real numbers.
Definition: floatarray.h:82
void plusDyadSymmUpper(const FloatArray &a, double dV)
Adds to the receiver the dyadic product .
Definition: floatmatrix.C:756
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
virtual double give(CrossSectionProperty a, GaussPoint *gp)
Returns the value of cross section property at given point.
Definition: crosssection.C:151
static IntArray shellOrdering
Ordering for the normal shell stiffness (everything but the out-of-plane rotations) ...
void beSubArrayOf(const FloatArray &src, const IntArray &indx)
Extract sub vector form src array and stores the result into receiver.
Definition: floatarray.C:379
IntegrationPointStatus * giveMaterialStatus()
Returns reference to associated material status (NULL if not defined).
Definition: gausspoint.h:205
virtual double giveCharacteristicLength(const FloatArray &normalToCrackPlane)
Returns the size of element in the given direction, in some cases adjusted (e.g.
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
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
Class representing the general Input Record.
Definition: inputrecord.h:101
Void cell geometry wrapper.
Definition: feinterpol.h:76
Class Interface.
Definition: interface.h:82
virtual void computeLumpedMassMatrix(FloatMatrix &answer, TimeStep *tStep)
Computes lumped mass matrix of receiver.
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
virtual bcGeomType giveBCGeoType() const
Returns geometry character of boundary condition.
virtual void computeGaussPoints()
Initializes the array of integration rules member variable.
virtual double computeEdgeVolumeAround(GaussPoint *gp, int iEdge)
Computes volume related to integration point on local edge.
std::vector< std::unique_ptr< IntegrationRule > > integrationRulesArray
List of integration rules of receiver (each integration rule contains associated integration points a...
Definition: element.h:170
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
virtual void giveGeneralizedStress_Shell(FloatArray &answer, GaussPoint *gp, const FloatArray &generalizedStrain, TimeStep *tStep)=0
virtual void computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int=1, int=ALL_STRAINS)
Computes the geometrical matrix of receiver in given integration point.
void zero()
Zeroes all coefficient of receiver.
Definition: floatmatrix.C:1326
InterfaceType
Enumerative type, used to identify interface type.
Definition: interfacetype.h:43
virtual void computeStrainVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep)
Compute strain vector of receiver evaluated at given integration point at given time step from elemen...
Load is base abstract class for all loads.
Definition: load.h:61
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:337
void computeVectorOfUnknowns(ValueModeType mode, TimeStep *tStep, FloatArray &shellUnknowns, FloatArray &drillUnknowns)
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
virtual bcValType giveBCValType() const
Returns receiver load type.
Class implementing node in finite element mesh.
Definition: node.h:87
int giveNumber() const
Definition: femcmpnn.h:107
double normalize()
Normalizes receiver.
Definition: floatarray.C:828
Node * giveNode(int i) const
Returns reference to the i-th node of element.
Definition: element.h:610
virtual double evaldNdx(FloatMatrix &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the matrix of derivatives of interpolation functions (shape functions) at given point...
Definition: fei2dquadlin.C:75
virtual void computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
Computes the stiffness matrix of receiver.
void symmetrized()
Initializes the lower half of the receiver according to the upper half.
Definition: floatmatrix.C:1576
Quad1MindlinShell3D(int n, Domain *d)
Class representing integration point in finite element program.
Definition: gausspoint.h:93
#define OOFEM_WARNING(...)
Definition: error.h:62
virtual int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
Returns the integration point corresponding value in full form.
std::vector< FloatArray > lnodes
Cached nodal coordinates in local c.s.,.
Class representing solution step.
Definition: timestep.h:80
FloatMatrix lcsMatrix
Cached coordinates in local c.s.,.
int numberOfDofMans
Number of dofmanagers.
Definition: element.h:149
void add(const FloatArray &src)
Adds array src to receiver.
Definition: floatarray.C:156
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)
Evaluates the array of interpolation functions (shape functions) at given point.
Definition: fei2dquadlin.C:59
const FloatArray & giveNaturalCoordinates()
Returns coordinate array of receiver.
Definition: gausspoint.h:138
Class representing Gaussian-quadrature integration rule.
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:30 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011