OOFEM 3.0
Loading...
Searching...
No Matches
node.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
35/*
36 * The original idea for this class comes from
37 * Dubois-Pelerin, Y.: "Object-Oriented Finite Elements: Programming concepts and Implementation",
38 * PhD Thesis, EPFL, Lausanne, 1992.
39 */
40
41#include "node.h"
42#include "dof.h"
43#include "slavedof.h"
44#include "simpleslavedof.h"
45#include "nodalload.h"
46#include "timestep.h"
47#include "floatarray.h"
48#include "floatmatrix.h"
49#include "intarray.h"
50#include "verbose.h"
51#include "datastream.h"
52#include "contextioerr.h"
53#include "mathfem.h"
54#include "classfactory.h"
55#include "dynamicinputrecord.h"
56#include "parametermanager.h"
57#include "domain.h"
58#include "engngm.h"
59#include "paramkey.h"
60
61#ifdef __OOFEG
62 #include "oofeggraphiccontext.h"
63 #include "xfem/enrichmentitem.h"
64 #include "xfem/xfemmanager.h"
65#endif
66
67namespace oofem {
69
72
73Node :: Node(int n, Domain *aDomain) :
74 DofManager(n, aDomain)
75{ }
76
77
78void Node :: initializeFrom(InputRecord &ir, int priority)
79// Gets from the source line from the data file all the data of the receiver.
80{
81 int size;
82 bool flag = false;
83 ParameterManager &ppm = this->giveDomain()->dofmanPPM;
84
85# ifdef VERBOSE
86 // VERBOSE_PRINT1("Instanciating node ",number)
87# endif
88
89 DofManager :: initializeFrom(ir, priority);
90
91 PM_UPDATE_PARAMETER_AND_REPORT(coordinates, ppm, ir, this->number, IPK_Node_coords, priority, flag) ;
92 //
93 // scaling of coordinates if necessary
94 //
95 if ( flag && domain->giveEngngModel()->giveEquationScalingFlag() ) {
96 double lscale = domain->giveEngngModel()->giveVariableScale(VST_Length);
97 this->coordinates.times(1. / lscale);
98 }
99 // Read if available local coordinate system in this node
100 FloatArray triplets;
101 PM_UPDATE_PARAMETER_AND_REPORT(triplets, ppm, ir, this->number, IPK_Node_lcs, priority, flag) ;
102 // process lcs if defined
103 if ( flag ) {
104 size = triplets.giveSize();
105 if ( size != 6 ) {
106 OOFEM_WARNING("lcs in node %d is not properly defined, will be ignored", this->giveNumber() );
107 }
108
109 double n1 = 0.0, n2 = 0.0;
110 localCoordinateSystem = std::make_unique<FloatMatrix>(3, 3);
111
112 for ( int j = 1; j <= 3; j++ ) {
113 localCoordinateSystem->at(1, j) = triplets.at(j);
114 n1 += triplets.at(j) * triplets.at(j);
115 localCoordinateSystem->at(2, j) = triplets.at(j + 3);
116 n2 += triplets.at(j + 3) * triplets.at(j + 3);
117 }
118
119 n1 = sqrt(n1);
120 n2 = sqrt(n2);
121 if ( ( n1 <= 1.e-6 ) || ( n2 <= 1.e-6 ) ) {
122 OOFEM_ERROR("lcs input error");
123 }
124
125 for ( int j = 1; j <= 3; j++ ) { // normalize e1' e2'
126 localCoordinateSystem->at(1, j) /= n1;
127 localCoordinateSystem->at(2, j) /= n2;
128 }
129
130 // vector e3' computed from vector product of e1', e2'
131 localCoordinateSystem->at(3, 1) =
132 localCoordinateSystem->at(1, 2) * localCoordinateSystem->at(2, 3) -
133 localCoordinateSystem->at(1, 3) * localCoordinateSystem->at(2, 2);
134 localCoordinateSystem->at(3, 2) =
135 localCoordinateSystem->at(1, 3) * localCoordinateSystem->at(2, 1) -
136 localCoordinateSystem->at(1, 1) * localCoordinateSystem->at(2, 3);
137 localCoordinateSystem->at(3, 3) =
138 localCoordinateSystem->at(1, 1) * localCoordinateSystem->at(2, 2) -
139 localCoordinateSystem->at(1, 2) * localCoordinateSystem->at(2, 1);
140 }
141}
142
143void
144Node :: initializeFinish()
145{
146 ParameterManager &ppm = this->giveDomain()->dofmanPPM;
147 DofManager :: initializeFinish();
149
150}
151
152
153
154void Node :: giveInputRecord(DynamicInputRecord &input)
155{
156 DofManager :: giveInputRecord(input);
157
159
160 if ( localCoordinateSystem ) {
162 }
163}
164
165
166void
167Node :: computeLoadVector(FloatArray &answer, Load *load, CharType type, TimeStep *tStep, ValueModeType mode)
168{
169 answer.clear();
170 if ( type != ExternalForcesVector ) {
171 return;
172 }
173
174 NodalLoad *loadN = dynamic_cast< NodalLoad * >(load);
175 if ( !loadN ) {
176 OOFEM_ERROR("incompatible load");
177 }
178
179 if ( loadN->giveBCGeoType() != NodalLoadBGT ) {
180 OOFEM_ERROR("incompatible load type applied");
181 }
182
183 load->computeComponentArrayAt(answer, tStep, mode);
184
185 // Transform from Global to Local c.s.
186 if ( loadN->giveCoordSystMode() == NodalLoad :: CST_Global ) {
187 FloatMatrix L2G;
188 if ( this->computeL2GTransformation(L2G, loadN->giveDofIDs()) ) {
189 answer.rotatedWith(L2G, 't');
190 }
191 }
192}
193
194
195void
196Node :: printYourself()
197// Prints the receiver on screen.
198{
199 printf("Node %d coord : x %f y %f z %f\n", number, this->giveCoordinate(1), this->giveCoordinate(2), this->giveCoordinate(3));
200 for ( Dof *dof: *this ) {
201 dof->printYourself();
202 }
203
204 printf("load array : ");
205 loadArray.printYourself();
206 printf("\n");
207}
208
209
210void
211Node :: updateYourself(TimeStep *tStep)
212// Updates the receiver at end of step.
213{
214 DofManager :: updateYourself(tStep);
215
216 fMode mode = domain->giveEngngModel()->giveFormulation();
217
218 if ( mode == AL ) { // updated Lagrange
219 for ( Dof *d: *this ) {
220 DofIDItem id = d->giveDofID();
221 if ( id == D_u || id == D_v || id == D_w ) {
222 int ic = id - D_u + 1;
223 coordinates.at(ic) += d->giveUnknown(VM_Incremental, tStep);
224 } else if ( id == V_u || id == V_v || id == V_w ) {
225 int ic = id - V_u + 1;
226 coordinates.at(ic) += d->giveUnknown(VM_Total, tStep) * tStep->giveTimeIncrement();
227 }
228 }
229 }
230}
231
232
233double
234Node :: giveUpdatedCoordinate(int ic, TimeStep *tStep, double scale)
235//
236// returns coordinate + scale * displacement
237//
238{
239#ifdef DEBUG
240 if ( ( ic < 1 ) || ( ic > 3 ) ) {
241 OOFEM_ERROR("Can't return non-existing coordinate (index not in range 1..3)");
242 }
243#endif
244
245 if ( tStep->isTheCurrentTimeStep() ) {
246 double coordinate = this->giveCoordinate(ic);
247 if ( !this->hasLocalCS() ) {
248 // this has no local cs.
249 for ( Dof *d: *this ) {
250 DofIDItem id = d->giveDofID();
251 if ( id == ic ) {
252 coordinate += scale * d->giveUnknown(VM_Total, tStep);
253 break;
254 } else if ( id - V_u + 1 == ic ) {
255 coordinate += scale * d->giveUnknown(VM_Total, tStep) * tStep->giveTimeIncrement();
256 break;
257 }
258 }
259 } else {
260 //
261 // this has local cs.
262 // We must perform transformation of displacements DOFs
263 // in to global c.s and then to add them to global coordinates.
264 //
266 FloatArray displacements( T->giveNumberOfRows() );
267 displacements.zero();
268
269 for ( Dof *d: *this ) {
270 DofIDItem id = d->giveDofID();
271 if ( id == D_u || id == D_v || id == D_w ) {
272 int ic2 = id - D_u + 1;
273 displacements.at(ic2) = scale * d->giveUnknown(VM_Total, tStep);
274 } else if ( id == V_u || id == V_v || id == V_w ) {
275 int ic2 = id - V_u + 1;
276 displacements.at(ic2) = scale * d->giveUnknown(VM_Total, tStep) * tStep->giveTimeIncrement();
277 }
278 }
279
280 // perform transformation for desired displacement
281 for ( int i = 1; i <= 3; i++ ) {
282 coordinate += displacements.at(i) * T->at(i, ic);
283 }
284 }
285
286 return coordinate;
287 } else {
288 OOFEM_ERROR("Can't return updatedCoordinate for non-current timestep");
289 }
290
291 // return 0.;
292}
293
294
295void
296Node :: giveUpdatedCoordinates(FloatArray &coord, TimeStep *tStep, double scale)
297//
298// returns coordinate + scale * displacement
299//
300{
301 if ( tStep->isTheCurrentTimeStep() ) {
302 FloatArray vec;
303 coord = this->coordinates;
304 this->giveUnknownVectorOfType(vec, DisplacementVector, VM_Total, tStep);
305 for ( int i = 1; i <= coord.giveSize(); i++ ) {
306 coord.at(i) += scale * vec.at(i);
307 }
308 }
309}
310
311
312int
313Node :: checkConsistency()
314{
315 /*
316 * Checks internal data consistency in node.
317 * Current implementation checks (when receiver has slave dofs) if receiver has the same
318 * coordinate system as master dofManager of slave dof.
319 */
320 int result;
321 int nslaves = 0;
322
323 result = DofManager :: checkConsistency();
324
325 for ( Dof *dof: *this ) {
326 if ( dynamic_cast< SimpleSlaveDof * >( dof ) ) {
327 nslaves++;
328 }
329 }
330
331 if ( nslaves == 0 ) {
332 return result; // return o.k. if no slaves exists
333 }
334
335 IntArray masterDofManagers(nslaves);
336 int numberOfMDM = 0; // counter of different master dofManagers
337 int master, alreadyFound = 0;
338 Node *masterNode;
339
340 for ( Dof *dof: *this ) {
341 SimpleSlaveDof *sdof = dynamic_cast< SimpleSlaveDof * >( dof );
342 if ( sdof ) {
343 alreadyFound = 0;
344 master = sdof->giveMasterDofManagerNum();
345 for ( int j = 1; j <= numberOfMDM; j++ ) {
346 if ( masterDofManagers.at(j) == master ) {
347 alreadyFound = 1;
348 break;
349 }
350 }
351
352 if ( alreadyFound == 0 ) {
353 // check master for same coordinate system
354 // first mark master as checked
355 numberOfMDM++;
356 masterDofManagers.at(numberOfMDM) = master;
357 // compare coordinate systems
358 masterNode = dynamic_cast< Node * >( domain->giveDofManager(master) );
359 if ( !masterNode ) {
360 OOFEM_WARNING("master dofManager is not compatible");
361 result = 0;
362 } else if ( !this->hasSameLCS(masterNode) ) {
363 OOFEM_WARNING("different lcs for master/slave nodes");
364 result = 0;
365 }
366 }
367 }
368 }
369
370 return result;
371}
372
373
374bool
375Node :: hasSameLCS(Node *remote)
376{
377 FloatMatrix *thisLcs, *masterLcs;
378 thisLcs = this->giveLocalCoordinateTriplet();
379 masterLcs = remote->giveLocalCoordinateTriplet();
380
381 if ( ( this->hasLocalCS() ) && ( remote->hasLocalCS() ) ) {
382 for ( int k = 1; k <= 3; k++ ) {
383 for ( int l = 1; l <= 3; l++ ) {
384 if ( fabs( thisLcs->at(k, l) - masterLcs->at(k, l) ) > 1.e-4 ) {
385 return false;
386 }
387 }
388 }
389 } else if ( this->hasLocalCS() ) {
390 for ( int k = 1; k <= 3; k++ ) {
391 for ( int l = 1; l <= 3; l++ ) {
392 if ( fabs( thisLcs->at(k, l) - ( k == l ) ) > 1.e-4 ) {
393 return false;
394 }
395 }
396 }
397 } else if ( remote->hasLocalCS() ) {
398 for ( int k = 1; k <= 3; k++ ) {
399 for ( int l = 1; l <= 3; l++ ) {
400 if ( fabs( masterLcs->at(k, l) - ( k == l ) ) > 1.e-4 ) {
401 return false;
402 }
403 }
404 }
405 }
406
407 return true;
408}
409
410
411bool
412Node :: computeL2GTransformation(FloatMatrix &answer, const IntArray &dofIDArry)
413{
414 //
415 // computes transformation of receiver from global cs to nodal (user-defined) cs.
416 // Note: implementation rely on D_u, D_v and D_w (R_u, R_v, R_w) order in cltypes.h
417 // file. Do not change their order and do not insert any values between these values.
418 //
419 DofIDItem id;
420
421 if ( !localCoordinateSystem ) {
422 answer.clear();
423 return false;
424 } else {
426 if ( dofIDArry.isEmpty() ) {
427 // response for all local dofs is computed
428
429 int numberOfDofs = this->giveNumberOfDofs();
430 answer.resize(numberOfDofs, numberOfDofs);
431 answer.zero();
432
433 int i = 0;
434 for ( Dof *dof: *this ) {
435 // test for vector quantities
436 i++;
437 int j = 0;
438 switch ( id = dof->giveDofID() ) {
439 case D_u:
440 case D_v:
441 case D_w:
442 for ( Dof *dof2: *this ) {
443 DofIDItem id2 = dof2->giveDofID();
444 j++;
445 if ( ( id2 == D_u ) || ( id2 == D_v ) || ( id2 == D_w ) ) {
446 answer.at(j, i) = localCoordinateSystem->at( ( int ) ( id ) - ( int ) ( D_u ) + 1,
447 ( int ) ( id2 ) - ( int ) ( D_u ) + 1 );
448 }
449 }
450
451 break;
452
453 case V_u:
454 case V_v:
455 case V_w:
456 for ( Dof *dof2: *this ) {
457 DofIDItem id2 = dof2->giveDofID();
458 j++;
459 if ( ( id2 == V_u ) || ( id2 == V_v ) || ( id2 == V_w ) ) {
460 answer.at(j, i) = localCoordinateSystem->at( ( int ) ( id ) - ( int ) ( V_u ) + 1,
461 ( int ) ( id2 ) - ( int ) ( V_u ) + 1 );
462 }
463 }
464
465 break;
466
467 case R_u:
468 case R_v:
469 case R_w:
470 for ( Dof *dof2: *this ) {
471 DofIDItem id2 = dof2->giveDofID();
472 j++;
473 if ( ( id2 == R_u ) || ( id2 == R_v ) || ( id2 == R_w ) ) {
474 answer.at(j, i) = localCoordinateSystem->at( ( int ) ( id ) - ( int ) ( R_u ) + 1,
475 ( int ) ( id2 ) - ( int ) ( R_u ) + 1 );
476 }
477 }
478
479 break;
480
481 case T_f:
482 case P_f:
483 // scalar quantities
484 answer.at(i, i) = 1.0;
485 break;
486
487 default:
488 OOFEM_ERROR("unknown dofID (%s)", __DofIDItemToString(id).c_str());
489 }
490 }
491 } else { // end if (dofIDArry.isEmpty())
492 // map is provided -> assemble for requested dofs
493 int size = dofIDArry.giveSize();
494 answer.resize(size, size);
495 answer.zero();
496
497 for ( int i = 1; i <= size; i++ ) {
498 // test for vector quantities
499 switch ( id = ( DofIDItem ) dofIDArry.at(i) ) {
500 case D_u:
501 case D_v:
502 case D_w:
503 for ( int j = 1; j <= size; j++ ) {
504 DofIDItem id2 = ( DofIDItem ) dofIDArry.at(j);
505 if ( ( id2 == D_u ) || ( id2 == D_v ) || ( id2 == D_w ) ) {
506 answer.at(j, i) = localCoordinateSystem->at( ( int ) ( id ) - ( int ) ( D_u ) + 1, ( int ) ( id2 ) - ( int ) ( D_u ) + 1 );
507 }
508 }
509
510 break;
511
512 case V_u:
513 case V_v:
514 case V_w:
515 for ( int j = 1; j <= size; j++ ) {
516 DofIDItem id2 = ( DofIDItem ) dofIDArry.at(j);
517 if ( ( id2 == V_u ) || ( id2 == V_v ) || ( id2 == V_w ) ) {
518 answer.at(j, i) = localCoordinateSystem->at( ( int ) ( id ) - ( int ) ( V_u ) + 1, ( int ) ( id2 ) - ( int ) ( V_u ) + 1 );
519 }
520 }
521
522 break;
523
524 case R_u:
525 case R_v:
526 case R_w:
527 for ( int j = 1; j <= size; j++ ) {
528 DofIDItem id2 = ( DofIDItem ) dofIDArry.at(j);
529 if ( ( id2 == R_u ) || ( id2 == R_v ) || ( id2 == R_w ) ) {
530 answer.at(j, i) = localCoordinateSystem->at( ( int ) ( id ) - ( int ) ( R_u ) + 1, ( int ) ( id2 ) - ( int ) ( R_u ) + 1 );
531 }
532 }
533
534 break;
535
536 case T_f:
537 case P_f:
538 // scalar quantities
539 answer.at(i, i) = 1.0;
540 break;
541
542 default:
543 OOFEM_ERROR("unknown dofID (%s)", __DofIDItemToString(id).c_str());
544 }
545 }
546 } // end map is provided -> assemble for requested dofs
547 } // end localCoordinateSystem defined
548 return true;
549}
550
551
552void
553Node :: saveContext(DataStream &stream, ContextMode mode)
554{
555 DofManager :: saveContext(stream, mode);
556
557 if ( mode & CM_Definition ) {
558 int _haslcs = hasLocalCS();
560 if ( ( iores = coordinates.storeYourself(stream) ) != CIO_OK ) {
561 THROW_CIOERR(iores);
562 }
563
564 if ( !stream.write(_haslcs) ) {
566 }
567
568 if ( _haslcs ) {
569 if ( ( iores = localCoordinateSystem->storeYourself(stream) ) != CIO_OK ) {
570 THROW_CIOERR(iores);
571 }
572 }
573 }
574}
575
576
577void
578Node :: restoreContext(DataStream &stream, ContextMode mode)
579{
580 DofManager :: restoreContext(stream, mode);
581
582 if ( mode & CM_Definition ) {
583 int _haslcs;
585 if ( ( iores = coordinates.restoreYourself(stream) ) != CIO_OK ) {
586 THROW_CIOERR(iores);
587 }
588
589 if ( !stream.read(_haslcs) ) {
591 }
592
593 if ( _haslcs ) {
594 localCoordinateSystem = std::make_unique<FloatMatrix>();
595 if ( ( iores = localCoordinateSystem->restoreYourself(stream) ) != CIO_OK ) {
596 THROW_CIOERR(iores);
597 }
598 } else {
599 localCoordinateSystem = nullptr;
600 }
601 }
602}
603
604
605#ifdef __OOFEG
606void
607Node :: drawYourself(oofegGraphicContext &gc, TimeStep *tStep)
608//
609// draws graphics representation of receiver
610//
611{
612 GraphicObj *go;
613 OGC_PlotModeType mode = gc.giveIntVarPlotMode();
614
615 if ( ( mode == OGC_nodeGeometry ) || ( mode == OGC_nodeAnnotation ) ) {
616 WCRec p [ 1 ]; /* point */
617 p [ 0 ].x = ( FPNum ) this->giveCoordinate(1);
618 p [ 0 ].y = ( FPNum ) this->giveCoordinate(2);
619 p [ 0 ].z = ( FPNum ) this->giveCoordinate(3);
620
621 EASValsSetLayer(OOFEG_NODE_ANNOTATION_LAYER);
622 EASValsSetMType(FILLED_CIRCLE_MARKER);
623 #if 1
624 if ( this->giveDomain()->hasXfemManager() ) {
625 XfemManager *xf = this->giveDomain()->giveXfemManager();
626 for ( int i = 1; i <= xf->giveNumberOfEnrichmentItems(); i++ ) {
627 if ( xf->giveEnrichmentItem(i)->isDofManEnriched(* this) ) {
628 EASValsSetMType(SQUARE_MARKER);
629 }
630 }
631 }
632
633 #endif
634
635 if ( this->giveParallelMode() == DofManager_local ) {
636 EASValsSetColor( gc.getNodeColor() );
637 } else if ( this->giveParallelMode() == DofManager_shared ) {
638 EASValsSetColor( gc.getDeformedElementColor() );
639 } else {
640 EASValsSetColor( gc.getCrackPatternColor() );
641 }
642
643 bool ordinary = true;
644
645 for ( Dof *dof: *this ) {
646 if ( dof->isPrimaryDof() ) {
647 ordinary = false;
648 break;
649 }
650 }
651
652 if ( !ordinary ) {
653 EASValsSetColor( gc.getBcIcColor() );
654 }
655
656 EASValsSetMSize(8);
657 go = CreateMarker3D(p);
658 EGWithMaskChangeAttributes(COLOR_MASK | LAYER_MASK | MTYPE_MASK | MSIZE_MASK, go);
659 EMAddGraphicsToModel(ESIModel(), go);
660 }
661
662 if ( mode == OGC_nodeAnnotation ) {
663 char num [ 30 ];
664 WCRec p [ 1 ]; /* point */
665 EASValsSetColor( gc.getNodeColor() );
666 EASValsSetLayer(OOFEG_NODE_ANNOTATION_LAYER);
667 p [ 0 ].x = ( FPNum ) this->giveCoordinate(1);
668 p [ 0 ].y = ( FPNum ) this->giveCoordinate(2);
669 p [ 0 ].z = ( FPNum ) this->giveCoordinate(3);
670
671 sprintf( num, "%d(%d)", this->giveNumber(), this->giveGlobalNumber() );
672 go = CreateAnnText3D(p, num);
673 EGWithMaskChangeAttributes(COLOR_MASK | LAYER_MASK, go);
674 EMAddGraphicsToModel(ESIModel(), go);
675 } else if ( mode == OGC_essentialBC ) {
676 int i, hasDisplSupport [ 3 ], hasRotSupport [ 3 ], hasAny = 0;
677 if ( !tStep ) {
678 TimeStep __temp( domain->giveEngngModel() );
679 tStep = & __temp;
680 }
681
682 WCRec pp [ 2 ];
683
684 for ( i = 0; i < 3; i++ ) {
685 hasDisplSupport [ i ] = 0;
686 hasRotSupport [ i ] = 0;
687 }
688
689 for ( Dof *dof: *this ) {
690 if ( dof->hasBc(tStep) ) {
691 hasAny = 1;
692 switch ( dof->giveDofID() ) {
693 case D_u: hasDisplSupport [ 0 ] = 1;
694 break;
695 case D_v: hasDisplSupport [ 1 ] = 1;
696 break;
697 case D_w: hasDisplSupport [ 2 ] = 1;
698 break;
699 case R_u: hasRotSupport [ 0 ] = 1;
700 break;
701 case R_v: hasRotSupport [ 1 ] = 1;
702 break;
703 case R_w: hasRotSupport [ 2 ] = 1;
704 break;
705 default: break;
706 }
707 }
708 }
709
710 if ( hasAny != 0 ) {
711 EASValsSetColor( gc.getBcIcColor() );
712 EASValsSetLayer(OOFEG_BCIC_ANNOTATION_LAYER);
713 pp [ 0 ].x = ( FPNum ) this->giveCoordinate(1);
714 pp [ 0 ].y = ( FPNum ) this->giveCoordinate(2);
715 pp [ 0 ].z = ( FPNum ) this->giveCoordinate(3);
716
717 /* primary bc */
718 for ( i = 0; i < 3; i++ ) {
719 if ( hasDisplSupport [ i ] || hasRotSupport [ i ] ) {
720 pp [ 1 ].x = 0.;
721 pp [ 1 ].y = 0.;
722 pp [ 1 ].z = 0.;
723
724 if ( !this->hasLocalCS() ) {
725 if ( i == 0 ) {
726 pp [ 1 ].x = 1.0;
727 }
728
729 if ( i == 1 ) {
730 pp [ 1 ].y = 1.0;
731 }
732
733 if ( i == 2 ) {
734 pp [ 1 ].z = 1.0;
735 }
736 } else {
738 ;
739 pp [ 1 ].x = T->at(i + 1, 1);
740 pp [ 1 ].y = T->at(i + 1, 2);
741 pp [ 1 ].z = T->at(i + 1, 3);
742 }
743
744
745 if ( hasDisplSupport [ i ] && hasRotSupport [ i ] ) {
746 EASValsSetVecMType(TRIPLE_ARROW_VECMARKER);
747 }
748
749 if ( hasDisplSupport [ i ] ) {
750 EASValsSetVecMType(ARROW_VECMARKER);
751 }
752
753 if ( hasRotSupport [ i ] ) {
754 EASValsSetVecMType(DOUBLE_ARROW_VECMARKER);
755 }
756
757 go = CreateVecMarker3D(pp);
758 EGWithMaskChangeAttributes(COLOR_MASK | LAYER_MASK | VECMTYPE_MASK, go);
759 EMAddGraphicsToModel(ESIModel(), go);
760 }
761 }
762 }
763 } else if ( mode == OGC_naturalBC ) {
764 if ( !tStep ) {
765 TimeStep __temp( domain->giveEngngModel() );
766 tStep = & __temp;
767 }
768
769 WCRec pp [ 2 ];
770 /* load */
771 if ( !this->giveLoadArray()->isEmpty() ) {
772 double defScale = gc.getDefScale();
773 pp [ 0 ].x = ( FPNum ) this->giveCoordinate(1);
774 pp [ 0 ].y = ( FPNum ) this->giveCoordinate(2);
775 pp [ 0 ].z = ( FPNum ) this->giveCoordinate(3);
776 pp [ 1 ].x = pp [ 1 ].y = pp [ 1 ].z = 0.0;
777
778 FloatArray load, f;
779 FloatMatrix t;
780 IntArray dofIDArry(0);
781
782 load.clear();
783 for ( int iload : *this->giveLoadArray() ) { // to more than one load
784 Load *loadN = domain->giveLoad(iload);
785 this->computeLoadVector(f, loadN, ExternalForcesVector, tStep, VM_Total);
786 load.add(f);
787 }
788 if ( computeL2GTransformation(t, dofIDArry) ) {
789 load.rotatedWith(t, 'n');
790 }
791
792 FloatArray force(3), momentum(3);
793 int i = 0;
794 for ( Dof *dof: *this ) {
795 i++;
796 switch ( dof->giveDofID() ) {
797 case D_u: force.at(1) = defScale * load.at(i);
798 break;
799 case D_v: force.at(2) = defScale * load.at(i);
800 break;
801 case D_w: force.at(3) = defScale * load.at(i);
802 break;
803 case R_u: momentum.at(1) = defScale * load.at(i);
804 break;
805 case R_v: momentum.at(2) = defScale * load.at(i);
806 break;
807 case R_w: momentum.at(3) = defScale * load.at(i);
808 break;
809 default: break;
810 }
811 }
812
813 EASValsSetColor( gc.getBcForceColor() );
814 EASValsSetLayer(OOFEG_NATURALBC_LAYER);
815
816 // draw force
817 EASValsSetVecMType(ARROW_VECMARKER);
818 pp [ 1 ].x = force.at(1);
819 pp [ 1 ].y = force.at(2);
820 pp [ 1 ].z = force.at(3);
821 go = CreateVector3D(pp);
822 EGWithMaskChangeAttributes(COLOR_MASK | LAYER_MASK | VECMTYPE_MASK, go);
823 EMAddGraphicsToModel(ESIModel(), go);
824 // draw moment
825 EASValsSetVecMType(DOUBLE_ARROW_VECMARKER);
826 pp [ 1 ].x = momentum.at(1);
827 pp [ 1 ].y = momentum.at(2);
828 pp [ 1 ].z = momentum.at(3);
829 go = CreateVector3D(pp);
830 EGWithMaskChangeAttributes(COLOR_MASK | LAYER_MASK | VECMTYPE_MASK, go);
831 EMAddGraphicsToModel(ESIModel(), go);
832 }
833 } else if ( mode == OGC_nodeVectorPlot ) {
834 GraphicObj *go;
835
836 if ( gc.giveIntVarType() == IST_Velocity ) {
837 WCRec p [ 2 ]; /* point */
838 double defScale = gc.getDefScale();
839
840 p [ 0 ].x = p [ 1 ].x = ( FPNum ) this->giveCoordinate(1);
841 p [ 0 ].y = p [ 1 ].y = ( FPNum ) this->giveCoordinate(2);
842 p [ 0 ].z = p [ 1 ].z = ( FPNum ) this->giveCoordinate(3);
843
844 //p[1].x = p[1].y = p[1].z = 0.0;
845 for ( Dof *dof: *this ) {
846 if ( dof->giveDofID() == V_u ) {
847 p [ 1 ].x = defScale * dof->giveUnknown(VM_Total, tStep);
848 } else if ( dof->giveDofID() == V_v ) {
849 p [ 1 ].y = defScale * dof->giveUnknown(VM_Total, tStep);
850 } else if ( dof->giveDofID() == V_w ) {
851 p [ 1 ].z = defScale * dof->giveUnknown(VM_Total, tStep);
852 }
853 }
854
855 EASValsSetColor( gc.getDeformedElementColor() );
856 EASValsSetLayer(OOFEG_DEFORMED_GEOMETRY_LAYER);
857 go = CreateVector3D(p);
858 EGWithMaskChangeAttributes(COLOR_MASK | LAYER_MASK, go);
859 EMAddGraphicsToModel(ESIModel(), go);
860 }
861 }
862}
863
864#endif
865} // end namespace oofem
#define REGISTER_DofManager(class)
virtual int read(int *data, std::size_t count)=0
Reads count integer values into array pointed by data.
virtual int write(const int *data, std::size_t count)=0
Writes count integer values from array pointed by data.
int giveGlobalNumber() const
Definition dofmanager.h:515
int giveNumberOfDofs() const
Definition dofmanager.C:287
IntArray loadArray
List of applied loads.
Definition dofmanager.h:108
double giveCoordinate(int i) const
Definition dofmanager.h:383
void giveUnknownVectorOfType(FloatArray &answer, UnknownType ut, ValueModeType mode, TimeStep *tStep)
Definition dofmanager.C:738
DofManager(int n, Domain *aDomain)
Definition dofmanager.C:71
IntArray * giveLoadArray()
Definition dofmanager.C:90
dofManagerParallelMode giveParallelMode() const
Definition dofmanager.h:526
FloatArray coordinates
Array storing nodal coordinates.
Definition dofmanager.h:103
DofIDItem giveDofID() const
Definition dof.h:276
virtual double giveUnknown(ValueModeType mode, TimeStep *tStep)=0
virtual bool isPrimaryDof()
Definition dof.h:287
virtual void printYourself()
Prints the receiver state on stdout.
Definition dof.C:107
virtual bool hasBc(TimeStep *tStep)=0
void setField(int item, InputFieldType id)
bool isDofManEnriched(const DofManager &iDMan) const
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
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void rotatedWith(FloatMatrix &r, char mode)
Definition floatarray.C:814
void add(const FloatArray &src)
Definition floatarray.C:218
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 zero()
Zeroes all coefficient of receiver.
int giveNumberOfRows() const
Returns number of rows of receiver.
double at(std::size_t i, std::size_t j) const
virtual const IntArray & giveDofIDs() const
bool isEmpty() const
Definition intarray.h:217
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
virtual void computeComponentArrayAt(FloatArray &answer, TimeStep *tStep, ValueModeType mode)
Definition load.C:84
CoordSystType giveCoordSystMode() override
Definition nodalload.h:88
bcGeomType giveBCGeoType() const override
Definition nodalload.h:93
Node(int n, Domain *aDomain)
Definition node.C:73
FloatMatrix * giveLocalCoordinateTriplet()
Definition node.h:149
bool hasLocalCS()
Returns nonzero if node has prescribed local coordinate system.
Definition node.h:141
void computeLoadVector(FloatArray &answer, Load *load, CharType type, TimeStep *tStep, ValueModeType mode) override
Definition node.C:167
static ParamKey IPK_Node_coords
Definition node.h:103
static ParamKey IPK_Node_lcs
Definition node.h:102
std::unique_ptr< FloatMatrix > localCoordinateSystem
Definition node.h:100
bool hasSameLCS(Node *remote)
Definition node.C:375
bool computeL2GTransformation(FloatMatrix &answer, const IntArray &dofIDArry) override
Definition node.C:412
int giveMasterDofManagerNum() const
Returns Master Dof Manager Number.
double giveTimeIncrement()
Returns solution step associated time increment.
Definition timestep.h:168
bool isTheCurrentTimeStep()
Definition timestep.C:164
EnrichmentItem * giveEnrichmentItem(int n)
int giveNumberOfEnrichmentItems() const
#define THROW_CIOERR(e)
#define CM_Definition
Definition contextmode.h:47
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
long ContextMode
Definition contextmode.h:43
std::string __DofIDItemToString(DofIDItem _value)
Definition cltypes.C:329
@ VST_Length
fMode
Definition fmode.h:42
@ AL
Updated Lagrange.
Definition fmode.h:45
@ NodalLoadBGT
Concentrated nodal load.
Definition bcgeomtype.h:42
@ DofManager_local
Definition dofmanager.h:67
@ DofManager_shared
Definition dofmanager.h:68
@ CIO_IOERR
General IO error.
#define _IFT_Node_lcs
Definition node.h:54
#define _IFT_Node_coords
Definition node.h:53
oofem::oofegGraphicContext gc[OOFEG_LAST_LAYER]
#define OOFEG_DEFORMED_GEOMETRY_LAYER
#define OOFEG_NODE_ANNOTATION_LAYER
#define OOFEG_NATURALBC_LAYER
#define OOFEG_BCIC_ANNOTATION_LAYER
#define PM_DOFMAN_ERROR_IFNOTSET(_pm, _componentnum, _paramkey)
#define PM_UPDATE_PARAMETER_AND_REPORT(_val, _pm, _ir, _componentnum, _paramkey, _prio, _flag)

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