OOFEM 3.0
Loading...
Searching...
No Matches
tr_shell11.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 - 2025 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
36#include "fei2dtrlin.h"
37#include "contextioerr.h"
39#include "gausspoint.h"
40#include "classfactory.h"
41#include "node.h"
43#include "load.h"
44
45namespace oofem {
47
48FEI2dTrLin TR_SHELL11 :: interp_lin(1, 2);
49
50
51TR_SHELL11 :: TR_SHELL11(int n, Domain *aDomain) : StructuralElement(n, aDomain), ZZNodalRecoveryModelInterface(this), ZZErrorEstimatorInterface(this), SpatialLocalizerInterface(this)
52{
56 area = 0.0;
57}
58
59void
60TR_SHELL11 :: computeGaussPoints()
61// Sets up the array containing the four Gauss points of the receiver.
62{
63 if ( integrationRulesArray.size() == 0 ) {
64 integrationRulesArray.resize(1);
65 integrationRulesArray [ 0 ] = std::make_unique<GaussIntegrationRule>(1, this, 1, 3);
66 this->giveCrossSection()->setupIntegrationPoints(* integrationRulesArray [ 0 ], numberOfGaussPoints, this);
67 }
68}
69
71TR_SHELL11 :: GiveDerivativeUX(const FloatArray &lCoords)
72{
73 // get node coordinates
74 FloatArray x(3), y(3);
75 this->giveNodeCoordinates(x, y);
76
77 //
78 FloatArray b(3), c(3), d(3);
79
80 for ( int i = 1; i <= 3; i++ ) {
81 int j = i + 1 - i / 3 * 3;
82 int k = j + 1 - j / 3 * 3;
83 b.at(i) = y.at(j) - y.at(k);
84 c.at(i) = x.at(k) - x.at(j);
85 d.at(i) = sqrt( b.at(i) * b.at(i) + c.at(i) * c.at(i) );
86 }
87
88 //
89 FloatArray angles = this->GivePitch();
90
91 //
92 FloatArray shapeFunct(3);
93 shapeFunct.at(1) = lCoords.at(1);
94 shapeFunct.at(2) = lCoords.at(2);
95 shapeFunct.at(3) = 1.0 - shapeFunct.at(1) - shapeFunct.at(2);
96
97 //
98 FloatArray nx(3);
99
100 for ( int i = 1; i <= 3; i++ ) {
101 int j = i + 1 - i / 3 * 3;
102 int k = j + 1 - j / 3 * 3;
103 nx.at(i) = ( d.at(j) / 2. * ( b.at(k) * shapeFunct.at(i) + shapeFunct.at(k) * b.at(i) ) * sin( angles.at(j) ) -
104 d.at(k) / 2. * ( b.at(i) * shapeFunct.at(j) + shapeFunct.at(i) * b.at(j) ) * sin( angles.at(k) ) );
105 }
106
107 return nx;
108}
109
110
112TR_SHELL11 :: GiveDerivativeVX(const FloatArray &lCoords)
113{
114 // get node coordinates
115 FloatArray x(3), y(3);
116 this->giveNodeCoordinates(x, y);
117
118 //
119 FloatArray b(3), c(3), d(3);
120
121 for ( int i = 1; i <= 3; i++ ) {
122 int j = i + 1 - i / 3 * 3;
123 int k = j + 1 - j / 3 * 3;
124 b.at(i) = y.at(j) - y.at(k);
125 c.at(i) = x.at(k) - x.at(j);
126 d.at(i) = sqrt( b.at(i) * b.at(i) + c.at(i) * c.at(i) );
127 }
128
129 //
130 FloatArray angles = this->GivePitch();
131
132 //
133 FloatArray shapeFunct(3);
134 shapeFunct.at(1) = lCoords.at(1);
135 shapeFunct.at(2) = lCoords.at(2);
136 shapeFunct.at(3) = 1.0 - shapeFunct.at(1) - shapeFunct.at(2);
137
138 //
139 FloatArray nx(3);
140
141 for ( int i = 1; i <= 3; i++ ) {
142 int j = i + 1 - i / 3 * 3;
143 int k = j + 1 - j / 3 * 3;
144 nx.at(i) = ( d.at(j) / 2. * ( b.at(k) * shapeFunct.at(i) + shapeFunct.at(k) * b.at(i) ) * cos( angles.at(j) ) -
145 d.at(k) / 2. * ( b.at(i) * shapeFunct.at(j) + shapeFunct.at(i) * b.at(j) ) * cos( angles.at(k) ) ) * ( -1.0 );
146 }
147
148 return nx;
149}
150
151
153TR_SHELL11 :: GiveDerivativeUY(const FloatArray &lCoords)
154{
155 // get node coordinates
156 FloatArray x(3), y(3);
157 this->giveNodeCoordinates(x, y);
158
159 //
160 FloatArray b(3), c(3), d(3);
161
162 for ( int i = 1; i <= 3; i++ ) {
163 int j = i + 1 - i / 3 * 3;
164 int k = j + 1 - j / 3 * 3;
165 b.at(i) = y.at(j) - y.at(k);
166 c.at(i) = x.at(k) - x.at(j);
167 d.at(i) = sqrt( b.at(i) * b.at(i) + c.at(i) * c.at(i) );
168 }
169
170 //
171 FloatArray angles = this->GivePitch();
172
173 //
174 FloatArray shapeFunct(3);
175 shapeFunct.at(1) = lCoords.at(1);
176 shapeFunct.at(2) = lCoords.at(2);
177 shapeFunct.at(3) = 1.0 - shapeFunct.at(1) - shapeFunct.at(2);
178
179 //
180 FloatArray ny(3);
181
182 for ( int i = 1; i <= 3; i++ ) {
183 int j = i + 1 - i / 3 * 3;
184 int k = j + 1 - j / 3 * 3;
185 ny.at(i) = ( d.at(j) / 2. * ( c.at(k) * shapeFunct.at(i) + shapeFunct.at(k) * c.at(i) ) * sin( angles.at(j) ) -
186 d.at(k) / 2. * ( c.at(i) * shapeFunct.at(j) + shapeFunct.at(i) * c.at(j) ) * sin( angles.at(k) ) );
187 }
188
189 return ny;
190}
191
192
194TR_SHELL11 :: GiveDerivativeVY(const FloatArray &lCoords)
195{
196 // get node coordinates
197 FloatArray x(3), y(3);
198 this->giveNodeCoordinates(x, y);
199
200 //
201 FloatArray b(3), c(3), d(3);
202
203 for ( int i = 1; i <= 3; i++ ) {
204 int j = i + 1 - i / 3 * 3;
205 int k = j + 1 - j / 3 * 3;
206 b.at(i) = y.at(j) - y.at(k);
207 c.at(i) = x.at(k) - x.at(j);
208 d.at(i) = sqrt( b.at(i) * b.at(i) + c.at(i) * c.at(i) );
209 }
210
211 //
212 FloatArray angles = this->GivePitch();
213
214 //
215 FloatArray shapeFunct(3);
216 shapeFunct.at(1) = lCoords.at(1);
217 shapeFunct.at(2) = lCoords.at(2);
218 shapeFunct.at(3) = 1.0 - shapeFunct.at(1) - shapeFunct.at(2);
219
220 //
221 FloatArray ny(3);
222
223 for ( int i = 1; i <= 3; i++ ) {
224 int j = i + 1 - i / 3 * 3;
225 int k = j + 1 - j / 3 * 3;
226 ny.at(i) = ( d.at(j) / 2. * ( c.at(k) * shapeFunct.at(i) + shapeFunct.at(k) * c.at(i) ) * cos( angles.at(j) ) -
227 d.at(k) / 2. * ( c.at(i) * shapeFunct.at(j) + shapeFunct.at(i) * c.at(j) ) * cos( angles.at(k) ) ) * ( -1.0 );
228 }
229
230 return ny;
231}
232
234TR_SHELL11 :: GivePitch()
235// Returns angles between each side and global x-axis
236{
237 // get node coordinates
238 FloatArray x(3), y(3);
239 this->giveNodeCoordinates(x, y);
240
241 //
242 FloatArray angles(3);
243
244 for ( int i = 0; i < 3; i++ ) {
245 int j = i + 1 - i / 2 * 3;
246 int k = j + 1 - j / 2 * 3;
247 if ( x(k) == x(j) ) {
248 if ( y(k) > y(j) ) {
249 angles.at(i + 1) = M_PI / 2.;
250 } else {
251 angles.at(i + 1) = M_PI * 3. / 2.;
252 }
253 }
254
255 if ( x(k) > x(j) ) {
256 if ( y(k) >= y(j) ) {
257 angles.at(i + 1) = atan( ( y(k) - y(j) ) / ( x(k) - x(j) ) );
258 } else {
259 angles.at(i + 1) = 2. * M_PI - atan( ( y(j) - y(k) ) / ( x(k) - x(j) ) );
260 }
261 }
262
263 if ( x(k) < x(j) ) {
264 if ( y(k) >= y(j) ) {
265 angles.at(i + 1) = M_PI - atan( ( y(k) - y(j) ) / ( x(j) - x(k) ) );
266 } else {
267 angles.at(i + 1) = M_PI + atan( ( y(j) - y(k) ) / ( x(j) - x(k) ) );
268 }
269 }
270 }
271
272 return angles;
273}
274
275void
276TR_SHELL11 :: computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int li, int ui)
277// Returns part of strain-displacement matrix {B} of the receiver,
278// (epsilon_x,epsilon_y,gamma_xy) = B . r
279// type of this part is [3,9] r=(u1,w1,fi1,u2,w2,fi2,u3,w3,fi3)
280// evaluated at gp.
281// strainVectorShell {eps_x,eps_y,gamma_xy, kappa_x, kappa_y, kappa_xy, gamma_zx, gamma_zy, gamma_rot}
282{
283 // get node coordinates
284 FloatArray x(3), y(3);
285 this->giveNodeCoordinates(x, y);
286
287 FloatArray l(3), b(3), c(3);
288
289 for ( int i = 1; i <= 3; i++ ) {
290 int j = i + 1 - i / 3 * 3;
291 int k = j + 1 - j / 3 * 3;
292 b.at(i) = y.at(j) - y.at(k);
293 c.at(i) = x.at(k) - x.at(j);
294 if (i<3) {
295 l.at(i) = gp->giveNaturalCoordinate(i);
296 }
297 }
298 l.at(3) = 1.-l.at(1)-l.at(2);
299
300 // Derivatives of the shape functions (for this special interpolation)
303
304 FloatArray center = Vec2(0.33333333, 0.33333333);
305 FloatArray nxRed = this->GiveDerivativeVX( center );
306 FloatArray nyRed = this->GiveDerivativeUY( center );
307
308 // These are the regular shape functions of a linear triangle evaluated at the center
309 FloatArray lc = Vec3( center.at(1), center.at(2), 1.0 - center.at(1) - center.at(2) ); // = {0, 0, 1}
310
311 double area = this->giveArea();
312 double detJ = 1.0 / ( 2.0 * area );
313 answer.resize(9, 18);
314 for ( int i = 1; i <= 3; i++ ) {
315 int j = i + 1 - i / 3 * 3;
316 int k = j + 1 - j / 3 * 3;
317 // eps_x
318 answer.at(1, 6 * i - 5) = b.at(i) * detJ;
319 answer.at(1, 6 * i - 0) = nx.at(i) * detJ;
320
321 // eps_y
322 answer.at(2, 6 * i - 4) = c.at(i) * detJ;
323 answer.at(2, 6 * i - 0) = ny.at(i) * detJ;
324
327 // eps_xy
328 answer.at(3, 6 * i - 5) = c.at(i) * detJ;
329 answer.at(3, 6 * i - 4) = b.at(i) * detJ;
330 answer.at(3, 6 * i - 0) = ( nxRed.at(i) + nyRed.at(i) ) * detJ;
331
332 // kappa_x
333 answer.at(4, 6*i - 1) = b.at(i)*detJ;
334 // kappa_y
335 answer.at(5, 6*i - 2) =-c.at(i)*detJ;
336 // kappa_xy
337 answer.at(6, 6*i - 2) =-b.at(i)*detJ;
338 answer.at(6, 6*i - 1) = c.at(i)*detJ;
339 // gamma_zx
340 answer.at(7, 6*i - 3) = b.at(i)*detJ;
341 answer.at(7, 6*i - 2) = (-b.at(i)*b.at(k)*lc.at(j) + b.at(i)*b.at(j)*lc.at(k))*0.5*detJ;
342 answer.at(7, 6*i - 1) = (-b.at(i)*c.at(k)*lc.at(j)-b.at(j)*c.at(k)*lc.at(i)+b.at(k)*c.at(j)*lc.at(i)+b.at(i)*c.at(j)*lc.at(k))*0.5*detJ+lc.at(i)*2.0*area*detJ;
343 // gamma_zy
344 answer.at(8, 6*i - 3) = c.at(i)*detJ;
345 answer.at(8, 6*i - 2) = (-b.at(k)*c.at(i)*lc.at(j)-b.at(k)*c.at(j)*lc.at(i)+b.at(j)*c.at(k)*lc.at(i)+b.at(j)*c.at(i)*lc.at(k))*0.5*detJ-lc.at(i)*2.0*area*detJ;
346 answer.at(8, 6*i - 1) = (-c.at(i)*c.at(k)*lc.at(j)+c.at(i)*c.at(j)*lc.at(k))*0.5*detJ;
347
348 // Reduced integration of the fourth strain component
349 // gamma_rot
350 answer.at(9, 6 * i - 5) = -1. * c.at(i) * 1.0 / 4.0 / area;
351 answer.at(9, 6 * i - 4) = b.at(i) * 1.0 / 4.0 / area;
352 answer.at(9, 6 * i - 0) = ( -4. * area * lc.at(i) + nxRed.at(i) - nyRed.at(i) ) * 1.0 / 4.0 / area;
353
354 }
355
356}
357
358
359
360
361void
362TR_SHELL11 :: computeNmatrixAt(const FloatArray &iLocCoord, FloatMatrix &answer)
363// Returns the displacement interpolation matrix {N} of the receiver
364// evaluated at gp.
365{
366 // get node coordinates
367 FloatArray x(3), y(3);
368 this->giveNodeCoordinates(x, y);
369
370 //
371 FloatArray b(3), c(3), d(3);
372
373 for ( int i = 1; i <= 3; i++ ) {
374 int j = i + 1 - i / 3 * 3;
375 int k = j + 1 - j / 3 * 3;
376 b.at(i) = y.at(j) - y.at(k);
377 c.at(i) = x.at(k) - x.at(j);
378 d.at(i) = sqrt( b.at(i) * b.at(i) + c.at(i) * c.at(i) );
379 }
380
381 //
382 FloatArray angles = this->GivePitch();
383
384 //
385 double l1, l2, l3, f11, f12, f13, f21, f22, f23;
386
387 l1 = iLocCoord.at(1);
388 l2 = iLocCoord.at(2);
389 l3 = 1. - l1 - l2;
390
391 f11 = d.at(2) / 2. *l1 *l3 *sin( angles.at(2) ) - d.at(3) / 2. *l2 *l1 *sin( angles.at(3) );
392 f12 = d.at(3) / 2. *l2 *l1 *sin( angles.at(3) ) - d.at(1) / 2. *l3 *l2 *sin( angles.at(1) );
393 f13 = d.at(1) / 2. *l3 *l2 *sin( angles.at(1) ) - d.at(2) / 2. *l1 *l3 *sin( angles.at(2) );
394
395 f21 = d.at(3) / 2. *l2 *l1 *cos( angles.at(3) ) - d.at(2) / 2. *l1 *l3 *cos( angles.at(2) );
396 f22 = d.at(1) / 2. *l3 *l2 *cos( angles.at(1) ) - d.at(3) / 2. *l2 *l1 *cos( angles.at(3) );
397 f23 = d.at(2) / 2. *l1 *l3 *cos( angles.at(2) ) - d.at(1) / 2. *l3 *l2 *cos( angles.at(1) );
398
399 //
400 answer.resize(6, 18);
401 answer.zero();
402
403 answer.at(1, 1) = l1;
404 answer.at(1, 6) = f11;
405 answer.at(1, 7) = l2;
406 answer.at(1, 12) = f12;
407 answer.at(1, 13) = l3;
408 answer.at(1, 18) = f13;
409
410 answer.at(2, 2) = l1;
411 answer.at(2, 6) = f21;
412 answer.at(2, 8) = l2;
413 answer.at(2, 12) = f22;
414 answer.at(2, 14) = l3;
415 answer.at(2, 18) = f23;
416
417 answer.at(3, 3) = l1; // d_w
418 answer.at(3, 4) = l1 * ( l2 * b.at(3) - l3 * b.at(2) ) * 0.5;
419 answer.at(3, 5) = l1 * ( l2 * c.at(3) - l3 * c.at(2) ) * 0.5;
420 answer.at(3, 9) = l2;
421 answer.at(3, 10) = l2 * ( l3 * b.at(1) - l1 * b.at(3) ) * 0.5;
422 answer.at(3, 11) = l2 * ( l3 * c.at(1) - l1 * c.at(3) ) * 0.5;
423 answer.at(3, 15) = l3;
424 answer.at(3, 16) = l3 * ( l1 * b.at(2) - l2 * b.at(1) ) * 0.5;
425 answer.at(3, 17) = l3 * ( l1 * c.at(2) - l2 * c.at(1) ) * 0.5;
426
427 answer.at(4, 4) = l1; // fi_x
428 answer.at(4, 10) = l2;
429 answer.at(4, 16) = l3;
430
431 answer.at(5, 5) = l1; // fi_y
432 answer.at(5, 11) = l2;
433 answer.at(5, 17) = l3;
434
435 answer.at(6, 6) = l1; // fi_y
436 answer.at(12, 12) = l2;
437 answer.at(18, 18) = l3;
438}
439
440
441double
442TR_SHELL11 :: giveArea()
443// returns the area occupied by the receiver
444{
446 if ( fabs(area) > 0 ) { // check if previously computed
447 return area;
448 }
449
450 // get node coordinates
451 FloatArray x(3), y(3);
452 this->giveNodeCoordinates(x, y);
453
454 //
455 double x1, x2, x3, y1, y2, y3;
456 x1 = x.at(1);
457 x2 = x.at(2);
458 x3 = x.at(3);
459
460 y1 = y.at(1);
461 y2 = y.at(2);
462 y3 = y.at(3);
463
464 //return ( area = fabs( 0.5 * ( x2 * y3 + x1 * y2 + y1 * x3 - x2 * y1 - x3 * y2 - x1 * y3 ) ) );
465 return ( area = 0.5 * ( x2 * y3 + x1 * y2 + y1 * x3 - x2 * y1 - x3 * y2 - x1 * y3 ) );
466}
467
468void
469TR_SHELL11 :: giveLocalCoordinates(FloatArray &answer, const FloatArray &global)
470// Returns global coordinates given in global vector
471// transformed into local coordinate system of the
472// receiver
473{
474 // test the parameter
475 if ( global.giveSize() != 3 ) {
476 OOFEM_ERROR("cannot transform coordinates - size mismatch");
477 }
478
479 // first ensure that receiver's GtoLRotationMatrix[3,3] is defined
480 if ( !GtoLRotationMatrix.isNotEmpty() ) {
482 }
483
484 FloatArray offset = global;
485 offset.subtract( this->giveNode(1)->giveCoordinates() );
486 answer.beProductOf(GtoLRotationMatrix, offset);
487}
488
489
490double
491TR_SHELL11 :: computeVolumeAround(GaussPoint *gp)
492{
493 double detJ, weight;
494
495 FloatArray x, y;
496 this->giveNodeCoordinates(x, y);
497 std :: vector< FloatArray > lc = {Vec2(x[0], y[0]), Vec2(x[1], y[1]), Vec2(x[2], y[2])};
498
499 weight = gp->giveWeight();
500 detJ = fabs( this->interp_lin.giveTransformationJacobian( gp->giveNaturalCoordinates(), FEIVertexListGeometryWrapper(lc, this->giveGeometryType()) ) );
501 return detJ * weight; // * this->giveStructuralCrossSection()->give(CS_Thickness, gp);
502}
503
504
505void
506TR_SHELL11 :: giveNodeCoordinates(FloatArray &x, FloatArray &y)
507{
508 FloatArray nc1(3), nc2(3), nc3(3);
509
510 this->giveLocalCoordinates( nc1, this->giveNode(1)->giveCoordinates() );
511 this->giveLocalCoordinates( nc2, this->giveNode(2)->giveCoordinates() );
512 this->giveLocalCoordinates( nc3, this->giveNode(3)->giveCoordinates() );
513
514 x.resize(3);
515 x.at(1) = nc1.at(1);
516 x.at(2) = nc2.at(1);
517 x.at(3) = nc3.at(1);
518
519 y.resize(3);
520 y.at(1) = nc1.at(2);
521 y.at(2) = nc2.at(2);
522 y.at(3) = nc3.at(2);
523
524 //if (z) {
525 // z[0] = nc1->at(3);
526 // z[1] = nc2->at(3);
527 // z[2] = nc3->at(3);
528 //}
529}
530
531
532void
533TR_SHELL11 :: giveDofManDofIDMask(int inode, IntArray &answer) const
534{
535 answer = {D_u, D_v, D_w, R_u, R_v, R_w};
536}
537
538
539void
540TR_SHELL11 :: computeConstitutiveMatrixAt(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep)
541{
542 answer = this->giveStructuralCrossSection()->give3dShellRotStiffMtrx(rMode, gp, tStep);
543}
544
545
546void
547TR_SHELL11 :: computeStressVector(FloatArray &answer, const FloatArray &strain, GaussPoint *gp, TimeStep *tStep)
548{
549 answer = this->giveStructuralCrossSection()->giveGeneralizedStress_ShellRot(strain, gp, tStep);
550}
551
552
553const FloatMatrix *
554TR_SHELL11 :: computeGtoLRotationMatrix()
555// Returns the rotation matrix of the receiver of the size [3,3]
556// coords(local) = T * coords(global)
557//
558// local coordinate (described by vector triplet e1',e2',e3') is defined as follows:
559//
560// e1' : [N2-N1] Ni - means i - th node
561// help : [N3-N1]
562// e3' : e1' x help
563// e2' : e3' x e1'
564{
565
566 if ( !GtoLRotationMatrix.isNotEmpty() ) {
567 FloatArray e1, e2, e3, help;
568
569 // compute e1' = [N2-N1] and help = [N3-N1]
570 e1.beDifferenceOf( this->giveNode(2)->giveCoordinates(), this->giveNode(1)->giveCoordinates() );
571 help.beDifferenceOf( this->giveNode(3)->giveCoordinates(), this->giveNode(1)->giveCoordinates() );
572
573 // let us normalize e1'
574 e1.normalize();
575
576 // compute e3' : vector product of e1' x help
577 e3.beVectorProductOf(e1, help);
578 // let us normalize
579 e3.normalize();
580
581 // now from e3' x e1' compute e2'
582 e2.beVectorProductOf(e3, e1);
583
584 //
585 GtoLRotationMatrix.resize(3, 3);
586
587 for ( int i = 1; i <= 3; i++ ) {
588 GtoLRotationMatrix.at(1, i) = e1.at(i);
589 GtoLRotationMatrix.at(2, i) = e2.at(i);
590 GtoLRotationMatrix.at(3, i) = e3.at(i);
591 }
592 }
593
594 return &GtoLRotationMatrix;
595}
596
597
598bool
599TR_SHELL11 :: computeGtoLRotationMatrix(FloatMatrix &answer)
600// Returns the rotation matrix of the receiver of the size [18,18]
601// r(local) = T * r(global)
602// for one node (r written transposed): {u,v,w, r1, r2, r3} = T * {u,v,w,r1,r2,r3}
603{
604 // test if pereviously computed
605 if ( !GtoLRotationMatrix.isNotEmpty() ) {
607 }
608
609 answer.resize(18, 18);
610 answer.zero();
611
612 for ( int i = 1; i <= 6; i++ ) {
613 answer.setSubMatrix(GtoLRotationMatrix, 3*i-2, 3*i-2);
614 }
615
616 return 1;
617}
618
619
620void
621TR_SHELL11 :: giveCharacteristicTensor(FloatMatrix &answer, CharTensor type, GaussPoint *gp, TimeStep *tStep)
622// returns characteristic tensor of the receiver at given gp and tStep
623// strain vector = (Eps_X, Eps_y, Gamma_xy, Kappa_z)
624{
625 FloatArray charVect;
627
628 answer.resize(3, 3);
629 answer.zero();
630
631 if ( type == LocalForceTensor || type == GlobalForceTensor ) {
632 //this->computeStressVector(charVect, gp, tStep);
633 charVect = ms->giveStressVector();
634
635 double h = this->giveStructuralCrossSection()->give(CS_Thickness, gp);
636 answer.at(1, 1) = charVect.at(1) * h;
637 answer.at(2, 2) = charVect.at(2) * h;
638 answer.at(1, 2) = charVect.at(3) * h;
639 answer.at(2, 1) = charVect.at(3) * h;
640
641 answer.at(1, 3) = charVect.at(7);
642 answer.at(3, 1) = charVect.at(7);
643 answer.at(2, 3) = charVect.at(8);
644 answer.at(3, 2) = charVect.at(8);
645
646 } else if ( type == LocalMomentTensor || type == GlobalMomentTensor ) {
647 //this->computeStressVector(charVect, gp, tStep);
648 charVect = ms->giveStressVector();
649
650 //answer.at(3, 3) = charVect.at(4);
651 answer.at(1, 1) = charVect.at(4);
652 answer.at(2, 2) = charVect.at(5);
653 answer.at(1, 2) = charVect.at(6);
654 answer.at(2, 1) = charVect.at(6);
655
656 } else if ( type == LocalStrainTensor || type == GlobalStrainTensor ) {
657 //this->computeStrainVector(charVect, gp, tStep);
658 charVect = ms->giveStrainVector();
659
660 answer.at(1, 1) = charVect.at(1);
661 answer.at(2, 2) = charVect.at(2);
662 answer.at(1, 2) = charVect.at(3) / 2.;
663 answer.at(2, 1) = charVect.at(3) / 2.;
664
665 answer.at(1, 3) = charVect.at(7) / 2.;
666 answer.at(3, 1) = charVect.at(7) / 2.;
667 answer.at(2, 3) = charVect.at(8) / 2.;
668 answer.at(3, 2) = charVect.at(8) / 2.;
669
670
671 } else if ( type == LocalCurvatureTensor || type == GlobalCurvatureTensor ) {
672 //this->computeStrainVector(charVect, gp, tStep);
673 charVect = ms->giveStrainVector();
674
675 //answer.at(3, 3) = charVect.at(4);
676
677 answer.at(1, 1) = charVect.at(4);
678 answer.at(2, 2) = charVect.at(5);
679 answer.at(1, 2) = charVect.at(6) / 2.;
680 answer.at(2, 1) = charVect.at(6) / 2.;
681
682 } else {
683 OOFEM_ERROR("unsupported tensor mode");
684 }
685
686 if ( type == GlobalForceTensor || type == GlobalMomentTensor ||
687 type == GlobalStrainTensor || type == GlobalCurvatureTensor ) {
690 }
691}
692
693
694int
695TR_SHELL11 :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
696{
697 FloatMatrix globTensor;
698 CharTensor cht;
699
700 answer.resize(6);
701
702 if ( type == IST_CurvatureTensor || type == IST_ShellStrainTensor ) {
703 if ( type == IST_CurvatureTensor ) {
705 } else {
706 cht = GlobalStrainTensor;
707 }
708
709 this->giveCharacteristicTensor(globTensor, cht, gp, tStep);
710
711 answer.at(1) = globTensor.at(1, 1); //xx
712 answer.at(2) = globTensor.at(2, 2); //yy
713 answer.at(3) = globTensor.at(3, 3); //zz
714 answer.at(4) = 2 * globTensor.at(2, 3); //yz
715 answer.at(5) = 2 * globTensor.at(1, 3); //xz
716 answer.at(6) = 2 * globTensor.at(1, 2); //xy
717
718 return 1;
719 } else if ( type == IST_ShellMomentTensor || type == IST_ShellForceTensor ) {
720 if ( type == IST_ShellMomentTensor ) {
721 cht = GlobalMomentTensor;
722 } else {
723 cht = GlobalForceTensor;
724 }
725
726 this->giveCharacteristicTensor(globTensor, cht, gp, tStep);
727
728 answer.at(1) = globTensor.at(1, 1); //xx
729 answer.at(2) = globTensor.at(2, 2); //yy
730 answer.at(3) = globTensor.at(3, 3); //zz
731 answer.at(4) = globTensor.at(2, 3); //yz
732 answer.at(5) = globTensor.at(1, 3); //xz
733 answer.at(6) = globTensor.at(1, 2); //xy
734
735 return 1;
736 } else {
737 return StructuralElement :: giveIPValue(answer, gp, type, tStep);
738 }
739}
740
741int
742TR_SHELL11 :: computeLoadGToLRotationMtrx(FloatMatrix &answer)
743// Returns the rotation matrix of the receiver of the size [6,6]
744// f(local) = T * f(global)
745{
746 // test if previously computed
747 if ( !GtoLRotationMatrix.isNotEmpty() ) {
749 }
750
751 answer.resize(6, 6);
752 answer.zero();
753
754 for ( int i = 1; i <= 3; i++ ) {
755 answer.at(1, i) = answer.at(4, i + 3) = GtoLRotationMatrix.at(1, i);
756 answer.at(2, i) = answer.at(5, i + 3) = GtoLRotationMatrix.at(2, i);
757 answer.at(3, i) = answer.at(6, i + 3) = GtoLRotationMatrix.at(3, i);
758 }
759
760 return 1;
761}
762
763
764void
765TR_SHELL11 :: computeBodyLoadVectorAt(FloatArray &answer, Load *forLoad, TimeStep *tStep, ValueModeType mode)
766// Computes numerically the load vector of the receiver due to the body loads, at tStep.
767// load is assumed to be in global cs.
768// load vector is then transformed to coordinate system in each node.
769// (should be global coordinate system, but there may be defined
770// different coordinate system in each node)
771{
772 double dens, dV, load;
773 FloatArray force;
774 FloatMatrix T;
775
776 if ( ( forLoad->giveBCGeoType() != BodyLoadBGT ) || ( forLoad->giveBCValType() != ForceLoadBVT ) ) {
777 OOFEM_ERROR("unknown load type");
778 }
779
780 // note: force is assumed to be in global coordinate system; 6 components
781 forLoad->computeComponentArrayAt(force, tStep, mode);
782 // get it in local c.s.
784 force.rotatedWith(T, 'n');
785
786 if ( force.giveSize() ) {
787 GaussIntegrationRule iRule (1, this, 1, 1);
788 iRule.SetUpPointsOnTriangle(1, _Unknown);
789 GaussPoint *gp = iRule.getIntegrationPoint(0);
790
791 dens = this->giveStructuralCrossSection()->give('d', gp);
792 dV = this->computeVolumeAround(gp);// * this->giveCrossSection()->give(CS_Thickness, gp);
793
794 answer.resize(18);
795 answer.zero();
796
797 load = force.at(1) * dens * dV / 3.0;
798 answer.at(1) = load;
799 answer.at(7) = load;
800 answer.at(13) = load;
801
802 load = force.at(2) * dens * dV / 3.0;
803 answer.at(2) = load;
804 answer.at(8) = load;
805 answer.at(14) = load;
806
807 load = force.at(3) * dens * dV / 3.0;
808 answer.at(3) = load;
809 answer.at(9) = load;
810 answer.at(15) = load;
811
812 // transform result from global cs to local element cs.
813 //if ( this->computeGtoLRotationMatrix(T) ) {
814 // answer.rotatedWith(T, 'n');
815 //}
816 } else {
817 answer.clear(); // nil resultant
818 }
819}
820
821void
822TR_SHELL11 :: computeSurfaceNMatrixAt(FloatMatrix &answer, int iSurf, GaussPoint *sgp)
823{
824 this->computeNmatrixAt(sgp->giveNaturalCoordinates(), answer);
825}
826
827void
828TR_SHELL11 :: giveSurfaceDofMapping(IntArray &answer, int iSurf) const
829{
830 answer.resize(18);
831 answer.zero();
832 if ( iSurf == 1 ) {
833 for (int i=1; i<=18; i++)
834 answer.at(i)=i;
835 } else {
836 OOFEM_ERROR("wrong surface number");
837 }
838}
839
840
841double
842TR_SHELL11 :: computeSurfaceVolumeAround(GaussPoint *gp, int iSurf)
843{
844 return this->computeVolumeAround(gp);
845}
846
847
848int
849TR_SHELL11 :: computeLoadLSToLRotationMatrix(FloatMatrix &answer, int isurf, GaussPoint *gp)
850{
851 return 0;
852}
853
854
855void
856TR_SHELL11 :: printOutputAt(FILE *file, TimeStep *tStep)
857// Performs end-of-step operations.
858{
859 FloatArray v;
860
861 fprintf( file, "element %d (%8d) :\n", this->giveLabel(), this->giveNumber() );
862
863 for ( int i = 0; i < (int)integrationRulesArray.size(); i++ ) {
864 for ( GaussPoint *gp: *integrationRulesArray [ i ] ) {
865
866 fprintf( file, " GP %2d.%-2d :", i + 1, gp->giveNumber() );
867
868 this->giveIPValue(v, gp, IST_ShellStrainTensor, tStep);
869 fprintf(file, " strains ");
870 for ( auto &val : v ) fprintf(file, " %.4e", val);
871
872 this->giveIPValue(v, gp, IST_CurvatureTensor, tStep);
873 fprintf(file, "\n curvatures ");
874 for ( auto &val : v ) fprintf(file, " %.4e", val);
875
876 // Forces - Moments
877 this->giveIPValue(v, gp, IST_ShellForceTensor, tStep);
878 fprintf(file, "\n stresses ");
879 for ( auto &val : v ) fprintf(file, " %.4e", val);
880
881 this->giveIPValue(v, gp, IST_ShellMomentTensor, tStep);
882 fprintf(file, "\n moments ");
883 for ( auto &val : v ) fprintf(file, " %.4e", val);
884
885
886 if ( gp->hasSlaveGaussPoint()) { // layered material
887 fprintf(file, "\n Layers report \n{\n");
888
889 for (auto &sgp: gp->giveSlaveGaussPoints()) {
890 sgp->printOutputAt(file, tStep);
891 }
892 fprintf(file, "} end layers report\n");
893
894 }
895
896
897 fprintf(file, "\n");
898 }
899 }
900}
901
902void
903TR_SHELL11 :: initializeFrom(InputRecord &ir, int priority)
904{
905 StructuralElement :: initializeFrom(ir, priority);
906}
907
908Interface *
909TR_SHELL11 :: giveInterface(InterfaceType interface)
910{
911 if ( interface == LayeredCrossSectionInterfaceType ) {
912 return static_cast< LayeredCrossSectionInterface * >(this);
913 } else if ( interface == ZZNodalRecoveryModelInterfaceType ) {
914 return static_cast< ZZNodalRecoveryModelInterface * >(this);
915 } else if ( interface == NodalAveragingRecoveryModelInterfaceType ) {
916 return static_cast< NodalAveragingRecoveryModelInterface * >(this);
917 } else if ( interface == SPRNodalRecoveryModelInterfaceType ) {
918 return static_cast< SPRNodalRecoveryModelInterface * >(this);
919 } else if ( interface == ZZErrorEstimatorInterfaceType ) {
920 return static_cast< ZZErrorEstimatorInterface * >(this);
921 }
922
923
924 return NULL;
925}
926
927void
928TR_SHELL11 :: NodalAveragingRecoveryMI_computeNodalValue(FloatArray &answer, int node,
929 InternalStateType type, TimeStep *tStep)
930{
931 GaussPoint *gp;
932 if ( ( type == IST_ShellForceTensor ) || ( type == IST_ShellMomentTensor ) ||
933 ( type == IST_ShellStrainTensor ) || ( type == IST_CurvatureTensor ) ) {
934 gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
935 this->giveIPValue(answer, gp, type, tStep);
936 } else {
937 answer.clear();
938 }
939}
940
941
942void
943TR_SHELL11 :: SPRNodalRecoveryMI_giveSPRAssemblyPoints(IntArray &pap)
944{
945 pap.resize(3);
946 pap.at(1) = this->giveNode(1)->giveNumber();
947 pap.at(2) = this->giveNode(2)->giveNumber();
948 pap.at(3) = this->giveNode(3)->giveNumber();
949}
950
951
952void
953TR_SHELL11 :: SPRNodalRecoveryMI_giveDofMansDeterminedByPatch(IntArray &answer, int pap)
954{
955 answer.resize(1);
956 if ( ( pap == this->giveNode(1)->giveNumber() ) ||
957 ( pap == this->giveNode(2)->giveNumber() ) ||
958 ( pap == this->giveNode(3)->giveNumber() ) ) {
959 answer.at(1) = pap;
960 } else {
961 OOFEM_ERROR("node unknown");
962 }
963}
964
965
967TR_SHELL11 :: SPRNodalRecoveryMI_givePatchType()
968{
969 return SPRPatchType_2dxy;
970}
971
972
973//
974// layered cross section support functions
975//
976void
977TR_SHELL11 :: computeStrainVectorInLayer(FloatArray &answer, const FloatArray &masterGpStrain,
978 GaussPoint *masterGp, GaussPoint *slaveGp, TimeStep *tStep)
979// returns full 3d strain vector of given layer (whose z-coordinate from center-line is
980// stored in slaveGp) for given tStep
981// // strainVectorShell {eps_x,eps_y,gamma_xy, kappa_x, kappa_y, kappa_xy, gamma_zx, gamma_zy, gamma_rot}
982{
983 double layerZeta, layerZCoord, top, bottom;
984
985 top = this->giveCrossSection()->give(CS_TopZCoord, masterGp);
986 bottom = this->giveCrossSection()->give(CS_BottomZCoord, masterGp);
987 layerZeta = slaveGp->giveNaturalCoordinate(3);
988 layerZCoord = 0.5 * ( ( 1. - layerZeta ) * bottom + ( 1. + layerZeta ) * top );
989
990 answer.resize(5); // {Exx,Eyy,GMyz,GMzx,GMxy}
991
992 answer.at(1) = masterGpStrain.at(1)+masterGpStrain.at(4) * layerZCoord;
993 answer.at(2) = masterGpStrain.at(2)+masterGpStrain.at(5) * layerZCoord;
994 answer.at(5) = masterGpStrain.at(3)+masterGpStrain.at(6) * layerZCoord;
995 answer.at(3) = masterGpStrain.at(8);
996 answer.at(4) = masterGpStrain.at(7);
997}
998
999double
1000TR_SHELL11 :: giveCharacteristicLength(const FloatArray &normalToCrackPlane)
1001//
1002// returns receiver's characteristic length for crack band models
1003// for a crack formed in the plane with normal normalToCrackPlane.
1004//
1005{
1006 return this->giveCharacteristicLengthForPlaneElements(normalToCrackPlane);
1007}
1008
1009
1010} // end namespace oofem
#define REGISTER_Element(class)
Node * giveNode(int i) const
Definition element.h:629
int numberOfDofMans
Number of dofmanagers.
Definition element.h:136
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
Definition element.h:157
int numberOfGaussPoints
Definition element.h:175
double giveCharacteristicLengthForPlaneElements(const FloatArray &normalToCrackPlane)
Definition element.C:1188
CrossSection * giveCrossSection()
Definition element.C:534
int giveLabel() const
Definition element.h:1125
int giveNumber() const
Definition femcmpnn.h:104
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Definition floatarray.C:403
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void rotatedWith(FloatMatrix &r, char mode)
Definition floatarray.C:814
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:689
void beVectorProductOf(const FloatArray &v1, const FloatArray &v2)
Definition floatarray.C:476
void subtract(const FloatArray &src)
Definition floatarray.C:320
void rotatedWith(const FloatMatrix &r, char mode='n')
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
void setSubMatrix(const FloatMatrix &src, int sr, int sc)
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
int SetUpPointsOnTriangle(int nPoints, MaterialMode mode) override
double giveNaturalCoordinate(int i) const
Returns i-th natural element coordinate of receiver.
Definition gausspoint.h:136
const FloatArray & giveNaturalCoordinates() const
Returns coordinate array of receiver.
Definition gausspoint.h:138
IntegrationPointStatus * giveMaterialStatus(IntegrationPointStatusIDType key=IPSID_Default)
Definition gausspoint.h:204
double giveWeight()
Returns integration weight of receiver.
Definition gausspoint.h:180
virtual bcGeomType giveBCGeoType() const
void resize(int n)
Definition intarray.C:73
void zero()
Sets all component to zero.
Definition intarray.C:52
int & at(std::size_t i)
Definition intarray.h:104
GaussPoint * getIntegrationPoint(int n)
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
Definition load.C:84
SpatialLocalizerInterface(Element *element)
StructuralCrossSection * giveStructuralCrossSection()
Helper function which returns the structural cross-section for the element.
StructuralElement(int n, Domain *d)
const FloatArray & giveStrainVector() const
Returns the const pointer to receiver's strain vector.
const FloatArray & giveStressVector() const
Returns the const pointer to receiver's stress vector.
static FEI2dTrLin interp_lin
Definition tr_shell11.h:62
Element_Geometry_Type giveGeometryType() const override
Definition tr_shell11.h:112
FloatArray GiveDerivativeUY(const FloatArray &lCoords)
Definition tr_shell11.C:153
const FloatMatrix * computeGtoLRotationMatrix()
Definition tr_shell11.C:554
void giveNodeCoordinates(FloatArray &x, FloatArray &y)
Definition tr_shell11.C:506
FloatArray GiveDerivativeVY(const FloatArray &lCoords)
Definition tr_shell11.C:194
int giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep) override
Definition tr_shell11.C:695
void giveLocalCoordinates(FloatArray &answer, const FloatArray &global)
Definition tr_shell11.C:469
void giveCharacteristicTensor(FloatMatrix &answer, CharTensor type, GaussPoint *gp, TimeStep *tStep)
Definition tr_shell11.C:621
FloatArray GiveDerivativeUX(const FloatArray &lCoords)
Definition tr_shell11.C:71
FloatMatrix GtoLRotationMatrix
Definition tr_shell11.h:65
void computeNmatrixAt(const FloatArray &iLocCoord, FloatMatrix &answer) override
Definition tr_shell11.C:362
double computeVolumeAround(GaussPoint *gp) override
Definition tr_shell11.C:491
FloatArray GivePitch()
Definition tr_shell11.C:234
FloatArray GiveDerivativeVX(const FloatArray &lCoords)
Definition tr_shell11.C:112
int computeLoadGToLRotationMtrx(FloatMatrix &answer) override
Definition tr_shell11.C:742
ZZErrorEstimatorInterface(Element *element)
Constructor.
ZZNodalRecoveryModelInterface(Element *element)
Constructor.
#define OOFEM_ERROR(...)
Definition error.h:79
#define M_PI
Definition mathfem.h:52
static FloatArray Vec2(const double &a, const double &b)
Definition floatarray.h:606
@ CS_BottomZCoord
Bottom z coordinate.
@ CS_Thickness
Thickness.
@ CS_TopZCoord
Top z coordinate.
@ BodyLoadBGT
Distributed body load.
Definition bcgeomtype.h:43
@ ForceLoadBVT
Definition bcvaltype.h:43
@ SPRNodalRecoveryModelInterfaceType
@ ZZNodalRecoveryModelInterfaceType
@ LayeredCrossSectionInterfaceType
@ ZZErrorEstimatorInterfaceType
@ NodalAveragingRecoveryModelInterfaceType
static FloatArray Vec3(const double &a, const double &b, const double &c)
Definition floatarray.h:607

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011