OOFEM 3.0
Loading...
Searching...
No Matches
rigidarmnode.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#include "rigidarmnode.h"
36#include "slavedof.h"
37#include "floatarray.h"
38#include "floatmatrix.h"
39#include "intarray.h"
40#include "classfactory.h"
41#include "domain.h"
43#include "paramkey.h"
44#include "parametermanager.h"
45
46namespace oofem {
48
51
52
53RigidArmNode :: RigidArmNode(int n, Domain *aDomain) : Node(n, aDomain)
54{ }
55
56
57void
58RigidArmNode :: initializeFrom(InputRecord &ir, int priority)
59{
60
61 Node :: initializeFrom(ir, priority);
62 ParameterManager &ppm = this->giveDomain()->dofmanPPM;
63
66}
67
68void
69RigidArmNode :: postInitialize()
70{
71 Node :: postInitialize();
72
73 ParameterManager &ppm = this->giveDomain()->dofmanPPM;
76
77 if ( masterMask.giveSize() != this->dofidmask.giveSize() ) {
78 throw ComponentInputException(IPK_DofManager_mastermask.getName(), ComponentInputException::ComponentType::ctDofManager, this->number, "mastermask size mismatch");
79 }
80
81 // auxiliary arrays
82 std::map< DofIDItem, IntArray > masterDofID;
83 std::map< DofIDItem, FloatArray > masterContribution;
84
85 this->masterNode = dynamic_cast< Node * >( this->domain->giveDofManager(masterDofMngr) );
86 if ( !masterNode ) {
87 OOFEM_WARNING("master dofManager is not a node");
88 }
89
90 int masterNdofs = masterNode->giveNumberOfDofs();
91
92 IntArray masterNodes(masterNdofs);
93 for ( int &nodeNum: masterNodes ) {
94 nodeNum = this->masterNode->giveNumber();
95 }
96
97 this->computeMasterContribution(masterDofID, masterContribution);
98
99 // initialize slave dofs (inside check of consistency of receiver and master dof)
100 for ( Dof *dof: *this ) {
101 SlaveDof *sdof = dynamic_cast< SlaveDof * >(dof);
102 if ( sdof ) {
103 DofIDItem id = sdof->giveDofID();
104 sdof->initialize(masterNodes, masterDofID [ id ], masterContribution [ id ]);
105 }
106 }
107
108#if 0
109 // check if master in same mode
111 if ( ( * masterNode )->giveParallelMode() != parallel_mode ) {
112 OOFEM_WARNING("mismatch in parallel mode of RigidArmNode and master", 1);
113 result = 0;
114 }
115 }
116#endif
117}
118
119
120int
121RigidArmNode :: checkConsistency()
122{
123 int result;
124
125 result = Node :: checkConsistency();
126
127 // check if receiver has the same coordinate system as master dofManager
128 /*
129 if ( !this->hasSameLCS(this->masterNode) ) {
130 OOFEM_WARNING("different lcs for master/slave nodes", 1);
131 result = 0;
132 }*/
133
134 // check if created DOFs (dofType) compatible with mastermask
135 for ( int i = 1; i <= this->giveNumberOfDofs(); i++ ) {
136 if ( this->masterMask.at(i) && this->dofArray [ i - 1 ]->isPrimaryDof() ) {
137 OOFEM_ERROR("incompatible mastermask and doftype data");
138 }
139 }
140
141 return result;
142}
143
144
145void
146RigidArmNode :: computeMasterContribution(std::map< DofIDItem, IntArray > &masterDofID,
147 std::map< DofIDItem, FloatArray > &masterContribution)
148{
149#if 0 // original implementation without support of different LCS in slave and master
150 int k;
151 IntArray R_uvw(3), uvw(3);
152 FloatArray xyz(3);
153 int numberOfMasterDofs = masterNode->giveNumberOfDofs();
154 //IntArray countOfMasterDofs((int)masterDofID.size());
155
156 // decode of masterMask
157 uvw.at(1) = this->dofidmask->findFirstIndexOf(R_u);
158 uvw.at(2) = this->dofidmask->findFirstIndexOf(R_v);
159 uvw.at(3) = this->dofidmask->findFirstIndexOf(R_w);
160
161 xyz.beDifferenceOf(*this->giveCoordinates(), *masterNode->giveCoordinates());
162
163 if ( hasLocalCS() ) {
164 // LCS is stored as global-to-local, so LCS*xyz_glob = xyz_loc
165 xyz.rotatedWith(* this->localCoordinateSystem, 'n');
166 }
167
168 for ( int i = 1; i <= this->dofidmask->giveSize(); i++ ) {
169 Dof *dof = this->giveDofWithID(dofidmask->at(i));
170 DofIDItem id = dof->giveDofID();
171 masterDofID [ id ].resize(numberOfMasterDofs);
172 masterContribution [ id ].resize(numberOfMasterDofs);
173 R_uvw.zero();
174
175 switch ( masterMask.at(i) ) {
176 case 0: continue;
177 break;
178 case 1:
179 if ( id == D_u ) {
180 if ( uvw.at(2) && masterMask.at( uvw.at(2) ) ) {
181 R_uvw.at(3) = ( ( int ) R_v );
182 }
183
184 if ( uvw.at(3) && masterMask.at( uvw.at(3) ) ) {
185 R_uvw.at(2) = -( ( int ) R_w );
186 }
187 } else if ( id == D_v ) {
188 if ( uvw.at(1) && masterMask.at( uvw.at(1) ) ) {
189 R_uvw.at(3) = -( ( int ) R_u );
190 }
191
192 if ( uvw.at(3) && masterMask.at( uvw.at(3) ) ) {
193 R_uvw.at(1) = ( ( int ) R_w );
194 }
195 } else if ( id == D_w ) {
196 if ( uvw.at(1) && masterMask.at( uvw.at(1) ) ) {
197 R_uvw.at(2) = ( ( int ) R_u );
198 }
199
200 if ( uvw.at(2) && masterMask.at( uvw.at(2) ) ) {
201 R_uvw.at(1) = -( ( int ) R_v );
202 }
203 }
204
205 break;
206 default:
207 OOFEM_ERROR("unknown value in masterMask");
208 }
209
210 //k = ++countOfMasterDofs.at(i);
211 k = 1;
212 masterDofID [ id ].at(k) = ( int ) id;
213 masterContribution [ id ].at(k) = 1.0;
214
215 for ( int j = 1; j <= 3; j++ ) {
216 if ( R_uvw.at(j) != 0 ) {
217 int sign = R_uvw.at(j) < 0 ? -1 : 1;
218 //k = ++countOfMasterDofs.at(i);
219 k++;
220 masterDofID [ id ].at(k) = sign * R_uvw.at(j);
221 masterContribution [ id ].at(k) = sign * xyz.at(j);
222 }
223 }
224 masterDofID [ id ].resizeWithValues(k);
225 masterContribution [ id ].resizeWithValues(k);
226 }
227#else
228 // receiver lcs stored in localCoordinateSystem
229 // (this defines the transformation from global to local)
230 FloatArray xyz(3);
231 FloatMatrix TG2L(6,6); // receiver global to receiver local
232 FloatMatrix TR(6,6); // rigid arm transformation between receiver global DOFs and Master global DOFs
233 FloatMatrix TMG2L(6,6); // master global to local
234 FloatMatrix T(6,6); // full transformation for all dofs
235 IntArray fullDofMask = {D_u, D_v, D_w, R_u, R_v, R_w};
236 bool hasg2l = this->computeL2GTransformation(TG2L, fullDofMask);
237 bool mhasg2l = masterNode->computeL2GTransformation(TMG2L, fullDofMask);
238
239 xyz.beDifferenceOf(this->giveCoordinates(), masterNode->giveCoordinates());
240
241 if (xyz.giveSize() < 3) {
242 xyz.resizeWithValues(3);
243 }
244
245 TR.beUnitMatrix();
246 TR.at(1,5) = xyz.at(3);
247 TR.at(1,6) = -xyz.at(2);
248 TR.at(2,4) = -xyz.at(3);
249 TR.at(2,6) = xyz.at(1);
250 TR.at(3,4) = xyz.at(2);
251 TR.at(3,5) = -xyz.at(1);
252
253 if (hasg2l && mhasg2l) {
254 FloatMatrix h;
255 h.beTProductOf(TG2L, TR); // T transforms global master DOfs to local dofs;
256 T.beProductOf(h,TMG2L); // Add transformation to master local c.s.
257 } else if (hasg2l) {
258 T.beTProductOf(TG2L, TR); // T transforms global master DOfs to local dofs;
259 } else if (mhasg2l) {
260 T.beProductOf(TR,TMG2L); // Add transformation to master local c.s.
261 } else {
262 T = TR;
263 }
264
265 // assemble DOF weights for relevant dofs
266 for ( int i = 1; i <= this->dofidmask.giveSize(); i++ ) {
267 Dof *dof = this->giveDofWithID(dofidmask.at(i));
268 DofIDItem id = dof->giveDofID();
269 masterDofID [ id ] = dofidmask;
270 masterContribution [ id ].resize(dofidmask.giveSize());
271
272 for (int j = 1; j <= this->dofidmask.giveSize(); j++ ) {
273 if ( dofidmask.at(j) <= 6 && id <= 6 ) {
274 masterContribution [ id ].at(j) = T.at(id, dofidmask.at(j));
275 } else if ( dofidmask.findFirstIndexOf(id) == j ) {
276 masterContribution [ id ].at(j) = 1;
277 }
278 }
279 }
280
281#endif
282
283}
284
285
286void RigidArmNode :: updateLocalNumbering(EntityRenumberingFunctor &f)
287{
289 //update masterNode numbering
290 this->masterDofMngr = f( this->masterDofMngr, ERS_DofManager );
291}
292
293
294} // end namespace oofem
#define REGISTER_DofManager(class)
IntArray dofidmask
List of additional dof ids to include.
Definition dofmanager.h:132
static ParamKey IPK_DofManager_mastermask
Definition dofmanager.h:150
int giveNumberOfDofs() const
Definition dofmanager.C:287
dofManagerParallelMode parallel_mode
Definition dofmanager.h:123
void updateLocalNumbering(EntityRenumberingFunctor &f) override
Definition dofmanager.C:909
const FloatArray & giveCoordinates() const
Definition dofmanager.h:390
Dof * giveDofWithID(int dofID) const
Definition dofmanager.C:127
DofIDItem giveDofID() const
Definition dof.h:276
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 & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void resizeWithValues(Index s, std::size_t allocChunk=0)
Definition floatarray.C:103
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 &a, const FloatMatrix &b)
double at(std::size_t i, std::size_t j) const
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
void beUnitMatrix()
Sets receiver to unity matrix.
int & at(std::size_t i)
Definition intarray.h:104
Node(int n, Domain *aDomain)
Definition node.C:73
bool hasLocalCS()
Returns nonzero if node has prescribed local coordinate system.
Definition node.h:141
std::unique_ptr< FloatMatrix > localCoordinateSystem
Definition node.h:100
bool computeL2GTransformation(FloatMatrix &answer, const IntArray &dofIDArry) override
Definition node.C:412
static ParamKey IPK_RigidArmNode_master
int masterDofMngr
Number of master DofManager (Node).
void computeMasterContribution(std::map< DofIDItem, IntArray > &masterDofID, std::map< DofIDItem, FloatArray > &masterContribution)
Node * masterNode
Pointer to master Node.
static ParamKey IPK_RigidArmNode_mastermask
void initialize(const IntArray &masterNodes, const IntArray &mstrDofID, const FloatArray &mstrContribution)
Definition slavedof.C:52
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
@ DofManager_local
Definition dofmanager.h:67
#define PM_DOFMAN_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