OOFEM 3.0
Loading...
Searching...
No Matches
libeam3dnl2.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
38#include "node.h"
39#include "material.h"
40#include "gausspoint.h"
42#include "floatmatrix.h"
43#include "intarray.h"
44#include "floatarray.h"
45#include "mathfem.h"
46#include "timestep.h"
47#include "contextioerr.h"
48#include "classfactory.h"
49#include "parametermanager.h"
50#include "paramkey.h"
51
52#ifdef __OOFEG
53 #include "oofeggraphiccontext.h"
54#endif
55
56namespace oofem {
59
60LIBeam3dNL2::LIBeam3dNL2(int n, Domain *aDomain) : NLStructuralElement(n, aDomain), q(4), tempQ(4) //, kappa (3)
61{
63 l0 = 0.;
64 tempQCounter = 0;
65 referenceNode = 0;
66 // init kappa vector at centre
67 // kappa.zero();
68}
69
70
71void
73{
74 if ( vec.giveSize() != 3 ) {
75 OOFEM_ERROR("vec param size mismatch");
76 }
77
78 answer.resize(3, 3);
79
80 answer.at(1, 1) = answer.at(2, 2) = answer.at(3, 3) = 0.;
81 answer.at(1, 2) = -vec.at(3);
82 answer.at(1, 3) = vec.at(2);
83 answer.at(2, 1) = vec.at(3);
84 answer.at(2, 3) = -vec.at(1);
85 answer.at(3, 1) = -vec.at(2);
86 answer.at(3, 2) = vec.at(1);
87}
88
89
90void
92{
93 FloatMatrix S(3, 3), SS(3, 3);
94 double psiSize;
95
96 if ( psi.giveSize() != 3 ) {
97 OOFEM_ERROR("psi param size mismatch");
98 }
99
100 answer.resize(3, 3);
101 answer.zero();
102
103 psiSize = psi.computeNorm();
104 answer.at(1, 1) = answer.at(2, 2) = answer.at(3, 3) = 1.;
105
106 if ( psiSize <= 1.e-40 ) {
107 return;
108 }
109
110 this->computeSMtrx(S, psi);
111 SS.beProductOf(S, S);
112 S.times(sin(psiSize) / psiSize);
113 SS.times( ( 1. - cos(psiSize) ) / ( psiSize * psiSize ) );
114
115 answer.add(S);
116 answer.add(SS);
117}
118
119
120void
122{
123 // test if not previously updated temporary quaternion
124 if ( tStep->giveSolutionStateCounter() != tempQCounter ) {
125 // update temporary quaternion
126 FloatArray u, centreSpin(3), q2(4);
127 double centreSpinSize;
128
129 // ask element's displacement increments
130 this->computeVectorOf(VM_Incremental, tStep, u);
131
132 // interpolate spin at the centre
133 centreSpin.at(1) = 0.5 * ( u.at(4) + u.at(10) );
134 centreSpin.at(2) = 0.5 * ( u.at(5) + u.at(11) );
135 centreSpin.at(3) = 0.5 * ( u.at(6) + u.at(12) );
136
137 centreSpinSize = centreSpin.computeNorm();
138 if ( centreSpinSize > 1.e-30 ) {
139 centreSpin.normalize();
140 q2.at(1) = sin(centreSpinSize / 2.) * centreSpin.at(1);
141 q2.at(2) = sin(centreSpinSize / 2.) * centreSpin.at(2);
142 q2.at(3) = sin(centreSpinSize / 2.) * centreSpin.at(3);
143 q2.at(4) = cos(centreSpinSize / 2.);
144
145 // update temporary quaternion at the center
146 tempQ.at(1) = q.at(4) * q2.at(1) + q2.at(4) * q.at(1) - ( q.at(2) * q2.at(3) - q.at(3) * q2.at(2) );
147 tempQ.at(2) = q.at(4) * q2.at(2) + q2.at(4) * q.at(2) - ( q.at(3) * q2.at(1) - q.at(1) * q2.at(3) );
148 tempQ.at(3) = q.at(4) * q2.at(3) + q2.at(4) * q.at(3) - ( q.at(1) * q2.at(2) - q.at(2) * q2.at(1) );
149 tempQ.at(4) = q.at(4) * q2.at(4) - ( q.at(1) * q2.at(1) + q.at(2) * q2.at(2) + q.at(3) * q2.at(3) );
150 } else {
151 tempQ = q;
152 }
153
154 // remember timestamp
156 }
157}
158
159
160void
162{
163 answer.resize(3, 3);
164
165 answer.at(1, 1) = q.at(4) * q.at(4) + q.at(1) * q.at(1) - 0.5;
166 answer.at(1, 2) = q.at(1) * q.at(2) - q.at(3) * q.at(4);
167 answer.at(1, 3) = q.at(1) * q.at(3) + q.at(2) * q.at(4);
168
169 answer.at(2, 1) = q.at(2) * q.at(1) + q.at(3) * q.at(4);
170 answer.at(2, 2) = q.at(4) * q.at(4) + q.at(2) * q.at(2) - 0.5;
171 answer.at(2, 3) = q.at(2) * q.at(3) - q.at(1) * q.at(4);
172
173 answer.at(3, 1) = q.at(3) * q.at(1) - q.at(2) * q.at(4);
174 answer.at(3, 2) = q.at(3) * q.at(2) + q.at(1) * q.at(4);
175 answer.at(3, 3) = q.at(4) * q.at(4) + q.at(3) * q.at(3) - 0.5;
176
177 answer.times(2.);
178}
179
180
181void
183{
184 // Spurrier's algorithm
185
186 int i, ii;
187 double a, trR;
188
189 answer.resize(4);
190
191 trR = R.at(1, 1) + R.at(2, 2) + R.at(3, 3);
192 a = trR;
193 ii = 0;
194 for ( i = 1; i <= 3; i++ ) {
195 if ( R.at(i, i) > a ) {
196 a = R.at(i, i);
197 ii = i;
198 }
199 }
200
201 if ( a == trR ) {
202 //printf (".");
203 answer.at(4) = 0.5 * sqrt(1. + a);
204 answer.at(1) = ( R.at(3, 2) - R.at(2, 3) ) / ( 4. * answer.at(4) );
205 answer.at(2) = ( R.at(1, 3) - R.at(3, 1) ) / ( 4. * answer.at(4) );
206 answer.at(3) = ( R.at(2, 1) - R.at(1, 2) ) / ( 4. * answer.at(4) );
207 } else {
208 //printf (":");
209 int jj, kk;
210 if ( ii == 1 ) {
211 jj = 2;
212 kk = 3;
213 } else if ( ii == 2 ) {
214 jj = 3;
215 kk = 1;
216 } else {
217 jj = 1;
218 kk = 2;
219 }
220
221 answer.at(ii) = sqrt(0.5 * a + 0.25 * ( 1. - trR ) );
222 answer.at(4) = 0.25 * ( R.at(kk, jj) - R.at(jj, kk) ) / answer.at(ii);
223 answer.at(jj) = 0.25 * ( R.at(jj, ii) + R.at(ii, jj) ) / answer.at(ii);
224 answer.at(kk) = 0.25 * ( R.at(kk, ii) + R.at(ii, kk) ) / answer.at(ii);
225 }
226}
227
228
229void
231{
232 FloatArray xd(3), eps(3), curv(3);
233 FloatMatrix tempTc;
234
235 // update temp triad
236 this->updateTempQuaternion(tStep);
237 this->computeRotMtrxFromQuaternion(tempTc, this->tempQ);
238
239 this->computeXdVector(xd, tStep);
240
241 // compute eps_xl, gamma_l2, gamma_l3
242 eps.beTProductOf(tempTc, xd);
243 eps.times(1. / this->l0);
244 eps.at(1) -= 1.0;
245
246 // update curvature at midpoint
247 this->computeTempCurv(curv, tStep);
248
249 answer.resize(6);
250 answer.at(1) = eps.at(1); // eps_xl
251 answer.at(2) = eps.at(2); // gamma_l2
252 answer.at(3) = eps.at(3); // gamma_l3
253 answer.at(4) = curv.at(1); // kappa_1
254 answer.at(5) = curv.at(2); // kappa_2
255 answer.at(6) = curv.at(3); // kappa_3
256}
257
258
259void
261{
262 FloatArray xd(3);
263 FloatMatrix s(3, 3);
264
265 this->computeXdVector(xd, tStep);
266 this->computeSMtrx(s, xd);
267
268 answer.resize(12, 6);
269 answer.zero();
270
271 for ( int i = 1; i < 4; i++ ) {
272 answer.at(i, i) = -1.0;
273 answer.at(i + 6, i) = 1.0;
274 answer.at(i + 3, i + 3) = -1.0;
275 answer.at(i + 9, i + 3) = 1.0;
276
277 for ( int j = 1; j < 4; j++ ) {
278 answer.at(i + 3, j) = answer.at(i + 9, j) = 0.5 * s.at(j, i);
279 }
280 }
281}
282
283
284void
285LIBeam3dNL2::giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord)
286{
288 FloatArray nm(6), stress, strain;
289 FloatMatrix x, tempTc;
290 double s1, s2;
291
292 // update temp triad
293 this->updateTempQuaternion(tStep);
294 this->computeRotMtrxFromQuaternion(tempTc, this->tempQ);
295
296 if ( useUpdatedGpRecord == 1 ) {
297 stress = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() )->giveStressVector();
298 } else {
299 this->computeStrainVector(strain, gp, tStep);
300 this->computeStressVector(stress, strain, gp, tStep);
301 }
302
303 for ( int i = 1; i <= 3; i++ ) {
304 s1 = s2 = 0.0;
305 for ( int j = 1; j <= 3; j++ ) {
306 s1 += tempTc.at(i, j) * stress.at(j);
307 s2 += tempTc.at(i, j) * stress.at(j + 3);
308 }
309
310 nm.at(i) = s1;
311 nm.at(i + 3) = s2;
312 }
313
314 this->computeXMtrx(x, tStep);
315 answer.beProductOf(x, nm);
316}
317
318
319void
321{
322 FloatArray u(3);
323
324 answer.resize(3);
325 // ask element's displacements
326 this->computeVectorOf(VM_Total, tStep, u);
327
328 answer.at(1) = ( this->giveNode(2)->giveCoordinate(1) + u.at(7) ) -
329 ( this->giveNode(1)->giveCoordinate(1) + u.at(1) );
330 answer.at(2) = ( this->giveNode(2)->giveCoordinate(2) + u.at(8) ) -
331 ( this->giveNode(1)->giveCoordinate(2) + u.at(2) );
332 answer.at(3) = ( this->giveNode(2)->giveCoordinate(3) + u.at(9) ) -
333 ( this->giveNode(1)->giveCoordinate(3) + u.at(3) );
334}
335
336
337void
338LIBeam3dNL2::computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
339{
340 double s1, s2;
341 FloatMatrix d, x, xt(12, 6), dxt, sn, sm, sxd, y, tempTc;
342 FloatArray n(3), m(3), xd(3), stress, strain;
344
345 answer.clear();
346
347 // linear part
348
349 this->updateTempQuaternion(tStep);
350 this->computeRotMtrxFromQuaternion(tempTc, this->tempQ);
351 this->computeXMtrx(x, tStep);
352 xt.zero();
353 for ( int i = 1; i <= 12; i++ ) {
354 for ( int j = 1; j <= 3; j++ ) {
355 for ( int k = 1; k <= 3; k++ ) {
356 // compute x*Tbar, taking into account sparsity of Tbar
357 xt.at(i, j) += x.at(i, k) * tempTc.at(k, j);
358 xt.at(i, j + 3) += x.at(i, k + 3) * tempTc.at(k, j);
359 }
360 }
361 }
362
363 this->computeConstitutiveMatrixAt(d, rMode, gp, tStep);
364 dxt.beProductTOf(d, xt);
365 answer.beProductOf(xt, dxt);
366 answer.times(1. / this->l0);
367
368 // geometric stiffness ks = ks1+ks2
369 // ks1
370 this->computeStrainVector(strain, gp, tStep);
371 this->computeStressVector(stress, strain, gp, tStep);
372
373 for ( int i = 1; i <= 3; i++ ) {
374 s1 = s2 = 0.0;
375 for ( int j = 1; j <= 3; j++ ) {
376 s1 += tempTc.at(i, j) * stress.at(j);
377 s2 += tempTc.at(i, j) * stress.at(j + 3);
378 }
379
380 n.at(i) = s1;
381 m.at(i) = s2;
382 }
383
384 this->computeSMtrx(sn, n);
385 this->computeSMtrx(sm, m);
386
387 for ( int i = 1; i <= 3; i++ ) {
388 for ( int j = 1; j <= 3; j++ ) {
389 answer.at(i, j + 3) += sn.at(i, j);
390 answer.at(i, j + 9) += sn.at(i, j);
391 answer.at(i + 3, j + 3) += sm.at(i, j);
392 answer.at(i + 3, j + 9) += sm.at(i, j);
393
394 answer.at(i + 6, j + 3) -= sn.at(i, j);
395 answer.at(i + 6, j + 9) -= sn.at(i, j);
396 answer.at(i + 9, j + 3) -= sm.at(i, j);
397 answer.at(i + 9, j + 9) -= sm.at(i, j);
398 }
399 }
400
401 // ks2
402 this->computeXdVector(xd, tStep);
403 this->computeSMtrx(sxd, xd);
404
405 y.beProductOf(sxd, sn);
406 y.times(0.5);
407
408 for ( int i = 1; i <= 3; i++ ) {
409 for ( int j = 1; j <= 3; j++ ) {
410 answer.at(i + 3, j) -= sn.at(i, j);
411 answer.at(i + 3, j + 3) += y.at(i, j);
412 answer.at(i + 3, j + 6) += sn.at(i, j);
413 answer.at(i + 3, j + 9) += y.at(i, j);
414
415 answer.at(i + 9, j) -= sn.at(i, j);
416 answer.at(i + 9, j + 3) += y.at(i, j);
417 answer.at(i + 9, j + 6) += sn.at(i, j);
418 answer.at(i + 9, j + 9) += y.at(i, j);
419 }
420 }
421}
422
423
424void
426// Sets up the array of Gauss Points of the receiver.
427{
428 if ( integrationRulesArray.size() == 0 ) {
429 integrationRulesArray.resize(1);
430 integrationRulesArray [ 0 ] = std::make_unique< GaussIntegrationRule >(1, this, 1, 2);
432 }
433}
434
435
436void
438{
439 answer = this->giveStructuralCrossSection()->give3dBeamStiffMtrx(rMode, gp, tStep);
440}
441
442void
444{
445 OOFEM_ERROR("computeConstitutiveMatrix_dPdF_At Not implemented");
446}
447
448
449void
451{
452 answer = this->giveStructuralCrossSection()->giveGeneralizedStress_Beam3d(strain, gp, tStep);
453}
454
455
456void
458{
459 // first call parent
461 ParameterManager &ppm = domain->elementPPM;
463}
464
465void
467{
469 ParameterManager &ppm = domain->elementPPM;
471 if ( referenceNode == 0 ) {
472 OOFEM_ERROR("wrong reference node specified");
473 }
474 // compute initial triad at centre - requires nodal coordinates
475 FloatMatrix lcs, tc;
476 this->giveLocalCoordinateSystem(lcs);
477 tc.beTranspositionOf(lcs);
478
480 this->nlGeometry = 0; // element always nonlinear, this is to force ouput in strains and stresses in GP (see structuralms.C)
481}
482
483double
485// Returns the original length (l0) of the receiver.
486{
487 double dx, dy, dz;
488 Node *nodeA, *nodeB;
489
490 if ( l0 == 0. ) {
491 nodeA = this->giveNode(1);
492 nodeB = this->giveNode(2);
493 dx = nodeB->giveCoordinate(1) - nodeA->giveCoordinate(1);
494 dy = nodeB->giveCoordinate(2) - nodeA->giveCoordinate(2);
495 dz = nodeB->giveCoordinate(3) - nodeA->giveCoordinate(3);
496 l0 = sqrt(dx * dx + dy * dy + dz * dz);
497 }
498
499 return l0;
500}
501
502
503void
505// Returns the lumped mass matrix of the receiver. This expression is
506// valid in both local and global axes.
507{
508 GaussPoint *gp = integrationRulesArray [ 0 ]->getIntegrationPoint(0);
509 double density = this->giveStructuralCrossSection()->give('d', gp);
510 double halfMass = density * this->giveCrossSection()->give(CS_Area, gp) * this->computeLength() / 2.;
511 answer.resize(12, 12);
512 answer.zero();
513 answer.at(1, 1) = answer.at(2, 2) = answer.at(3, 3) = halfMass;
514 answer.at(7, 7) = answer.at(8, 8) = answer.at(9, 9) = halfMass;
515}
516
517
518void
520// Returns the displacement interpolation matrix {N} of the receiver, eva-
521// luated at gp.
522{
523 double ksi, n1, n2;
524
525 ksi = iLocCoord.at(1);
526 n1 = ( 1. - ksi ) * 0.5;
527 n2 = ( 1. + ksi ) * 0.5;
528
529 answer.resize(6, 12);
530 answer.zero();
531
532 // u
533 answer.at(1, 1) = n1;
534 answer.at(1, 7) = n2;
535 // v
536 answer.at(2, 2) = n1;
537 answer.at(2, 8) = n2;
538 // w
539 answer.at(3, 3) = n1;
540 answer.at(3, 9) = n2;
541 // fi_x
542 answer.at(4, 4) = n1;
543 answer.at(4, 10) = n2;
544 // fi_y
545 answer.at(5, 5) = n1;
546 answer.at(5, 11) = n2;
547 // fi_z
548 answer.at(6, 6) = n1;
549 answer.at(6, 12) = n2;
550}
551
552
553double
555// Returns the length of the receiver. This method is valid only if 1
556// Gauss point is used.
557{
558 double weight = gp->giveWeight();
559 return weight * 0.5 * this->computeLength();
560}
561
562
563void
565{
566 answer = { D_u, D_v, D_w, R_u, R_v, R_w };
567}
568
569int
571{
572 double ksi, n1, n2;
573
574 ksi = lcoords.at(1);
575 n1 = ( 1. - ksi ) * 0.5;
576 n2 = ( 1. + ksi ) * 0.5;
577
578 answer.resize(3);
579 answer.at(1) = n1 * this->giveNode(1)->giveCoordinate(1) + n2 * this->giveNode(2)->giveCoordinate(1);
580 answer.at(2) = n1 * this->giveNode(1)->giveCoordinate(2) + n2 * this->giveNode(2)->giveCoordinate(2);
581 answer.at(3) = n1 * this->giveNode(1)->giveCoordinate(3) + n2 * this->giveNode(2)->giveCoordinate(3);
582
583 return 1;
584}
585
586
587void
589{
590 /*
591 * provides dof mapping of local edge dofs (only nonzero are taken into account)
592 * to global element dofs
593 */
594 if ( iEdge != 1 ) {
595 OOFEM_ERROR("wrong edge number");
596 }
597
598 answer.resize(12);
599 for ( int i = 1; i <= 12; i++ ) {
600 answer.at(i) = i;
601 }
602}
603
604
605double
607{
608 if ( iEdge != 1 ) { // edge between nodes 1 2
609 OOFEM_ERROR("wrong egde number");
610 }
611
612 double weight = gp->giveWeight();
613 return 0.5 * this->computeLength() * weight;
614}
615
616
617int
619//
620// returns a unit vectors of local coordinate system at element
621// stored rowwise (mainly used by some materials with ortho and anisotrophy)
622//
623{
624 FloatArray lx(3), ly(3), lz(3), help(3);
625 double length = this->computeLength();
626 Node *nodeA, *nodeB, *refNode;
627
628 answer.resize(3, 3);
629 answer.zero();
630 nodeA = this->giveNode(1);
631 nodeB = this->giveNode(2);
632 refNode = this->giveDomain()->giveNode(this->referenceNode);
633
634 for ( int i = 1; i <= 3; i++ ) {
635 lx.at(i) = ( nodeB->giveCoordinate(i) - nodeA->giveCoordinate(i) ) / length;
636 help.at(i) = ( refNode->giveCoordinate(i) - nodeA->giveCoordinate(i) );
637 }
638
639 lz.beVectorProductOf(lx, help);
640 lz.normalize();
641 ly.beVectorProductOf(lz, lx);
642 ly.normalize();
643
644 for ( int i = 1; i <= 3; i++ ) {
645 answer.at(1, i) = lx.at(i);
646 answer.at(2, i) = ly.at(i);
647 answer.at(3, i) = lz.at(i);
648 }
649
650 return 1;
651}
652
653
654int
656{
657 /*
658 * Returns transformation matrix from global coordinate system to local
659 * element coordinate system for element load vector components.
660 * If no transformation is necessary, answer is empty matrix (default);
661 *
662 * Does not support follower load
663 */
664
665 FloatMatrix lcs;
666
667 answer.resize(6, 6);
668 answer.zero();
669
670 this->giveLocalCoordinateSystem(lcs);
671
672 for ( int i = 1; i <= 3; i++ ) {
673 for ( int j = 1; j <= 3; j++ ) {
674 answer.at(i, j) = lcs.at(i, j);
675 answer.at(3 + i, 3 + j) = lcs.at(i, j);
676 }
677 }
678
679 return 1;
680}
681
682
683int
685{
686 // returns transformation matrix from
687 // edge local coordinate system
688 // to element local c.s
689 // (same as global c.s in this case)
690 //
691 // i.e. f(element local) = T * f(edge local)
692 //
693 answer.clear();
694 return 0;
695}
696
697
698void
699LIBeam3dNL2::computeBodyLoadVectorAt(FloatArray &answer, Load *load, TimeStep *tStep, ValueModeType mode)
700{
701 FloatArray lc(1);
702 NLStructuralElement::computeBodyLoadVectorAt(answer, load, tStep, mode);
703 answer.times(this->giveCrossSection()->give(CS_Area, lc, this) );
704}
705
706
707void
709// Updates the receiver at end of step.
710{
712
713 // update quaternion
714 this->updateTempQuaternion(tStep);
715 q = tempQ;
716
717 // update curvature
718 //FloatArray curv;
719 //this->computeTempCurv (curv, tStep);
720 //kappa = curv;
721}
722
723void
725// initializes receiver to new time step or can be used
726// if current time step must be restarted
727{
729 tempQ = q;
730}
731
732
733void
735{
737 FloatArray ui(3), ac(3), PrevEpsilon;
738
739 answer.resize(3);
740
741 /*
742 * // update curvature at midpoint
743 * // first, compute Tmid
744 * // ask increments
745 * this -> computeVectorOf(UnknownMode_Incremental,tStep, ui) ;
746 * ac.at(1) = 0.5*(ui.at(10) - ui.at(4));
747 * ac.at(2) = 0.5*(ui.at(11) - ui.at(5));
748 * ac.at(3) = 0.5*(ui.at(12) - ui.at(6));
749 * this->computeSMtrx (sc, ac);
750 * sc.times (1./2.);
751 * // compute I+sc
752 * sc.at(1,1) += 1.0;
753 * sc.at(2,2) += 1.0;
754 * sc.at(3,3) += 1.0;
755 *
756 * this->computeRotMtrxFromQuaternion(tc, this->q);
757 * tmid.beProductOf (sc, tc);
758 *
759 * // update curvature at centre
760 * ac.at(1) = (ui.at(10) - ui.at(4));
761 * ac.at(2) = (ui.at(11) - ui.at(5));
762 * ac.at(3) = (ui.at(12) - ui.at(6));
763 *
764 * answer.beTProductOf (tmid, ac);
765 * answer.times (1/this->l0);
766 * // ask for previous kappa
767 * PrevEpsilon = ((StructuralMaterialStatus*) mat->giveStatus(gp)) -> giveStrainVector ();
768 * if (PrevEpsilon.giveSize()) {
769 * answer.at(1) += PrevEpsilon.at(4);
770 * answer.at(2) += PrevEpsilon.at(5);
771 * answer.at(3) += PrevEpsilon.at(6);
772 * }
773 */
774 // update curvature
775 // exact procedure due to Simo & Vu Quoc
776 FloatMatrix dR, Rn, Ro;
777 FloatArray om, omp, acp(3), kapgn1(3);
778 double acSize, coeff;
779
780 this->computeVectorOf(VM_Incremental, tStep, ui);
781
782 ac.at(1) = 0.5 * ( ui.at(10) - ui.at(4) );
783 ac.at(2) = 0.5 * ( ui.at(11) - ui.at(5) );
784 ac.at(3) = 0.5 * ( ui.at(12) - ui.at(6) );
785
786 this->computeRotMtrx(dR, ac);
787 this->computeRotMtrxFromQuaternion(Ro, this->q);
788 Rn.beProductOf(dR, Ro);
789
790 acSize = ac.computeSquaredNorm();
791
792 if ( acSize > 1.e-30 ) {
793 FloatMatrix h(3, 3);
794 ac.normalize();
795 om = ac;
796 om.times(2. * tan(acSize / 2.) );
797
798 coeff = ( 1. - ( acSize / sin(acSize) ) );
799 for ( int i = 1; i <= 3; i++ ) {
800 for ( int j = 1; j <= 3; j++ ) {
801 h.at(i, j) = coeff * ac.at(i) * ac.at(j);
802 }
803 }
804
805 for ( int i = 1; i <= 3; i++ ) {
806 h.at(i, i) = 1. - h.at(i, i);
807 }
808
809 // compute dPsi/ds
810 acp.at(1) = ( ui.at(10) - ui.at(4) ) / this->l0;
811 acp.at(2) = ( ui.at(11) - ui.at(5) ) / this->l0;
812 acp.at(3) = ( ui.at(12) - ui.at(6) ) / this->l0;
813
814 omp.beProductOf(h, acp);
815 omp.times(2. * tan(acSize / 2.) / acSize);
816
817 kapgn1.beVectorProductOf(om, omp);
818 kapgn1.times(1. / 2.);
819 kapgn1.add(omp);
820
821 coeff = 1. / ( 1. + 0.25 * om.computeSquaredNorm() );
822 kapgn1.times(coeff);
823
824 answer.beTProductOf(Rn, kapgn1);
825 }
826
827 // ask for previous kappa
828 StructuralMaterialStatus *matStat = static_cast< StructuralMaterialStatus * >( gp->giveMaterialStatus() );
829 if ( matStat ) {
830 PrevEpsilon = matStat->giveStrainVector();
831 }
832 if ( PrevEpsilon.giveSize() ) {
833 answer.at(1) += PrevEpsilon.at(4);
834 answer.at(2) += PrevEpsilon.at(5);
835 answer.at(3) += PrevEpsilon.at(6);
836 }
837}
838
839
840void
842{
845
846 if ( ( iores = q.storeYourself(stream) ) != CIO_OK ) {
847 THROW_CIOERR(iores);
848 }
849}
850
851
852void
854{
857
858 if ( ( iores = q.restoreYourself(stream) ) != CIO_OK ) {
859 THROW_CIOERR(iores);
860 }
861}
862
863
864#ifdef __OOFEG
866{
867 GraphicObj *go;
868
869 if ( !gc.testElementGraphicActivity(this) ) {
870 return;
871 }
872
873 // if (!go) { // create new one
874 WCRec p[ 2 ]; /* poin */
875 EASValsSetLineWidth(OOFEG_RAW_GEOMETRY_WIDTH);
876 EASValsSetColor(gc.getElementColor() );
877 EASValsSetLayer(OOFEG_RAW_GEOMETRY_LAYER);
878 p [ 0 ].x = ( FPNum ) this->giveNode(1)->giveCoordinate(1);
879 p [ 0 ].y = ( FPNum ) this->giveNode(1)->giveCoordinate(2);
880 p [ 0 ].z = ( FPNum ) this->giveNode(1)->giveCoordinate(3);
881 p [ 1 ].x = ( FPNum ) this->giveNode(2)->giveCoordinate(1);
882 p [ 1 ].y = ( FPNum ) this->giveNode(2)->giveCoordinate(2);
883 p [ 1 ].z = ( FPNum ) this->giveNode(2)->giveCoordinate(3);
884 go = CreateLine3D(p);
885 EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | LAYER_MASK, go);
886 EGAttachObject(go, ( EObjectP ) this);
887 EMAddGraphicsToModel(ESIModel(), go);
888}
889
890
892{
893 GraphicObj *go;
894
895 if ( !gc.testElementGraphicActivity(this) ) {
896 return;
897 }
898
899 double defScale = gc.getDefScale();
900 // if (!go) { // create new one
901 WCRec p[ 2 ]; /* poin */
902 const char *colors[] = {
903 "red", "green", "blue"
904 };
905
906 EASValsSetLineWidth(OOFEG_DEFORMED_GEOMETRY_WIDTH);
907 EASValsSetColor(gc.getDeformedElementColor() );
908 EASValsSetLayer(OOFEG_DEFORMED_GEOMETRY_LAYER);
909 p [ 0 ].x = ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(1, tStep, defScale);
910 p [ 0 ].y = ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(2, tStep, defScale);
911 p [ 0 ].z = ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(3, tStep, defScale);
912
913 p [ 1 ].x = ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(1, tStep, defScale);
914 p [ 1 ].y = ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(2, tStep, defScale);
915 p [ 1 ].z = ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(3, tStep, defScale);
916 go = CreateLine3D(p);
917 EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | LAYER_MASK, go);
918 EMAddGraphicsToModel(ESIModel(), go);
919
920 // draw centre triad
921 FloatMatrix tc;
922 int i, succ;
923 double coeff = this->l0 / 3.;
924 this->computeRotMtrxFromQuaternion(tc, this->q);
925
926 p [ 0 ].x = 0.5 * ( ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(1, tStep, defScale) + ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(1, tStep, defScale) );
927 p [ 0 ].y = 0.5 * ( ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(2, tStep, defScale) + ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(2, tStep, defScale) );
928 p [ 0 ].z = 0.5 * ( ( FPNum ) this->giveNode(1)->giveUpdatedCoordinate(3, tStep, defScale) + ( FPNum ) this->giveNode(2)->giveUpdatedCoordinate(3, tStep, defScale) );
929
930 // draw t1
931 for ( i = 1; i <= 3; i++ ) {
932 p [ 1 ].x = p [ 0 ].x + coeff * tc.at(1, i);
933 p [ 1 ].y = p [ 0 ].y + coeff * tc.at(2, i);
934 p [ 1 ].z = p [ 0 ].z + coeff * tc.at(3, i);
935
936 EASValsSetColor(ColorGetPixelFromString(const_cast< char * >( colors [ i - 1 ] ), & succ) );
937
938 go = CreateLine3D(p);
939 EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | LAYER_MASK, go);
940 EMAddGraphicsToModel(ESIModel(), go);
941 }
942}
943#endif
944} // end namespace oofem
double length(const Vector &a)
Definition CSG.h:88
#define REGISTER_Element(class)
virtual double give(CrossSectionProperty a, GaussPoint *gp) const
virtual int setupIntegrationPoints(IntegrationRule &irule, int npoints, Element *element)
double giveCoordinate(int i) const
Definition dofmanager.h:383
Node * giveNode(int n)
Definition domain.h:398
Node * giveNode(int i) const
Definition element.h:629
virtual void updateYourself(TimeStep *tStep)
Definition element.C:824
int numberOfDofMans
Number of dofmanagers.
Definition element.h:136
void computeVectorOf(ValueModeType u, TimeStep *tStep, FloatArray &answer)
Definition element.C:103
void postInitialize() override
Performs post initialization steps.
Definition element.C:797
void saveContext(DataStream &stream, ContextMode mode) override
Definition element.C:923
std::vector< std ::unique_ptr< IntegrationRule > > integrationRulesArray
Definition element.h:157
virtual void initForNewStep()
Definition element.C:879
CrossSection * giveCrossSection()
Definition element.C:534
void restoreContext(DataStream &stream, ContextMode mode) override
Definition element.C:999
virtual IntegrationRule * giveDefaultIntegrationRulePtr()
Definition element.h:886
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
double computeNorm() const
Definition floatarray.C:861
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
double computeSquaredNorm() const
Definition floatarray.C:867
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
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 times(double s)
Definition floatarray.C:834
void times(double f)
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 beProductTOf(const FloatMatrix &a, const FloatMatrix &b)
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
void beTranspositionOf(const FloatMatrix &src)
void zero()
Zeroes all coefficient of receiver.
double at(std::size_t i, std::size_t j) const
IntegrationPointStatus * giveMaterialStatus(IntegrationPointStatusIDType key=IPSID_Default)
Definition gausspoint.h:204
double giveWeight()
Returns integration weight of receiver.
Definition gausspoint.h:180
void resize(int n)
Definition intarray.C:73
int & at(std::size_t i)
Definition intarray.h:104
GaussPoint * getIntegrationPoint(int n)
FloatArray tempQ
Temporary quaternion at the center.
Definition libeam3dnl2.h:64
double computeLength() override
int referenceNode
Reference node.
Definition libeam3dnl2.h:70
void giveInternalForcesVector(FloatArray &answer, TimeStep *tStep, int useUpdatedGpRecord=0) override
void computeNmatrixAt(const FloatArray &iLocCoord, FloatMatrix &answer) override
void postInitialize() override
Performs post initialization steps.
void updateYourself(TimeStep *tStep) override
double l0
Initial length.
Definition libeam3dnl2.h:60
LIBeam3dNL2(int n, Domain *d)
Definition libeam3dnl2.C:60
FloatArray q
Quaternion at the center (last equilibrated).
Definition libeam3dnl2.h:62
void initializeFrom(InputRecord &ir, int prio) override
void drawDeformedGeometry(oofegGraphicContext &gc, TimeStep *tStep, UnknownType) override
void computeXdVector(FloatArray &answer, TimeStep *tStep)
void saveContext(DataStream &stream, ContextMode mode) override
double computeEdgeVolumeAround(GaussPoint *gp, int iEdge) override
void computeSMtrx(FloatMatrix &answer, FloatArray &vec)
Definition libeam3dnl2.C:72
void updateTempQuaternion(TimeStep *tStep)
void restoreContext(DataStream &stream, ContextMode mode) override
void giveEdgeDofMapping(IntArray &answer, int iEdge) const override
void computeRotMtrxFromQuaternion(FloatMatrix &answer, FloatArray &q)
int giveLocalCoordinateSystem(FloatMatrix &answer) override
void computeQuaternionFromRotMtrx(FloatArray &answer, FloatMatrix &R)
void computeStressVector(FloatArray &answer, const FloatArray &strain, GaussPoint *gp, TimeStep *tStep) override
void initForNewStep() override
void computeTempCurv(FloatArray &answer, TimeStep *tStep)
void computeRotMtrx(FloatMatrix &answer, FloatArray &psi)
Definition libeam3dnl2.C:91
void giveDofManDofIDMask(int inode, IntArray &answer) const override
void computeBodyLoadVectorAt(FloatArray &answer, Load *load, TimeStep *tStep, ValueModeType mode) override
void computeXMtrx(FloatMatrix &answer, TimeStep *tStep)
int computeLoadGToLRotationMtrx(FloatMatrix &answer) override
void computeLumpedMassMatrix(FloatMatrix &answer, TimeStep *tStep) override
double computeVolumeAround(GaussPoint *gp) override
static ParamKey IPK_LIBeam3dNL2_refnode
Definition libeam3dnl2.h:72
int computeGlobalCoordinates(FloatArray &answer, const FloatArray &lcoords) override
void computeGaussPoints() override
void computeStiffnessMatrix(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep) override
void computeConstitutiveMatrixAt(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) override
void computeStrainVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep) override
void computeConstitutiveMatrix_dPdF_At(FloatMatrix &answer, MatResponseMode rMode, GaussPoint *gp, TimeStep *tStep) override
int computeLoadLEToLRotationMatrix(FloatMatrix &answer, int iEdge, GaussPoint *gp) override
StateCounterType tempQCounter
Time stamp of temporary centre quaternion.
Definition libeam3dnl2.h:68
void drawRawGeometry(oofegGraphicContext &gc, TimeStep *tStep) override
void initializeFrom(InputRecord &ir, int priority) override
NLStructuralElement(int n, Domain *d)
int nlGeometry
Flag indicating if geometrical nonlinearities apply.
virtual double giveUpdatedCoordinate(int ic, TimeStep *tStep, double scale=1.)
Definition node.C:234
virtual FloatMatrixF< 6, 6 > give3dBeamStiffMtrx(MatResponseMode mode, GaussPoint *gp, TimeStep *tStep) const =0
virtual FloatArrayF< 6 > giveGeneralizedStress_Beam3d(const FloatArrayF< 6 > &generalizedStrain, GaussPoint *gp, TimeStep *tStep) const =0
StructuralCrossSection * giveStructuralCrossSection()
Helper function which returns the structural cross-section for the element.
virtual void computeBodyLoadVectorAt(FloatArray &answer, Load *load, TimeStep *tStep, ValueModeType mode)
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.
StateCounterType giveSolutionStateCounter()
Definition timestep.h:211
#define THROW_CIOERR(e)
#define OOFEM_ERROR(...)
Definition error.h:79
#define S(p)
Definition mdm.C:469
long ContextMode
Definition contextmode.h:43
@ CS_Area
Area.
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_ELEMENT_ERROR_IFNOTSET(_pm, _componentnum, _paramkey)
#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