OOFEM 3.0
Loading...
Searching...
No Matches
beam3d.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
37#include "node.h"
38#include "material.h"
39#include "crosssection.h"
40#include "gausspoint.h"
42#include "floatmatrix.h"
43#include "intarray.h"
44#include "floatarray.h"
45#include "engngm.h"
46#include "boundaryload.h"
47#include "mathfem.h"
48#include "fei3dlinelin.h"
49#include "classfactory.h"
51#include "masterdof.h"
52#include "bctracker.h"
53#include "parametermanager.h"
54#include "paramkey.h"
55
56#include "bodyload.h"
57#include "boundaryload.h"
58
59#ifdef __OOFEG
60 #include "oofeggraphiccontext.h"
61#endif
62
63namespace oofem {
71
72FEI3dLineLin Beam3d :: interp;
73
74Beam3d :: Beam3d(int n, Domain *aDomain) : BeamBaseElement(n, aDomain)
75{
77 referenceNode = 0;
78 referenceAngle = 0.;
79
81 length = 0.;
82 kappay = kappaz = -1.0;
83
84 ghostNodes [ 0 ] = ghostNodes [ 1 ] = NULL;
86 subsoilMat = 0;
87}
88
89Beam3d :: ~Beam3d()
90{
91 delete ghostNodes [ 0 ];
92 delete ghostNodes [ 1 ];
93}
94
95FEInterpolation *Beam3d :: giveInterpolation() const { return & interp; }
96
97void
98Beam3d :: computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int li, int ui)
99// eeps = {\eps_x, \gamma_xz, \gamma_xy, \der{phi_x}{x}, \kappa_y, \kappa_z}^T
100{
101 double l, ksi, kappay, kappaz, c1y, c1z;
102 TimeStep *tStep = this->domain->giveEngngModel()->giveCurrentStep();
103
104 l = this->computeLength();
105 ksi = 0.5 + 0.5 * gp->giveNaturalCoordinate(1);
106 kappay = this->giveKappayCoeff(tStep);
107 kappaz = this->giveKappazCoeff(tStep);
108 c1y = 1. + 2. * kappay;
109 c1z = 1. + 2. * kappaz;
110
111 answer.resize(6, 12);
112 answer.zero();
113
114 answer.at(1, 1) = -1. / l;
115 answer.at(1, 7) = 1. / l;
116
117 answer.at(2, 3) = ( -2. * kappay ) / ( l * c1y );
118 answer.at(2, 5) = kappay / ( c1y );
119 answer.at(2, 9) = 2. * kappay / ( l * c1y );
120 answer.at(2, 11) = kappay / ( c1y );
121
122 answer.at(3, 2) = ( -2. * kappaz ) / ( l * c1z );
123 answer.at(3, 6) = -kappaz / ( c1z );
124 answer.at(3, 8) = 2. * kappaz / ( l * c1z );
125 answer.at(3, 12) = -kappaz / ( c1z );
126
127
128 answer.at(4, 4) = -1. / l;
129 answer.at(4, 10) = 1. / l;
130
131 answer.at(5, 3) = ( 6. - 12. * ksi ) / ( l * l * c1y );
132 answer.at(5, 5) = ( -2. * ( 2. + kappay ) + 6. * ksi ) / ( l * c1y );
133 answer.at(5, 9) = ( -6. + 12. * ksi ) / ( l * l * c1y );
134 answer.at(5, 11) = ( -2. * ( 1. - kappay ) + 6. * ksi ) / ( l * c1y );
135
136 answer.at(6, 2) = -1.0 * ( 6. - 12. * ksi ) / ( l * l * c1z );
137 answer.at(6, 6) = ( -2. * ( 2. + kappaz ) + 6. * ksi ) / ( l * c1z );
138 answer.at(6, 8) = -1.0 * ( -6. + 12. * ksi ) / ( l * l * c1z );
139 answer.at(6, 12) = ( -2. * ( 1. - kappaz ) + 6. * ksi ) / ( l * c1z );
140}
141
142
143void Beam3d :: computeGaussPoints()
144{
145 if ( integrationRulesArray.size() == 0 ) {
146 // the gauss point is used only when methods from crosssection and/or material
147 // classes are requested
148 integrationRulesArray.resize(1);
149 integrationRulesArray [ 0 ] = std :: make_unique< GaussIntegrationRule >(1, this, 1, 2);
150 this->giveCrossSection()->setupIntegrationPoints(* integrationRulesArray [ 0 ], this->numberOfGaussPoints, this);
151 }
152}
153
154
155void
156Beam3d :: computeNmatrixAt(const FloatArray &iLocCoord, FloatMatrix &answer)
157// Returns the displacement interpolation matrix {N} of the receiver, eva-
158// luated at gp. Used for numerical calculation of consistent mass
159// matrix. Must contain only interpolation for displacement terms,
160// not for any rotations. (Inertia forces do not work on rotations).
161// r = {u1,v1,w1,fi_x1,fi_y1,fi_z1,u2,v2,w2,fi_x2,fi_y2,fi_21}^T
162{
163 double l, ksi, ksi2, ksi3, kappay, kappaz, c1y, c1z;
164 TimeStep *tStep = this->domain->giveEngngModel()->giveCurrentStep();
165
166 l = this->computeLength();
167 ksi = 0.5 + 0.5 * iLocCoord.at(1);
168 kappay = this->giveKappayCoeff(tStep);
169 kappaz = this->giveKappazCoeff(tStep);
170 c1y = 1. + 2. * kappay;
171 c1z = 1. + 2. * kappaz;
172 ksi2 = ksi * ksi;
173 ksi3 = ksi2 * ksi;
174
175 answer.resize(6, 12);
176 answer.zero();
177
178 answer.at(1, 1) = 1. - ksi;
179 answer.at(1, 7) = ksi;
180 answer.at(2, 2) = ( c1z - 2. * kappaz * ksi - 3. * ksi2 + 2. * ksi3 ) / c1z;
181 answer.at(2, 6) = -l * ( -( 1. + kappaz ) * ksi + ( 2. + kappaz ) * ksi2 - ksi3 ) / c1z;
182 answer.at(2, 8) = ( 2. * kappaz * ksi + 3. * ksi2 - 2. * ksi3 ) / c1z;
183 answer.at(2, 12) = -l * ( kappaz * ksi + ( 1. - kappaz ) * ksi2 - ksi3 ) / c1z;
184 answer.at(3, 3) = ( c1y - 2. * kappay * ksi - 3. * ksi2 + 2. * ksi3 ) / c1y;
185 answer.at(3, 5) = l * ( -( 1. + kappay ) * ksi + ( 2. + kappay ) * ksi2 - ksi3 ) / c1y;
186 answer.at(3, 9) = ( 2. * kappay * ksi + 3. * ksi2 - 2. * ksi3 ) / c1y;
187 answer.at(3, 11) = l * ( kappay * ksi + ( 1. - kappay ) * ksi2 - ksi3 ) / c1y;
188
189 // rotations excluded
190 answer.at(4, 4) = 1. - ksi;
191 answer.at(4, 10) = ksi;
192 answer.at(5, 3) = ( 6. * ksi - 6. * ksi2 ) / ( l * c1y );
193 answer.at(5, 5) = ( c1y - 2. * ( 2. + kappay ) * ksi + 3. * ksi2 ) / c1y;
194 answer.at(5, 9) = -( 6. * ksi - 6. * ksi2 ) / ( l * c1y );
195 answer.at(5, 11) = ( -2. * ( 1. - kappay ) * ksi + 3. * ksi2 ) / c1y;
196 answer.at(6, 2) = -( 6. * ksi - 6. * ksi2 ) / ( l * c1z );
197 answer.at(6, 6) = ( c1z - 2. * ( 2. + kappaz ) * ksi + 3. * ksi2 ) / c1z;
198 answer.at(6, 8) = ( 6. * ksi - 6. * ksi2 ) / ( l * c1z );
199 answer.at(6, 12) = ( -2. * ( 1. - kappaz ) * ksi + 3. * ksi2 ) / c1z;
200}
201
202
203void
204Beam3d :: computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
205{
206 double l = this->computeLength();
207 FloatMatrix B, DB, d;
208 answer.clear();
209 for ( auto &gp : *this->giveDefaultIntegrationRulePtr() ) {
210 this->computeBmatrixAt(gp, B);
211 this->computeConstitutiveMatrixAt(d, rMode, gp, tStep);
212 double dV = gp->giveWeight() * 0.5 * l;
213 DB.beProductOf(d, B);
214 answer.plusProductSymmUpper(B, DB, dV);
215 }
216 answer.symmetrized();
217
218 if ( subsoilMat ) {
219 FloatMatrix k;
220 this->computeSubSoilStiffnessMatrix(k, rMode, tStep);
221 answer.add(k);
222 }
223}
224
225
226void
227Beam3d :: computeBoundaryEdgeLoadVector(FloatArray &answer, BoundaryLoad *load, int edge, CharType type, ValueModeType mode, TimeStep *tStep, bool global)
228{
229 answer.clear();
230
231 if ( edge != 1 ) {
232 OOFEM_ERROR("Beam3D only has 1 edge (the midline) that supports loads. Attempted to apply load to edge %d", edge);
233 }
234
235 if ( type != ExternalForcesVector ) {
236 return;
237 }
238
239 double l = this->computeLength();
240 FloatArray coords, t;
241 FloatMatrix N, T;
242
243 for ( GaussPoint *gp : *this->giveDefaultIntegrationRulePtr() ) {
244 const FloatArray &lcoords = gp->giveNaturalCoordinates();
245 this->computeNmatrixAt(lcoords, N);
246 if ( load->giveFormulationType() == Load :: FT_Entity ) {
247 load->computeValues(t, tStep, lcoords, { D_u, D_v, D_w, R_u, R_v, R_w }, mode);
248 } else {
249 this->computeGlobalCoordinates(coords, lcoords);
250 load->computeValues(t, tStep, coords, { D_u, D_v, D_w, R_u, R_v, R_w }, mode);
251 }
252
253 if ( load->giveCoordSystMode() == Load :: CST_Global ) {
254 if ( this->computeLoadGToLRotationMtrx(T) ) {
255 t.rotatedWith(T, 'n');
256 }
257 }
258
259 double dl = gp->giveWeight() * 0.5 * l;
260 answer.plusProduct(N, t, dl);
261 }
262
263 if ( global ) {
264 // Loads from sets expects global c.s.
266 answer.rotatedWith(T, 't');
267 }
268}
269
270
271int
272Beam3d :: computeLoadGToLRotationMtrx(FloatMatrix &answer)
273{
274 FloatMatrix lcs;
275
276 answer.resize(6, 6);
277 answer.zero();
278
279 this->giveLocalCoordinateSystem(lcs);
280 for ( int i = 1; i <= 3; i++ ) {
281 for ( int j = 1; j <= 3; j++ ) {
282 answer.at(i, j) = lcs.at(i, j);
283 answer.at(3 + i, 3 + j) = lcs.at(i, j);
284 }
285 }
286 return 1;
287}
288
289
290bool
291Beam3d :: computeGtoLRotationMatrix(FloatMatrix &answer)
292{
293 FloatMatrix lcs;
294 int ndofs = computeNumberOfGlobalDofs();
295 answer.resize(ndofs, ndofs);
296 answer.zero();
297
298 this->giveLocalCoordinateSystem(lcs);
299 for ( int i = 1; i <= 3; i++ ) {
300 for ( int j = 1; j <= 3; j++ ) {
301 answer.at(i, j) = lcs.at(i, j);
302 answer.at(i + 3, j + 3) = lcs.at(i, j);
303 answer.at(i + 6, j + 6) = lcs.at(i, j);
304 answer.at(i + 9, j + 9) = lcs.at(i, j);
305 }
306 }
307
308 for ( int i = 13; i <= ndofs; i++ ) {
309 answer.at(i, i) = 1.0;
310 }
311
312 if ( this->hasDofs2Condense() ) {
313 int condensedDofCounter = 0;
314 DofIDItem dofids[] = {
315 D_u, D_v, D_w, R_u, R_v, R_w
316 };
317 FloatMatrix l2p(12, ndofs); // local -> primary
318 l2p.zero();
319 // loop over nodes
320 for ( int inode = 0; inode < 2; inode++ ) {
321 // loop over DOFs
322 for ( int idof = 0; idof < 6; idof++ ) {
323 int eq = inode * 6 + idof + 1;
324 if ( ghostNodes [ inode ] ) {
325 if ( ghostNodes [ inode ]->hasDofID(dofids [ idof ]) ) {
326 condensedDofCounter++;
327 l2p.at(eq, 12 + condensedDofCounter) = 1.0;
328 continue;
329 }
330 }
331 l2p.at(eq, eq) = 1.0;
332 }
333 }
334
335 FloatMatrix g2l(answer);
336 answer.beProductOf(l2p, g2l);
337 }
338
339 return true;
340}
341
342
343
345Beam3d :: B3SSMI_getUnknownsGtoLRotationMatrix() const
346// Returns the rotation matrix for element unknowns
347{
348 FloatMatrix lcs;
349
350 FloatMatrixF<6,6> answer;
351
352 const_cast<Beam3d*>(this)->giveLocalCoordinateSystem(lcs);
353 for ( int i = 1; i <= 3; i++ ) {
354 for ( int j = 1; j <= 3; j++ ) {
355 answer.at(i, j) = lcs.at(i, j);
356 answer.at(i + 3, j + 3) = lcs.at(i, j);
357 }
358 }
359 return answer;
360}
361
362double
363Beam3d :: computeVolumeAround(GaussPoint *gp)
364{
365 return gp->giveWeight() * 0.5 * this->computeLength();
366}
367
368
369int
370Beam3d :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
371{
372 if ( type == IST_BeamForceMomentTensor ) {
373 answer = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveStressVector();
374 return 1;
375 } else if ( type == IST_BeamStrainCurvatureTensor ) {
376 answer = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveStrainVector();
377 return 1;
378 } else if ( type == IST_ShellForceTensor || type == IST_ShellStrainTensor ) {
379 // Order in generalized strain is:
380 // {\eps_x, \gamma_xz, \gamma_xy, \der{phi_x}{x}, \kappa_y, \kappa_z}
381 const FloatArray &help = type == IST_ShellForceTensor ?
384
385 answer.resize(6);
386 answer.at(1) = help.at(1); // nx
387 answer.at(2) = 0.0; // ny
388 answer.at(3) = 0.0; // nz
389 answer.at(4) = 0.0; // vyz
390 answer.at(5) = help.at(2); // vxz
391 answer.at(6) = help.at(3); // vxy
392 return 1;
393 } else if ( type == IST_ShellMomentTensor || type == IST_CurvatureTensor ) {
394 const FloatArray &help = type == IST_ShellMomentTensor ?
397 answer.resize(6);
398 answer.at(1) = help.at(4); // mx
399 answer.at(2) = 0.0; // my
400 answer.at(3) = 0.0; // mz
401 answer.at(4) = 0.0; // myz
402 answer.at(5) = help.at(6); // mxz
403 answer.at(6) = help.at(5); // mxy
404 return 1;
405 } else {
406 return BeamBaseElement :: giveIPValue(answer, gp, type, tStep);
407 }
408}
409
410
411void
412Beam3d :: giveDofManDofIDMask(int inode, IntArray &answer) const
413{
414 answer = {
415 D_u, D_v, D_w, R_u, R_v, R_w
416 };
417}
418
419
420double
421Beam3d :: computeLength()
422{
423 double dx, dy, dz;
424 Node *nodeA, *nodeB;
425
426 if ( length == 0. ) {
427 nodeA = this->giveNode(1);
428 nodeB = this->giveNode(2);
429 dx = nodeB->giveCoordinate(1) - nodeA->giveCoordinate(1);
430 dy = nodeB->giveCoordinate(2) - nodeA->giveCoordinate(2);
431 dz = nodeB->giveCoordinate(3) - nodeA->giveCoordinate(3);
432 length = sqrt(dx * dx + dy * dy + dz * dz);
433 }
434
435 return length;
436}
437
438
439void
440Beam3d :: computeKappaCoeffs(TimeStep *tStep)
441{
442 // kappa_y = (6*E*Iy)/(k*G*A*l^2)
443
444 FloatMatrix d;
445 double l = this->computeLength();
446
447 this->computeConstitutiveMatrixAt(d, ElasticStiffness, integrationRulesArray [ 0 ]->getIntegrationPoint(0), tStep);
448
449 // kappay = 6. * d.at(5, 5) / ( d.at(3, 3) * l * l );
450 // kappaz = 6. * d.at(6, 6) / ( d.at(2, 2) * l * l );
451 if ( d.at(3, 3) != 0. ) {
452 kappay = 6. * d.at(5, 5) / ( d.at(3, 3) * l * l );
453 } else {
454 kappay = 0.;
455 }
456 if ( d.at(2, 2) != 0. ) {
457 kappaz = 6. * d.at(6, 6) / ( d.at(2, 2) * l * l );
458 } else {
459 kappaz = 0.;
460 }
461}
462
463
464double
465Beam3d :: giveKappayCoeff(TimeStep *tStep)
466{
467 if ( kappay < 0.0 ) {
468 this->computeKappaCoeffs(tStep);
469 }
470
471 return kappay;
472}
473
474
475double
476Beam3d :: giveKappazCoeff(TimeStep *tStep)
477{
478 if ( kappaz < 0.0 ) {
479 this->computeKappaCoeffs(tStep);
480 }
481
482 return kappaz;
483}
484
485
486int
487Beam3d :: giveLocalCoordinateSystem(FloatMatrix &answer)
488//
489// returns a unit vectors of local coordinate system at element
490// stored rowwise (mainly used by some materials with ortho and anisotrophy)
491//
492{
493 FloatArray lx, ly, lz, help(3);
494 Node *nodeA, *nodeB;
495 nodeA = this->giveNode(1);
496 nodeB = this->giveNode(2);
497
498 lx.beDifferenceOf( nodeB->giveCoordinates(), nodeA->giveCoordinates() );
499 lx.normalize();
500
501 if ( this->referenceNode ) {
502 Node *refNode = this->giveDomain()->giveNode(this->referenceNode);
503 help.beDifferenceOf( refNode->giveCoordinates(), nodeA->giveCoordinates() );
504
505 lz.beVectorProductOf(lx, help);
506 lz.normalize();
507 } else if ( this->zaxis.giveSize() > 0 ) {
508 lz = this->zaxis;
509 lz.normalize();
510 lz.add(lz.dotProduct(lx), lx);
511 lz.normalize();
512 } else if ( this->yaxis.giveSize() > 0 ) {
513 ly = this->yaxis;
514 ly.normalize();
515 ly.add(ly.dotProduct(lx), lx);
516 ly.normalize();
517 lz.beVectorProductOf(ly, lx);
518 lz.normalize();
519 } else {
520 FloatMatrix rot(3, 3);
521 double theta = referenceAngle * M_PI / 180.0;
522
523 rot.at(1, 1) = cos(theta) + pow(lx.at(1), 2) * ( 1 - cos(theta) );
524 rot.at(1, 2) = lx.at(1) * lx.at(2) * ( 1 - cos(theta) ) - lx.at(3) * sin(theta);
525 rot.at(1, 3) = lx.at(1) * lx.at(3) * ( 1 - cos(theta) ) + lx.at(2) * sin(theta);
526
527 rot.at(2, 1) = lx.at(2) * lx.at(1) * ( 1 - cos(theta) ) + lx.at(3) * sin(theta);
528 rot.at(2, 2) = cos(theta) + pow(lx.at(2), 2) * ( 1 - cos(theta) );
529 rot.at(2, 3) = lx.at(2) * lx.at(3) * ( 1 - cos(theta) ) - lx.at(1) * sin(theta);
530
531 rot.at(3, 1) = lx.at(3) * lx.at(1) * ( 1 - cos(theta) ) - lx.at(2) * sin(theta);
532 rot.at(3, 2) = lx.at(3) * lx.at(2) * ( 1 - cos(theta) ) + lx.at(1) * sin(theta);
533 rot.at(3, 3) = cos(theta) + pow(lx.at(3), 2) * ( 1 - cos(theta) );
534
535 help.at(3) = 1.0; // up-vector
536 // here is ly is used as a temp var
537 if ( fabs( lx.dotProduct(help) ) > 0.999 ) { // Check if it is vertical
538 ly = {
539 0., 1., 0.
540 };
541 } else {
542 ly.beVectorProductOf(lx, help);
543 }
544 lz.beProductOf(rot, ly);
545 lz.normalize();
546 }
547
548 ly.beVectorProductOf(lz, lx);
549 ly.normalize();
550
551 answer.resize(3, 3);
552 answer.zero();
553 for ( int i = 1; i <= 3; i++ ) {
554 answer.at(1, i) = lx.at(i);
555 answer.at(2, i) = ly.at(i);
556 answer.at(3, i) = lz.at(i);
557 }
558
559 return 1;
560}
561
562
563void
564Beam3d :: initializeFrom(InputRecord &ir, int priority)
565{
566 BeamBaseElement :: initializeFrom(ir, priority);
567 ParameterManager &ppm = domain->elementPPM;
568 PM_UPDATE_PARAMETER(yaxis, ppm, ir, this->number, IPK_Beam3d_yaxis, priority) ;
569 PM_UPDATE_PARAMETER(zaxis, ppm, ir, this->number, IPK_Beam3d_zaxis, priority) ;
570 PM_UPDATE_PARAMETER(referenceNode, ppm, ir, this->number, IPK_Beam3d_refnode, priority) ;
572 PM_UPDATE_PARAMETER(subsoilMat, ppm, ir, this->number, IPK_Beam3d_subsoilmat, priority) ;
574
575}
576
577void
578Beam3d :: postInitialize()
579{
580 BeamBaseElement :: postInitialize();
581 ParameterManager &ppm = domain->elementPPM;
582 if ( ppm.checkIfSet(this->number, IPK_Beam3d_refnode.getIndex())) {
583 if ( referenceNode == 0 ) {
584 OOFEM_WARNING("wrong reference node specified. Using default orientation.");
585 }
586 }
587 bool yaxis = ppm.checkIfSet(this->number, IPK_Beam3d_yaxis.getIndex());
588 bool zaxis = ppm.checkIfSet(this->number, IPK_Beam3d_zaxis.getIndex());
589 bool refnode = ppm.checkIfSet(this->number, IPK_Beam3d_refnode.getIndex());
590 bool refangle = ppm.checkIfSet(this->number, IPK_Beam3d_refangle.getIndex());
591
592 if (!(yaxis || zaxis || refnode || refangle)) {
593 throw ComponentInputException(ComponentInputException::ComponentType::ctElement, this->number, "Beam3d: axis, reference node, or angle not set");
594 }
595
596 if ( ppm.checkIfSet(this->number, IPK_Beam3d_dofsToCondense.getIndex()) ) {
597 auto _val = ppm.getTempParam(this->number, IPK_Beam3d_dofsToCondense.getIndex());
598 IntArray val (std::get<IntArray>(*_val));
599 if ( val.giveSize() >= 12 ) {
600 throw ComponentInputException(IPK_Beam3d_dofsToCondense.getName(), ComponentInputException::ComponentType::ctElement, this->number, "wrong input data for condensed dofs");
601 }
602
603 //dofsToCondense = new IntArray(val);
604 DofIDItem mask[] = {
605 D_u, D_v, D_w, R_u, R_v, R_w
606 };
607 this->numberOfCondensedDofs = val.giveSize();
608 for ( int i = 1; i <= val.giveSize(); i++ ) {
609 if ( val.at(i) <= 6 ) {
610 if ( ghostNodes [ 0 ] == NULL ) {
611 ghostNodes [ 0 ] = new ElementDofManager(1, giveDomain(), this);
612 }
613 ghostNodes [ 0 ]->appendDof( new MasterDof(ghostNodes [ 0 ], mask [ val.at(i) - 1 ]) );
614 } else {
615 if ( ghostNodes [ 1 ] == NULL ) {
616 ghostNodes [ 1 ] = new ElementDofManager(2, giveDomain(), this);
617 }
618 ghostNodes [ 1 ]->appendDof( new MasterDof(ghostNodes [ 1 ], mask [ val.at(i) - 7 ]) );
619 }
620 }
621 } else {
622 //dofsToCondense = NULL;
623 }
624}
625
626
627void
628Beam3d :: giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
629{
630#if 0
631 FloatMatrix stiffness;
632 FloatArray u;
633
634 this->computeStiffnessMatrix(stiffness, SecantStiffness, tStep);
635 this->computeVectorOf(VM_Total, tStep, u);
636 answer.beProductOf(stiffness, u);
637#else
638 BeamBaseElement :: giveInternalForcesVector(answer, tStep, useUpdatedGpRecord);
639 if ( subsoilMat ) {
640 // add internal forces due to subsoil interaction
641 // @todo: linear subsoil assumed here; more general approach should integrate internal forces
642 FloatMatrix k;
643 FloatArray u, F;
644 this->computeSubSoilStiffnessMatrix(k, TangentStiffness, tStep);
645 this->computeVectorOf(VM_Total, tStep, u);
646 F.beProductOf(k, u);
647 answer.add(F);
648 }
649#endif
650}
651
652
653void
654Beam3d :: computeConstitutiveMatrixAt(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep)
655{
656 answer = this->giveStructuralCrossSection()->give3dBeamStiffMtrx(rMode, gp, tStep);
657}
658
659
660void
661Beam3d :: computeStressVector(FloatArray &answer, const FloatArray &strain, GaussPoint *gp, TimeStep *tStep)
662{
663 answer = this->giveStructuralCrossSection()->giveGeneralizedStress_Beam3d(strain, gp, tStep);
664}
665
666
667void
668Beam3d :: giveEndForcesVector(FloatArray &answer, TimeStep *tStep)
669{
670 // computes exact global end-forces vector
671 FloatArray loadEndForces;
672
673 this->giveInternalForcesVector(answer, tStep);
674
675 // add exact end forces due to nonnodal loading
676 this->computeLocalForceLoadVector(loadEndForces, tStep, VM_Total); // will compute only contribution of loads applied directly on receiver (not using sets)
677 if ( loadEndForces.giveSize() ) {
678 answer.subtract(loadEndForces);
679 }
680 /*
681 * if (subsoilMat) {
682 * // @todo: linear subsoil assumed here; more general approach should integrate internal forces
683 * FloatMatrix k;
684 * FloatArray u, F;
685 * this->computeSubSoilStiffnessMatrix(k, TangentStiffness, tStep);
686 * this->computeVectorOf(VM_Total, tStep, u);
687 * F.beProductOf(k, u);
688 * answer.add(F);
689 * }
690 */
691}
692
693
694void
695Beam3d :: printOutputAt(FILE *File, TimeStep *tStep)
696{
697 FloatArray rl, Fl;
698
699 fprintf( File, "beam element %d (%8d) :\n", this->giveLabel(), this->giveNumber() );
700
701 // ask for global element displacement vector
702 this->computeVectorOf(VM_Total, tStep, rl);
703 // ask for global element end forces vector
704 this->giveEndForcesVector(Fl, tStep);
705
706 fprintf(File, " local displacements ");
707 for ( auto &val : rl ) {
708 fprintf(File, " %.4e", val);
709 }
710
711 fprintf(File, "\n local end forces ");
712 for ( auto &val : Fl ) {
713 fprintf(File, " %.4e", val);
714 }
715
716 fprintf(File, "\n");
717
718 for ( auto &iRule : integrationRulesArray ) {
719 iRule->printOutputAt(File, tStep);
720 }
721}
722
723
724void
725Beam3d :: computeBodyLoadVectorAt(FloatArray &answer, Load *load, TimeStep *tStep, ValueModeType mode)
726{
727 FloatArray lc(1);
728 BeamBaseElement :: computeBodyLoadVectorAt(answer, load, tStep, mode);
729 answer.times( this->giveCrossSection()->give(CS_Area, lc, this) );
730}
731
732
733void
734Beam3d :: computeConsistentMassMatrix(FloatMatrix &answer, TimeStep *tStep, double &mass, const double *ipDensity)
735{
736 if (0) {
737 StructuralElement::computeConsistentMassMatrix(answer, tStep, mass, ipDensity);
738 GaussPoint *gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
739 double area = this->giveCrossSection()->give(CS_Area, gp); // constant area assumed
740 answer.times(area);
741 mass *= area;
742 return;
743 } else {
744
745
746 FloatMatrix stiff;
747 GaussPoint *gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
748
749 /*
750 * SructuralElement::computeMassMatrix(answer, tStep);
751 * answer.times(this->giveCrossSection()->give('A'));
752 */
753 double l = this->computeLength();
754 double kappay = this->giveKappayCoeff(tStep);
755 double kappaz = this->giveKappazCoeff(tStep);
756 double kappay2 = kappay * kappay;
757 double kappaz2 = kappaz * kappaz;
758
759 double density = this->giveStructuralCrossSection()->give('d', gp); // constant density assumed
760 if ( ipDensity != NULL ) {
761 // Override density if desired
762 density = * ipDensity;
763 }
764
765 double area = this->giveCrossSection()->give(CS_Area, gp); // constant area assumed
766 double Ikk = this->giveCrossSection()->give(CS_InertiaMomentY, gp) +
767 this->giveCrossSection()->give(CS_InertiaMomentZ, gp); // polar moment of inertia
768 double c2y = ( area * density ) / ( ( 1. + 2. * kappay ) * ( 1. + 2. * kappay ) );
769 double c2z = ( area * density ) / ( ( 1. + 2. * kappaz ) * ( 1. + 2. * kappaz ) );
770 double c1 = ( area * density );
771
772 answer.resize(12, 12);
773 answer.zero();
774
775 answer.at(1, 1) = c1 * l / 3.0;
776 answer.at(1, 7) = c1 * l / 6.0;
777 answer.at(2, 2) = c2z * l * ( 13. / 35. + 7. * kappaz / 5. + 4. * kappaz2 / 3. );
778 answer.at(2, 6) = c2z * l * l * ( 11. / 210. + kappaz * 11. / 60. + kappaz2 / 6. );
779 answer.at(2, 8) = c2z * l * ( 9. / 70. + kappaz * 3. / 5. + kappaz2 * 2. / 3. );
780 answer.at(2, 12) = -c2z * l * l * ( 13. / 420. + kappaz * 3. / 20. + kappaz2 / 6. );
781 answer.at(3, 3) = c2y * l * ( 13. / 35. + 7. * kappay / 5. + 4. * kappay2 / 3. );
782 answer.at(3, 5) = -c2y * l * l * ( 11. / 210. + kappay * 11. / 60. + kappay2 / 6. );
783 answer.at(3, 9) = c2y * l * ( 9. / 70. + kappay * 3. / 5. + kappay2 * 2. / 3. );
784 answer.at(3, 11) = c2y * l * l * ( 13. / 420. + kappay * 3. / 20. + kappay2 / 6. );
785 answer.at(4,4) = Ikk*density*l/3.;
786 answer.at(4,10) = Ikk*density*l/6.;
787 answer.at(5, 5) = c2y * l * l * l * ( 1. / 105. + kappay / 30. + kappay2 / 30. );
788 answer.at(5, 9) = -c2y * l * l * ( 13. / 420. + kappay * 3. / 20. + kappay2 / 6. );
789 answer.at(5, 11) = -c2y * l * l * l * ( 1. / 140. + kappay / 30. + kappay2 / 30. );
790 answer.at(6, 6) = c2z * l * l * l * ( 1. / 105. + kappaz / 30. + kappaz2 / 30. );
791 answer.at(6, 8) = c2z * l * l * ( 13. / 420. + kappaz * 3. / 20. + kappaz2 / 6. );
792 answer.at(6, 12) = -c2z * l * l * l * ( 1. / 140. + kappaz / 30. + kappaz2 / 30. );
793
794
795 answer.at(7, 7) = c1 * l / 3.0;
796 answer.at(8, 8) = c2z * l * ( 13. / 35. + kappaz * 7. / 5. + kappaz2 * 4. / 3. );
797 answer.at(8, 12) = -c2z * l * l * ( 11. / 210. + kappaz * 11. / 60. + kappaz2 / 6. );
798 answer.at(9, 9) = c2y * l * ( 13. / 35. + kappay * 7. / 5. + kappay2 * 4. / 3. );
799 answer.at(9, 11) = c2y * l * l * ( 11. / 210. + kappay * 11. / 60. + kappay2 / 6. );
800 answer.at(10,10) = Ikk*density*l/3.;
801 answer.at(11, 11) = c2y * l * l * l * ( 1. / 105. + kappay / 30. + kappay2 / 30. );
802 answer.at(12, 12) = c2z * l * l * l * ( 1. / 105. + kappaz / 30. + kappaz2 / 30. );
803
804 answer.symmetrized();
805
806 mass = area * l * density;
807 }
808}
809
810
811int
812Beam3d :: computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords)
813{
814 double ksi, n1, n2;
815
816 ksi = lcoords.at(1);
817 n1 = ( 1. - ksi ) * 0.5;
818 n2 = ( 1. + ksi ) * 0.5;
819
820 answer.resize(3);
821 answer.at(1) = n1 * this->giveNode(1)->giveCoordinate(1) + n2 *this->giveNode(2)->giveCoordinate(1);
822 answer.at(2) = n1 * this->giveNode(1)->giveCoordinate(2) + n2 *this->giveNode(2)->giveCoordinate(2);
823 answer.at(3) = n1 * this->giveNode(1)->giveCoordinate(3) + n2 *this->giveNode(2)->giveCoordinate(3);
824
825 return 1;
826}
827
828
829void
830Beam3d :: computeInitialStressMatrix(FloatMatrix &answer, TimeStep *tStep)
831{
832 // computes initial stress matrix of receiver (or geometric stiffness matrix)
833
834 FloatMatrix stiff;
835 FloatArray endForces;
836
837 double l = this->computeLength();
838 double kappay = this->giveKappayCoeff(tStep);
839 double kappaz = this->giveKappazCoeff(tStep);
840 double kappay2 = kappay * kappay;
841 double kappaz2 = kappaz * kappaz;
842 double minVal;
843 double denomy = ( 1. + 2. * kappay ) * ( 1. + 2. * kappay ), denomz = ( 1. + 2. * kappaz ) * ( 1. + 2. * kappaz );
844 double N;
845
846 answer.resize(12, 12);
847 answer.zero();
848
849 answer.at(2, 2) = ( 4. * kappaz2 + 4. * kappaz + 6. / 5. ) / denomz;
850 answer.at(2, 6) = ( l / 10. ) / denomz;
851 answer.at(2, 8) = ( -4. * kappaz2 - 4. * kappaz - 6. / 5. ) / denomz;
852 answer.at(2, 12) = ( l / 10. ) / denomz;
853
854 answer.at(3, 3) = ( 4. * kappay2 + 4. * kappay + 6. / 5. ) / denomy;
855 answer.at(3, 5) = ( -l / 10. ) / denomy;
856 answer.at(3, 9) = ( -4. * kappay2 - 4. * kappay - 6. / 5. ) / denomy;
857 answer.at(3, 11) = ( -l / 10. ) / denomy;
858
859 answer.at(5, 5) = l * l * ( kappay2 / 3. + kappay / 3. + 2. / 15. ) / denomy;
860 answer.at(5, 9) = ( l / 10. ) / denomy;
861 answer.at(5, 11) = -l * l * ( kappay2 / 3. + kappay / 3. + 1. / 30. ) / denomy;
862
863 answer.at(6, 6) = l * l * ( kappaz2 / 3. + kappaz / 3. + 2. / 15. ) / denomz;
864 answer.at(6, 8) = ( -l / 10. ) / denomz;
865 answer.at(6, 12) = -l * l * ( kappaz2 / 3. + kappaz / 3. + 1. / 30. ) / denomz;
866
867 answer.at(8, 8) = ( 4. * kappaz2 + 4. * kappaz + 6. / 5. ) / denomz;
868 answer.at(8, 12) = ( -l / 10. ) / denomz;
869
870 answer.at(9, 9) = ( 4. * kappay2 + 4. * kappay + 6. / 5. ) / denomy;
871 answer.at(9, 11) = ( l / 10. ) / denomy;
872
873 answer.at(11, 11) = l * l * ( kappay2 / 3. + kappay / 3. + 2. / 15. ) / denomy;
874 answer.at(12, 12) = l * l * ( kappaz2 / 3. + kappaz / 3. + 2. / 15. ) / denomz;
875
876 minVal = min( fabs( answer.at(2, 2) ), fabs( answer.at(3, 3) ) );
877 minVal = min( minVal, fabs( answer.at(5, 5) ) );
878 minVal = min( minVal, fabs( answer.at(6, 6) ) );
879
880 answer.at(1, 1) = minVal / 1000.;
881 answer.at(1, 7) = -answer.at(1, 1);
882 answer.at(7, 7) = answer.at(1, 1);
883
884 answer.at(4, 4) = minVal / 1000.;
885 answer.at(4, 10) = -answer.at(4, 4);
886 answer.at(10, 10) = answer.at(4, 4);
887
888
889
890 answer.symmetrized();
891 // ask end forces in g.c.s
892 this->giveEndForcesVector(endForces, tStep);
893
894 N = ( -endForces.at(1) + endForces.at(7) ) / 2.;
895 answer.times(N / l);
896
897 //answer.beLumpedOf (mass);
898}
899
900
901void
902Beam3d :: computeLumpedInitialStressMatrix(FloatMatrix &answer, TimeStep *tStep)
903{
904 // computes initial stress matrix of receiver (or geometric stiffness matrix)
905
906 FloatMatrix stiff;
907 FloatArray endForces;
908
909 double l = this->computeLength();
910 double N;
911
912 answer.resize(12, 12);
913 answer.zero();
914
915 answer.at(2, 2) = 1.;
916 answer.at(2, 8) =-1.;
917 answer.at(8, 2) =-1.;
918 answer.at(8, 8) = 1.;
919
920 answer.at(3, 3) = 1.;
921 answer.at(3, 9) =-1.;
922 answer.at(9, 3) =-1.;
923 answer.at(9, 9) = 1.;
924
925
926 // ask end forces in g.c.s
927 // ask end forces in g.c.s
928 this->giveEndForcesVector(endForces, tStep);
929 N = ( -endForces.at(1) + endForces.at(7) ) / 2.;
930 answer.times(N / l);
931
932}
933
934
935void
936Beam3d :: FiberedCrossSectionInterface_computeStrainVectorInFiber(FloatArray &answer, const FloatArray &masterGpStrain,
937 GaussPoint *slaveGp, TimeStep *tStep)
938{
939 double layerYCoord, layerZCoord;
940
941 layerZCoord = slaveGp->giveNaturalCoordinate(2);
942 layerYCoord = slaveGp->giveNaturalCoordinate(1);
943
944 answer.resize(3); // {Exx,GMzx,GMxy}
945
946 answer.at(1) = masterGpStrain.at(1) + masterGpStrain.at(5) * layerZCoord - masterGpStrain.at(6) * layerYCoord;
947 answer.at(2) = masterGpStrain.at(2) + layerYCoord * masterGpStrain.at(4);
948 answer.at(3) = masterGpStrain.at(3) - layerZCoord * masterGpStrain.at(4);
949}
950
951
952Interface *
953Beam3d :: giveInterface(InterfaceType interface)
954{
955 if ( interface == FiberedCrossSectionInterfaceType ) {
956 return static_cast< FiberedCrossSectionInterface * >(this);
957 } else if ( interface == Beam3dSubsoilMaterialInterfaceType ) {
958 return static_cast< Beam3dSubsoilMaterialInterface * >(this);
959 } else if ( interface == VTKXMLExportModuleElementInterfaceType ) {
960 return static_cast< VTKXMLExportModuleElementInterface * >(this);
961 }
962
963 return NULL;
964}
965
966
967void
968Beam3d :: updateLocalNumbering(EntityRenumberingFunctor &f)
969{
970 BeamBaseElement :: updateLocalNumbering(f);
971 if ( this->referenceNode ) {
973 }
974}
975
976
977#ifdef __OOFEG
978void Beam3d :: drawRawGeometry(oofegGraphicContext &gc, TimeStep *tStep)
979{
980 GraphicObj *go;
981
982 if ( !gc.testElementGraphicActivity(this) ) {
983 return;
984 }
985
986 // if (!go) { // create new one
987 WCRec p [ 2 ]; /* poin */
988 EASValsSetLineWidth(OOFEG_RAW_GEOMETRY_WIDTH);
989 EASValsSetColor( gc.getElementColor() );
990 EASValsSetLayer(OOFEG_RAW_GEOMETRY_LAYER);
991 p [ 0 ].x = ( FPNum ) this->giveNode(1)->giveCoordinate(1);
992 p [ 0 ].y = ( FPNum ) this->giveNode(1)->giveCoordinate(2);
993 p [ 0 ].z = ( FPNum ) this->giveNode(1)->giveCoordinate(3);
994 p [ 1 ].x = ( FPNum ) this->giveNode(2)->giveCoordinate(1);
995 p [ 1 ].y = ( FPNum ) this->giveNode(2)->giveCoordinate(2);
996 p [ 1 ].z = ( FPNum ) this->giveNode(2)->giveCoordinate(3);
997 go = CreateLine3D(p);
998 EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | LAYER_MASK, go);
999 EGAttachObject(go, ( EObjectP ) this);
1000 EMAddGraphicsToModel(ESIModel(), go);
1001}
1002
1003
1004void Beam3d :: drawDeformedGeometry(oofegGraphicContext &gc, TimeStep *tStep, UnknownType type)
1005{
1006 GraphicObj *go;
1007
1008 if ( !gc.testElementGraphicActivity(this) ) {
1009 return;
1010 }
1011
1012 double defScale = gc.getDefScale();
1013 // if (!go) { // create new one
1014 WCRec p [ 2 ]; /* poin */
1015 EASValsSetLineWidth(OOFEG_DEFORMED_GEOMETRY_WIDTH);
1016 EASValsSetColor( gc.getDeformedElementColor() );
1017 EASValsSetLayer(OOFEG_DEFORMED_GEOMETRY_LAYER);
1018 p [ 0 ].x = ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(1, tStep, defScale);
1019 p [ 0 ].y = ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(2, tStep, defScale);
1020 p [ 0 ].z = ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(3, tStep, defScale);
1021
1022 p [ 1 ].x = ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(1, tStep, defScale);
1023 p [ 1 ].y = ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(2, tStep, defScale);
1024 p [ 1 ].z = ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(3, tStep, defScale);
1025 go = CreateLine3D(p);
1026 EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | LAYER_MASK, go);
1027 EMAddGraphicsToModel(ESIModel(), go);
1028}
1029#endif
1030
1031void
1032Beam3d :: computeSubSoilNMatrixAt(GaussPoint *gp, FloatMatrix &answer)
1033{
1034 // only winkler model supported now (passing only unknown interpolation)
1035 this->computeNmatrixAt(gp->giveNaturalCoordinates(), answer);
1036}
1037
1038
1039void
1040Beam3d :: computeSubSoilStiffnessMatrix(FloatMatrix &answer,
1041 MatResponseMode rMode, TimeStep *tStep)
1042{
1043 double l = this->computeLength();
1044 FloatMatrix N, DN, d;
1045 answer.clear();
1046 for ( GaussPoint *gp : *this->giveDefaultIntegrationRulePtr() ) {
1047 this->computeSubSoilNMatrixAt(gp, N);
1048 d = static_cast<StructuralMaterial *>(this->domain->giveMaterial(subsoilMat))->give3dBeamSubSoilStiffMtrx(rMode, gp, tStep);
1049 double dV = gp->giveWeight() * 0.5 * l;
1050 DN.beProductOf(d, N);
1051 answer.plusProductSymmUpper(N, DN, dV);
1052 }
1053 answer.symmetrized();
1054}
1055
1056int
1057Beam3d :: computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords, const FloatArray &pCoords)
1058{
1059 double ksi, n1, n2;
1060
1061 ksi = lcoords.at(1);
1062 n1 = ( 1. - ksi ) * 0.5;
1063 n2 = ( 1. + ksi ) * 0.5;
1064
1065 answer.resize(3);
1066 answer.at(1) = n1 * this->giveNode(1)->giveCoordinate(1) + n2 *pCoords.at(1);
1067 answer.at(2) = n1 * this->giveNode(1)->giveCoordinate(2) + n2 *pCoords.at(2);
1068 answer.at(3) = n1 * this->giveNode(1)->giveCoordinate(3) + n2 *pCoords.at(3);
1069
1070 return 1;
1071}
1072
1073void
1074Beam3d :: giveInternalForcesVectorAtPoint(FloatArray &answer, TimeStep *tStep, FloatArray &coords)
1075{
1076 // computes exact global end-forces vector
1077 FloatArray loadEndForces, iF;
1078 IntArray leftIndx = {
1079 1, 2, 3, 4, 5, 6
1080 };
1081 this->giveEndForcesVector(iF, tStep);
1082
1083 answer.beSubArrayOf(iF, leftIndx);
1084 Node *nodeA;
1085
1086 nodeA = this->giveNode(1);
1087 double dx = nodeA->giveCoordinate(1) - coords.at(1);
1088 double dy = nodeA->giveCoordinate(2) - coords.at(2);
1089 double dz = nodeA->giveCoordinate(3) - coords.at(3);
1090 double ds = sqrt(dx * dx + dy * dy + dz * dz);
1091
1092 answer.at(5) += iF.at(3) * ds;
1093 answer.at(6) -= iF.at(2) * ds;
1094
1095
1096
1097 // loop over body load array first
1098 int nBodyLoads = this->giveBodyLoadArray()->giveSize();
1099 FloatArray help;
1100
1101 for ( int i = 1; i <= nBodyLoads; i++ ) {
1102 int id = bodyLoadArray.at(i);
1103 Load *load = domain->giveLoad(id);
1104 bcGeomType ltype = load->giveBCGeoType();
1105 if ( ( ltype == BodyLoadBGT ) && ( load->giveBCValType() == ForceLoadBVT ) ) {
1106 this->computeInternalForcesFromBodyLoadVectorAtPoint(help, load, tStep, VM_Total, coords, ds); // this one is local
1107 answer.add(help);
1108 } else {
1109 if ( load->giveBCValType() != TemperatureBVT && load->giveBCValType() != EigenstrainBVT ) {
1110 // temperature and eigenstrain is handled separately at computeLoadVectorAt subroutine
1111 OOFEM_ERROR("body load %d is of unsupported type (%d)", id, ltype);
1112 }
1113 }
1114 }
1115
1116 // loop over boundary load array
1117 int nBoundaryLoads = this->giveBoundaryLoadArray()->giveSize() / 2;
1118 for ( int i = 1; i <= nBoundaryLoads; i++ ) {
1119 int n = boundaryLoadArray.at(1 + ( i - 1 ) * 2);
1120 int id = boundaryLoadArray.at(i * 2);
1121 Load *load = domain->giveLoad(n);
1122 BoundaryLoad *bLoad;
1123 if ( ( bLoad = dynamic_cast< BoundaryLoad * >(load) ) ) {
1124 bcGeomType ltype = load->giveBCGeoType();
1125 if ( ltype == EdgeLoadBGT ) {
1127 ExternalForcesVector, VM_Total, tStep, coords, ds, false);
1128 answer.add(help);
1129 } else {
1130 OOFEM_ERROR("boundary load %d is of unsupported type (%d)", id, ltype);
1131 }
1132 }
1133 }
1134 // add exact end forces due to nonnodal loading
1135 // this->computeForceLoadVectorAt(loadEndForces, tStep, VM_Total, coords); // will compute only contribution of loads applied directly on receiver (not using sets)
1136 if ( loadEndForces.giveSize() ) {
1137 answer.subtract(loadEndForces);
1138 }
1139
1140 // add exact end forces due to nonnodal loading applied indirectly (via sets)
1141 BCTracker *bct = this->domain->giveBCTracker();
1142 BCTracker :: entryListType bcList = bct->getElementRecords(this->number);
1143
1144 for ( BCTracker :: entryListType :: iterator it = bcList.begin(); it != bcList.end(); ++it ) {
1145 GeneralBoundaryCondition *bc = this->domain->giveBc( ( * it ).bcNumber );
1146 BodyLoad *bodyLoad;
1147 BoundaryLoad *boundaryLoad;
1148 if ( bc->isImposed(tStep) ) {
1149 if ( ( bodyLoad = dynamic_cast< BodyLoad * >(bc) ) ) { // body load
1150 this->computeInternalForcesFromBodyLoadVectorAtPoint(help, bodyLoad, tStep, VM_Total, coords, ds); // this one is local
1151 //answer.subtract(help);
1152 } else if ( ( boundaryLoad = dynamic_cast< BoundaryLoad * >(bc) ) ) {
1153 // compute Boundary Edge load vector in GLOBAL CS !!!!!!!
1154 this->computeInternalForcesFromBoundaryEdgeLoadVectorAtPoint(help, boundaryLoad, ( * it ).boundaryId,
1155 ExternalForcesVector, VM_Total, tStep, coords, ds, false);
1156 }
1157 answer.add(help);
1158 }
1159 }
1160
1161
1162
1163
1164 if ( subsoilMat ) {
1165 // @todo: linear subsoil assumed here; more general approach should integrate internal forces
1166 FloatMatrix k;
1167 FloatArray u, F;
1168 this->computeSubSoilStiffnessMatrix(k, TangentStiffness, tStep);
1169 this->computeVectorOf(VM_Total, tStep, u);
1170 F.beProductOf(k, u);
1171 answer.add(F);
1172 }
1173
1174
1175 answer.times(-1);
1176}
1177
1178
1179void
1180Beam3d :: computeInternalForcesFromBoundaryEdgeLoadVectorAtPoint(FloatArray &answer, BoundaryLoad *load, int edge, CharType type, ValueModeType mode, TimeStep *tStep, FloatArray &pointCoords, double ds, bool global)
1181{
1182 answer.clear();
1183
1184 if ( edge != 1 ) {
1185 OOFEM_ERROR("Beam3D only has 1 edge (the midline) that supports loads. Attempted to apply load to edge %d", edge);
1186 }
1187
1188 if ( type != ExternalForcesVector ) {
1189 return;
1190 }
1191
1192 FloatArray coords, t;
1193 FloatMatrix T;
1194
1195
1196 for ( GaussPoint *gp : *this->giveDefaultIntegrationRulePtr() ) {
1197 const FloatArray &lcoords = gp->giveNaturalCoordinates();
1198 this->computeGlobalCoordinates(coords, lcoords, pointCoords);
1199 if ( load->giveFormulationType() == Load :: FT_Entity ) {
1200 load->computeValues(t, tStep, lcoords, { D_u, D_v, D_w, R_u, R_v, R_w }, mode);
1201 } else {
1202 load->computeValues(t, tStep, coords, { D_u, D_v, D_w, R_u, R_v, R_w }, mode);
1203 }
1204
1205 if ( load->giveCoordSystMode() == Load :: CST_Global ) {
1206 if ( this->computeLoadGToLRotationMtrx(T) ) {
1207 t.rotatedWith(T, 'n');
1208 }
1209 }
1210
1211
1212 double dl = gp->giveWeight() * 0.5 * ds;
1213 FloatArray f;
1214 f = t;
1215 f.at(5) += f.at(3) * ( lcoords.at(1) + 1 ) * ds / 2;
1216 f.at(6) -= f.at(2) * ( lcoords.at(1) + 1 ) * ds / 2;
1217 answer.add(dl, f);
1218 }
1219
1220 if ( global ) {
1221 // Loads from sets expects global c.s.
1223 answer.rotatedWith(T, 't');
1224 }
1225}
1226
1227void
1228Beam3d :: computeInternalForcesFromBodyLoadVectorAtPoint(FloatArray &answer, Load *forLoad, TimeStep *tStep, ValueModeType mode, FloatArray &pointCoords, double ds)
1229// Computes numerically the load vector of the receiver due to the body
1230// loads, at tStep.
1231// load is assumed to be in global cs.
1232// load vector is then transformed to coordinate system in each node.
1233// (should be global coordinate system, but there may be defined
1234// different coordinate system in each node)
1235{
1236 double dens, dV;
1237 FloatArray force, ntf;
1238 FloatMatrix n, T;
1239 FloatArray lc(1);
1240
1241 if ( ( forLoad->giveBCGeoType() != BodyLoadBGT ) || ( forLoad->giveBCValType() != ForceLoadBVT ) ) {
1242 OOFEM_ERROR("unknown load type");
1243 }
1244
1245 // note: force is assumed to be in global coordinate system.
1246 forLoad->computeComponentArrayAt(force, tStep, mode);
1247 force.times( this->giveCrossSection()->give(CS_Area, lc, this) );
1248 // transform from global to element local c.s
1249 if ( this->computeLoadGToLRotationMtrx(T) ) {
1250 force.rotatedWith(T, 'n');
1251 }
1252
1253 answer.clear();
1254
1255 if ( force.giveSize() ) {
1256 for ( GaussPoint *gp : *this->giveDefaultIntegrationRulePtr() ) {
1257 const FloatArray &lcoords = gp->giveNaturalCoordinates();
1258 this->computeNmatrixAt(gp->giveSubPatchCoordinates(), n);
1259 dV = gp->giveWeight() * 0.5 * ds;
1260 dens = this->giveCrossSection()->give('d', gp);
1261 FloatArray iF;
1262 iF = force;
1263 iF.at(5) += force.at(3) * ( lcoords.at(1) + 1 ) * ds / 2;
1264 iF.at(6) -= force.at(2) * ( lcoords.at(1) + 1 ) * ds / 2;
1265 answer.add(dV * dens, iF);
1266 }
1267 } else {
1268 return;
1269 }
1270}
1271
1272
1273void
1274Beam3d :: giveCompositeExportData(std :: vector< ExportRegion > &vtkPieces, IntArray &primaryVarsToExport, IntArray &internalVarsToExport, IntArray cellVarsToExport, TimeStep *tStep)
1275{
1276 // divide element into several small ones
1277 vtkPieces.resize(1);
1278 vtkPieces [ 0 ].setNumberOfCells(Beam3d_nSubBeams);
1279 int nNodes = 2 * Beam3d_nSubBeams;
1280 vtkPieces [ 0 ].setNumberOfNodes(nNodes);
1281 FloatArray nodeXi(nNodes), xi(1);
1282
1283 Node *nodeA, *nodeB;
1284 nodeA = this->giveNode(1);
1285 nodeB = this->giveNode(2);
1286 double dx = ( nodeB->giveCoordinate(1) - nodeA->giveCoordinate(1) ) / Beam3d_nSubBeams;
1287 double dy = ( nodeB->giveCoordinate(2) - nodeA->giveCoordinate(2) ) / Beam3d_nSubBeams;
1288 double dz = ( nodeB->giveCoordinate(3) - nodeA->giveCoordinate(3) ) / Beam3d_nSubBeams;
1289 FloatArray coords(3);
1290 int nodeNumber = 1;
1291 int val = 1;
1292 int offset = 0;
1293 IntArray connectivity(2);
1294 for ( int i = 0; i < Beam3d_nSubBeams; i++ ) {
1295 for ( int j = 0; j < 2; j++ ) {
1296 coords.at(1) = nodeA->giveCoordinate(1) + ( i + j ) * dx;
1297 coords.at(2) = nodeA->giveCoordinate(2) + ( i + j ) * dy;
1298 coords.at(3) = nodeA->giveCoordinate(3) + ( i + j ) * dz;
1299 vtkPieces [ 0 ].setNodeCoords(nodeNumber, coords);
1300 nodeXi.at(nodeNumber) = -1.0 + ( 2.0 / Beam3d_nSubBeams ) * ( i + j );
1301 nodeNumber++;
1302 connectivity.at(j + 1) = val++;
1303 }
1304 vtkPieces [ 0 ].setConnectivity(i + 1, connectivity);
1305 offset += 2;
1306 vtkPieces [ 0 ].setOffset(i + 1, offset);
1307 vtkPieces [ 0 ].setCellType(i + 1, 3);
1308 }
1309
1310 InternalStateType isttype;
1311 int n = internalVarsToExport.giveSize();
1312 vtkPieces [ 0 ].setNumberOfInternalVarsToExport(internalVarsToExport, nNodes);
1313 for ( int i = 1; i <= n; i++ ) {
1314 isttype = ( InternalStateType ) internalVarsToExport.at(i);
1315 for ( int nN = 1; nN <= nNodes; nN++ ) {
1316 if ( isttype == IST_BeamForceMomentTensor ) {
1317 FloatArray coords = vtkPieces [ 0 ].giveNodeCoords(nN);
1318 FloatArray endForces;
1319 this->giveInternalForcesVectorAtPoint(endForces, tStep, coords);
1320 vtkPieces [ 0 ].setInternalVarInNode(isttype, nN, endForces);
1321 } else if ( isttype == IST_X_LCS || isttype == IST_Y_LCS || isttype == IST_Z_LCS ) {
1322 FloatArray answer;
1323 this->giveLocalCoordinateSystemVector(isttype, answer);
1324 vtkPieces[0].setInternalVarInNode(isttype, nN, answer);
1325 } else {
1326 fprintf( stderr, "VTKXMLExportModule::exportIntVars: unsupported variable type %s\n", __InternalStateTypeToString(isttype) );
1327 }
1328 }
1329 }
1330
1331 n = primaryVarsToExport.giveSize();
1332 vtkPieces [ 0 ].setNumberOfPrimaryVarsToExport(primaryVarsToExport, nNodes);
1333 for ( int i = 1; i <= n; i++ ) {
1334 UnknownType utype = ( UnknownType ) primaryVarsToExport.at(i);
1335 if ( utype == DisplacementVector ) {
1336 FloatMatrix Tgl, n;
1337 FloatArray d(3);
1338
1340 for ( int nN = 1; nN <= nNodes; nN++ ) {
1341 FloatArray u, dl, dg;
1342 this->computeVectorOf(VM_Total, tStep, u);
1343 xi.at(1) = nodeXi.at(nN);
1344 this->computeNmatrixAt(xi, n);
1345 dl.beProductOf(n, u); // local interpolated displacement
1346 dg.beTProductOf(Tgl, dl); // local displacement tranformed to global c.s.
1347 d.at(1) = dg.at(1);
1348 d.at(2) = dg.at(2);
1349 d.at(3) = dg.at(3);
1350 vtkPieces [ 0 ].setPrimaryVarInNode(utype, nN, d);
1351 }
1352 } else {
1353 fprintf( stderr, "VTKXMLExportModule::exportPrimaryVars: unsupported variable type %s\n", __UnknownTypeToString(utype) );
1354 }
1355 }
1356}
1357} // end namespace oofem
#define Beam3d_nSubBeams
Definition beam3d.h:55
#define N(a, b)
#define REGISTER_Element(class)
const entryListType & getElementRecords(int elem)
Definition bctracker.C:133
int computeLoadGToLRotationMtrx(FloatMatrix &answer) override
Definition beam3d.C:272
void computeInternalForcesFromBodyLoadVectorAtPoint(FloatArray &answer, Load *forLoad, TimeStep *tStep, ValueModeType mode, FloatArray &pointCoords, double ds)
Definition beam3d.C:1228
void giveEndForcesVector(FloatArray &answer, TimeStep *tStep)
Definition beam3d.C:668
void giveInternalForcesVector(FloatArray &answer, TimeStep *, int useUpdatedGpRecord=0) override
Definition beam3d.C:628
double kappaz
Definition beam3d.h:82
static FEI3dLineLin interp
Geometry interpolator only.
Definition beam3d.h:80
double computeLength() override
Definition beam3d.C:421
DofManager * ghostNodes[2]
Definition beam3d.h:93
FloatArray zaxis
Definition beam3d.h:84
void computeSubSoilStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
Definition beam3d.C:1040
static ParamKey IPK_Beam3d_refangle
[optional] Reference angle for the beam
Definition beam3d.h:102
void computeNmatrixAt(const FloatArray &iLocCoord, FloatMatrix &) override
Definition beam3d.C:156
void computeSubSoilNMatrixAt(GaussPoint *gp, FloatMatrix &answer)
Definition beam3d.C:1032
void computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep) override
Definition beam3d.C:204
void computeKappaCoeffs(TimeStep *tStep)
Definition beam3d.C:440
static ParamKey IPK_Beam3d_zaxis
[optional] Z axis for the beam
Definition beam3d.h:104
Beam3d(int n, Domain *d)
Definition beam3d.C:74
double giveKappayCoeff(TimeStep *tStep)
Definition beam3d.C:465
double giveKappazCoeff(TimeStep *tStep)
Definition beam3d.C:476
FloatMatrixF< 6, 6 > B3SSMI_getUnknownsGtoLRotationMatrix() const override
Evaluate transformation matrix for reciver unknowns.
Definition beam3d.C:345
int numberOfCondensedDofs
number of condensed DOFs
Definition beam3d.h:95
bool computeGtoLRotationMatrix(FloatMatrix &answer) override
Definition beam3d.C:291
void giveInternalForcesVectorAtPoint(FloatArray &answer, TimeStep *tStep, FloatArray &coords)
Definition beam3d.C:1074
int computeNumberOfGlobalDofs() override
Definition beam3d.h:130
double kappay
Definition beam3d.h:82
static ParamKey IPK_Beam3d_dofsToCondense
[optional] DOFs to condense
Definition beam3d.h:100
FloatArray yaxis
Definition beam3d.h:84
bool hasDofs2Condense()
Definition beam3d.h:229
static ParamKey IPK_Beam3d_yaxis
[optional] Y axis for the beam
Definition beam3d.h:103
static ParamKey IPK_Beam3d_refnode
[optional] Reference node for the beam
Definition beam3d.h:101
void computeConstitutiveMatrixAt(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) override
Definition beam3d.C:654
void computeInternalForcesFromBoundaryEdgeLoadVectorAtPoint(FloatArray &answer, BoundaryLoad *load, int edge, CharType type, ValueModeType mode, TimeStep *tStep, FloatArray &pointCoords, double ds, bool global)
Definition beam3d.C:1180
int subsoilMat
Subsoil material.
Definition beam3d.h:98
static ParamKey IPK_Beam3d_subsoilmat
[optional] Subsoil material for the beam
Definition beam3d.h:105
int referenceNode
Definition beam3d.h:83
double referenceAngle
Definition beam3d.h:85
int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords) override
Definition beam3d.C:812
int giveLocalCoordinateSystem(FloatMatrix &answer) override
Definition beam3d.C:487
double length
Definition beam3d.h:82
void computeBmatrixAt(GaussPoint *, FloatMatrix &, int=1, int=ALL_STRAINS) override
Definition beam3d.C:98
virtual void computeLocalForceLoadVector(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
BeamBaseElement(int n, Domain *d)
CoordSystType giveCoordSystMode() override
double giveCoordinate(int i) const
Definition dofmanager.h:383
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
Node * giveNode(int i) const
Definition element.h:629
IntArray boundaryLoadArray
Definition element.h:147
virtual void giveLocalCoordinateSystemVector(InternalStateType isttype, FloatArray &answer)
Definition element.C:1265
IntArray * giveBodyLoadArray()
Returns array containing load numbers of loads acting on element.
Definition element.C:411
int numberOfDofMans
Number of dofmanagers.
Definition element.h:136
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Definition element.C:103
IntArray * giveBoundaryLoadArray()
Returns array containing load numbers of boundary loads acting on element.
Definition element.C:420
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
Definition element.h:157
int numberOfGaussPoints
Definition element.h:175
CrossSection * giveCrossSection()
Definition element.C:534
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Definition element.h:886
int giveLabel() const
Definition element.h:1125
IntArray bodyLoadArray
Definition element.h:147
Domain * giveDomain() const
Definition femcmpnn.h:97
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition femcmpnn.h:79
int number
Component number.
Definition femcmpnn.h:77
int giveNumber() const
Definition femcmpnn.h:104
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
void plusProduct(const FloatMatrix &b, const FloatArray &s, double dV)
Definition floatarray.C:288
double dotProduct(const FloatArray &x) const
Definition floatarray.C:524
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 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 beTProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
Definition floatarray.C:721
void add(const FloatArray &src)
Definition floatarray.C:218
void subtract(const FloatArray &src)
Definition floatarray.C:320
void beSubArrayOf(const FloatArray &src, const IntArray &indx)
Definition floatarray.C:440
void times(double s)
Definition floatarray.C:834
double at(std::size_t i, std::size_t j) const
void times(double f)
void plusProductSymmUpper(const FloatMatrix &a, const FloatMatrix &b, double dV)
void add(const FloatMatrix &a)
void resize(Index rows, Index cols)
Definition floatmatrix.C:79
*Sets size of receiver to be an empty matrix It will have zero rows and zero columns size void clear()
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
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
virtual bool isImposed(TimeStep *tStep)
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
virtual void computeValues(FloatArray &answer, TimeStep *tStep, const FloatArray &coords, const IntArray &dofids, ValueModeType mode)
Definition load.C:59
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
Definition load.C:84
virtual FormulationType giveFormulationType()
Definition load.h:170
bool checkIfSet(size_t componentIndex, size_t paramIndex)
std::optional< paramValue > getTempParam(size_t componentIndex, size_t paramIndex) const
StructuralCrossSection * giveStructuralCrossSection()
Helper function which returns the structural cross-section for the element.
virtual void computeConsistentMassMatrix(FloatMatrix &answer, TimeStep *tStep, double &mass, const double *ipDensity=NULL)
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.
virtual FloatMatrixF< 6, 6 > give3dBeamSubSoilStiffMtrx(MatResponseMode mmode, GaussPoint *gp, TimeStep *tStep) const
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define M_PI
Definition mathfem.h:52
const char * __InternalStateTypeToString(InternalStateType _value)
Definition cltypes.C:309
@ CS_InertiaMomentZ
Moment of inertia around z-axis.
@ CS_InertiaMomentY
Moment of inertia around y-axis.
@ CS_Area
Area.
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
bcGeomType
Type representing the geometric character of loading.
Definition bcgeomtype.h:40
@ BodyLoadBGT
Distributed body load.
Definition bcgeomtype.h:43
@ EdgeLoadBGT
Distributed edge load.
Definition bcgeomtype.h:44
const char * __UnknownTypeToString(UnknownType _value)
Definition cltypes.C:313
@ ForceLoadBVT
Definition bcvaltype.h:43
@ EigenstrainBVT
Definition bcvaltype.h:48
@ TemperatureBVT
Definition bcvaltype.h:42
@ Beam3dSubsoilMaterialInterfaceType
@ VTKXMLExportModuleElementInterfaceType
@ FiberedCrossSectionInterfaceType
oofem::oofegGraphicContext gc[OOFEG_LAST_LAYER]
#define OOFEG_DEFORMED_GEOMETRY_LAYER
#define OOFEG_DEFORMED_GEOMETRY_WIDTH
#define OOFEG_RAW_GEOMETRY_WIDTH
#define OOFEG_RAW_GEOMETRY_LAYER
#define PM_UPDATE_TEMP_PARAMETER(_type, _pm, _ir, _componentnum, _paramkey, _prio)
#define PM_UPDATE_PARAMETER(_val, _pm, _ir, _componentnum, _paramkey, _prio)

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