OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
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 - 2013 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 
44 namespace oofem {
45 REGISTER_DofManager(RigidArmNode);
46 
47 RigidArmNode :: RigidArmNode(int n, Domain *aDomain) : Node(n, aDomain)
48 { }
49 
50 
53 {
54  IRResultType result; // Required by IR_GIVE_FIELD macro
55 
56  result = Node :: initializeFrom(ir);
57  if ( result != IRRT_OK ) {
58  return result;
59  }
60 
62 
64  if ( masterMask.giveSize() != this->dofidmask->giveSize() ) {
65  OOFEM_WARNING("mastermask size mismatch");
66  return IRRT_BAD_FORMAT;
67  }
68 
69  return IRRT_OK;
70 }
71 
72 void
74 {
76 
77  // auxiliary arrays
78  std::map< DofIDItem, IntArray > masterDofID;
79  std::map< DofIDItem, FloatArray > masterContribution;
80 
81  this->masterNode = dynamic_cast< Node * >( this->domain->giveDofManager(masterDofMngr) );
82  if ( !masterNode ) {
83  OOFEM_WARNING("master dofManager is not a node");
84  }
85 
86  int masterNdofs = masterNode->giveNumberOfDofs();
87 
88  IntArray masterNodes(masterNdofs);
89  for ( int &nodeNum: masterNodes ) {
90  nodeNum = this->masterNode->giveNumber();
91  }
92 
93  this->computeMasterContribution(masterDofID, masterContribution);
94 
95  // initialize slave dofs (inside check of consistency of receiver and master dof)
96  for ( Dof *dof: *this ) {
97  SlaveDof *sdof = dynamic_cast< SlaveDof * >(dof);
98  if ( sdof ) {
99  DofIDItem id = sdof->giveDofID();
100  sdof->initialize(masterNodes, masterDofID [ id ], masterContribution [ id ]);
101  }
102  }
103 
104 #if 0
105  // check if master in same mode
106  if ( parallel_mode != DofManager_local ) {
107  if ( ( * masterNode )->giveParallelMode() != parallel_mode ) {
108  OOFEM_WARNING("mismatch in parallel mode of RigidArmNode and master", 1);
109  result = 0;
110  }
111  }
112 #endif
113 }
114 
115 
116 int
118 {
119  int result;
120 
121  result = Node :: checkConsistency();
122 
123  // check if receiver has the same coordinate system as master dofManager
124  /*
125  if ( !this->hasSameLCS(this->masterNode) ) {
126  OOFEM_WARNING("different lcs for master/slave nodes", 1);
127  result = 0;
128  }*/
129 
130  // check if created DOFs (dofType) compatible with mastermask
131  for ( int i = 1; i <= this->giveNumberOfDofs(); i++ ) {
132  if ( this->masterMask.at(i) && this->dofArray [ i - 1 ]->isPrimaryDof() ) {
133  OOFEM_ERROR("incompatible mastermask and doftype data");
134  }
135  }
136 
137  return result;
138 }
139 
140 
141 void
142 RigidArmNode :: computeMasterContribution(std::map< DofIDItem, IntArray > &masterDofID,
143  std::map< DofIDItem, FloatArray > &masterContribution)
144 {
145 #if 0 // original implementation without support of different LCS in slave and master
146  int k;
147  IntArray R_uvw(3), uvw(3);
148  FloatArray xyz(3);
149  int numberOfMasterDofs = masterNode->giveNumberOfDofs();
150  //IntArray countOfMasterDofs((int)masterDofID.size());
151 
152  // decode of masterMask
153  uvw.at(1) = this->dofidmask->findFirstIndexOf(R_u);
154  uvw.at(2) = this->dofidmask->findFirstIndexOf(R_v);
155  uvw.at(3) = this->dofidmask->findFirstIndexOf(R_w);
156 
158 
159  if ( hasLocalCS() ) {
160  // LCS is stored as global-to-local, so LCS*xyz_glob = xyz_loc
161  xyz.rotatedWith(* this->localCoordinateSystem, 'n');
162  }
163 
164  for ( int i = 1; i <= this->dofidmask->giveSize(); i++ ) {
165  Dof *dof = this->giveDofWithID(dofidmask->at(i));
166  DofIDItem id = dof->giveDofID();
167  masterDofID [ id ].resize(numberOfMasterDofs);
168  masterContribution [ id ].resize(numberOfMasterDofs);
169  R_uvw.zero();
170 
171  switch ( masterMask.at(i) ) {
172  case 0: continue;
173  break;
174  case 1:
175  if ( id == D_u ) {
176  if ( uvw.at(2) && masterMask.at( uvw.at(2) ) ) {
177  R_uvw.at(3) = ( ( int ) R_v );
178  }
179 
180  if ( uvw.at(3) && masterMask.at( uvw.at(3) ) ) {
181  R_uvw.at(2) = -( ( int ) R_w );
182  }
183  } else if ( id == D_v ) {
184  if ( uvw.at(1) && masterMask.at( uvw.at(1) ) ) {
185  R_uvw.at(3) = -( ( int ) R_u );
186  }
187 
188  if ( uvw.at(3) && masterMask.at( uvw.at(3) ) ) {
189  R_uvw.at(1) = ( ( int ) R_w );
190  }
191  } else if ( id == D_w ) {
192  if ( uvw.at(1) && masterMask.at( uvw.at(1) ) ) {
193  R_uvw.at(2) = ( ( int ) R_u );
194  }
195 
196  if ( uvw.at(2) && masterMask.at( uvw.at(2) ) ) {
197  R_uvw.at(1) = -( ( int ) R_v );
198  }
199  }
200 
201  break;
202  default:
203  OOFEM_ERROR("unknown value in masterMask");
204  }
205 
206  //k = ++countOfMasterDofs.at(i);
207  k = 1;
208  masterDofID [ id ].at(k) = ( int ) id;
209  masterContribution [ id ].at(k) = 1.0;
210 
211  for ( int j = 1; j <= 3; j++ ) {
212  if ( R_uvw.at(j) != 0 ) {
213  int sign = R_uvw.at(j) < 0 ? -1 : 1;
214  //k = ++countOfMasterDofs.at(i);
215  k++;
216  masterDofID [ id ].at(k) = sign * R_uvw.at(j);
217  masterContribution [ id ].at(k) = sign * xyz.at(j);
218  }
219  }
220  masterDofID [ id ].resizeWithValues(k);
221  masterContribution [ id ].resizeWithValues(k);
222  }
223 #else
224  // receiver lcs stored in localCoordinateSystem
225  // (this defines the transformation from global to local)
226  FloatArray xyz(3);
227  FloatMatrix TG2L(6,6); // receiver global to receiver local
228  FloatMatrix TR(6,6); // rigid arm transformation between receiver global DOFs and Master global DOFs
229  FloatMatrix TMG2L(6,6); // master global to local
230  FloatMatrix T(6,6); // full transformation for all dofs
231  IntArray fullDofMask = {D_u, D_v, D_w, R_u, R_v, R_w};
232  bool hasg2l = this->computeL2GTransformation(TG2L, fullDofMask);
233  bool mhasg2l = masterNode->computeL2GTransformation(TMG2L, fullDofMask);
234 
236 
237  TR.beUnitMatrix();
238  TR.at(1,5) = xyz.at(3);
239  TR.at(1,6) = -xyz.at(2);
240  TR.at(2,4) = -xyz.at(3);
241  TR.at(2,6) = xyz.at(1);
242  TR.at(3,4) = xyz.at(2);
243  TR.at(3,5) = -xyz.at(1);
244 
245  if (hasg2l && mhasg2l) {
246  FloatMatrix h;
247  h.beTProductOf(TG2L, TR); // T transforms global master DOfs to local dofs;
248  T.beProductOf(h,TMG2L); // Add transformation to master local c.s.
249  } else if (hasg2l) {
250  T.beTProductOf(TG2L, TR); // T transforms global master DOfs to local dofs;
251  } else if (mhasg2l) {
252  T.beProductOf(TR,TMG2L); // Add transformation to master local c.s.
253  } else {
254  T = TR;
255  }
256 
257  // assemble DOF weights for relevant dofs
258  for ( int i = 1; i <= this->dofidmask->giveSize(); i++ ) {
259  Dof *dof = this->giveDofWithID(dofidmask->at(i));
260  DofIDItem id = dof->giveDofID();
261  masterDofID [ id ] = *dofidmask;
262  masterContribution [ id ].resize(dofidmask->giveSize());
263 
264  for (int j = 1; j <= this->dofidmask->giveSize(); j++ ) {
265  masterContribution [ id ].at(j) = T.at(id, dofidmask->at(j));
266  }
267  }
268 
269 #endif
270 
271 }
272 
273 
275 {
277  //update masterNode numbering
278  this->masterDofMngr = f( this->masterDofMngr, ERS_DofManager );
279 }
280 
281 
282 } // end namespace oofem
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: rigidarmnode.C:52
Class and object Domain.
Definition: domain.h:115
#define _IFT_DofManager_mastermask
Definition: dofmanager.h:56
int masterDofMngr
Number of master DofManager (Node)
Definition: rigidarmnode.h:78
bool hasLocalCS()
Returns nonzero if node has prescribed local coordinate system.
Definition: node.h:150
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition: femcmpnn.h:82
FloatMatrix * localCoordinateSystem
Triplet defining the local coordinate system in node.
Definition: node.h:98
virtual void postInitialize()
Performs post-initialization such like checking if there are any slave dofs etc.
Definition: rigidarmnode.C:73
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
virtual void postInitialize()
Performs post-initialization such like checking if there are any slave dofs etc.
Definition: dofmanager.C:862
virtual int checkConsistency()
Allows programmer to test some internal data, before computation begins.
Definition: node.C:325
std::vector< Dof * > dofArray
Array of DOFs.
Definition: dofmanager.h:117
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: node.C:93
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
virtual int checkConsistency()
Allows programmer to test some internal data, before computation begins.
Definition: rigidarmnode.C:117
void rotatedWith(FloatMatrix &r, char mode)
Returns the receiver a rotated according the change-of-base matrix r.
Definition: floatarray.C:799
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Sets receiver to be a - b.
Definition: floatarray.C:341
virtual void updateLocalNumbering(EntityRenumberingFunctor &f)
Local renumbering support.
Definition: rigidarmnode.C:274
Node * masterNode
Pointer to master Node.
Definition: rigidarmnode.h:80
int giveNumberOfDofs() const
Definition: dofmanager.C:279
REGISTER_DofManager(ElementSide)
#define OOFEM_ERROR(...)
Definition: error.h:61
void initialize(const IntArray &masterNodes, const IntArray &mstrDofID, const FloatArray &mstrContribution)
Definition: slavedof.C:52
DofIDItem
Type representing particular dof type.
Definition: dofiditem.h:86
DofIDItem giveDofID() const
Returns DofID value of receiver, which determines type of of unknown connected to receiver (e...
Definition: dof.h:276
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
void computeMasterContribution(std::map< DofIDItem, IntArray > &masterDofID, std::map< DofIDItem, FloatArray > &masterContribution)
Compute vector of master contribution coefficients - SUMA of contributions == 1.0.
Definition: rigidarmnode.C:142
#define _IFT_RigidArmNode_master
Definition: rigidarmnode.h:43
Class representing vector of real numbers.
Definition: floatarray.h:82
dofManagerParallelMode parallel_mode
Definition: dofmanager.h:134
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
Class representing the general Input Record.
Definition: inputrecord.h:101
Dof * giveDofWithID(int dofID) const
Returns DOF with given dofID; issues error if not present.
Definition: dofmanager.C:119
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:367
virtual FloatArray * giveCoordinates()
Definition: node.h:114
void beUnitMatrix()
Sets receiver to unity matrix.
Definition: floatmatrix.C:1332
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
Assigns to the receiver product of .
Definition: floatmatrix.C:337
int giveSize() const
Definition: intarray.h:203
virtual bool computeL2GTransformation(FloatMatrix &answer, const IntArray &dofIDArry)
Computes transformation matrix from global c.s.
Definition: node.C:424
the oofem namespace is to define a context or scope in which all oofem names are defined.
Class implementing node in finite element mesh.
Definition: node.h:87
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
Abstract class Dof represents Degree Of Freedom in finite element mesh.
Definition: dof.h:93
int giveNumber() const
Definition: femcmpnn.h:107
DofManager * giveDofManager(int n)
Service for accessing particular domain dof manager.
Definition: domain.C:314
DofManager is local, there are no contribution from other domains to this DofManager.
Definition: dofmanager.h:81
#define OOFEM_WARNING(...)
Definition: error.h:62
Class representing "slave" degree of freedom.
Definition: slavedof.h:47
virtual void updateLocalNumbering(EntityRenumberingFunctor &f)
Local renumbering support.
Definition: dofmanager.C:950
int findFirstIndexOf(int value) const
Finds index of first occurrence of given value in array.
Definition: intarray.C:331
IntArray * dofidmask
List of additional dof ids to include.
Definition: dofmanager.h:143
RigidArmNode(int n, Domain *aDomain)
Constructor.
Definition: rigidarmnode.C:47

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:31 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011