OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
qcnode.C
Go to the documentation of this file.
1 
2 /*
3  *
4  * ##### ##### ###### ###### ### ###
5  * ## ## ## ## ## ## ## ### ##
6  * ## ## ## ## #### #### ## # ##
7  * ## ## ## ## ## ## ## ##
8  * ## ## ## ## ## ## ## ##
9  * ##### ##### ## ###### ## ##
10  *
11  *
12  * OOFEM : Object Oriented Finite Element Code
13  *
14  * Copyright (C) 1993 - 2013 Borek Patzak
15  *
16  *
17  *
18  * Czech Technical University, Faculty of Civil Engineering,
19  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
20  *
21  * This library is free software; you can redistribute it and/or
22  * modify it under the terms of the GNU Lesser General Public
23  * License as published by the Free Software Foundation; either
24  * version 2.1 of the License, or (at your option) any later version.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29  * Lesser General Public License for more details.
30  *
31  * You should have received a copy of the GNU Lesser General Public
32  * License along with this library; if not, write to the Free Software
33  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
34  */
35 
36 
37 #include "qcnode.h"
38 #include "../sm/EngineeringModels/qclinearstatic.h"
39 #include "hangingnode.h"
40 #include "slavedof.h"
41 #include "floatarray.h"
42 #include "intarray.h"
43 #include "element.h"
44 #include "feinterpol.h"
45 #include "spatiallocalizer.h"
46 #include "classfactory.h"
47 #include "engngm.h"
48 
49 #include "outputmanager.h"
50 
51 namespace oofem {
52 REGISTER_DofManager(qcNode);
53 
54 qcNode :: qcNode(int n, Domain *aDomain) : Node(n, aDomain)
55 {
56 #ifdef __OOFEG
57  initialized = false;
58 #endif
59 }
60 
62 {
63  IRResultType result; // Required by IR_GIVE_FIELD macro
64 
66  this->masterElement = -1;
68  this->masterRegion = 0;
70 
71 
72  QClinearStatic *em = dynamic_cast< QClinearStatic * >( this->giveDomain()->giveEngngModel() );
73  if ( em ) {
74  if ( em->giveQcApproachNumber() == 0 ) {
75  this->setAsRepnode();
76  } else {
77  // set node type according to fullsolveddomain
78  if ( this->initializeAsRepnode() ) {
79  this->setAsRepnode();
80  } else {
81  this->setAsHanging();
82  }
83  }
84  } else {
85  OOFEM_ERROR("\"qcNode\" can be used only in \"QClinearStatic\" EngngModel");
86  }
87 
88 
89  return IRRT_OK;
90 }
91 
93 {
94  // for all nodes
95  int result = Node :: checkConsistency();
96 
97  // for hanging nodes only
98  if ( this->qcNodeTypeLabel == 2 ) {
99  Element *e = this->domain->giveElement(this->masterElement);
100 
101 #if 0
102  // Check if master is in same mode
103  if ( parallel_mode != DofManager_local ) {
104  for ( int i = 1; i <= countOfMasterNodes; i++ ) {
105  if ( e->giveNode(i)->giveParallelMode() != parallel_mode ) {
106  OOFEM_WARNING("Mismatch in parallel mode of qcNode and master");
107  return false;
108  }
109  }
110  }
111 #endif
112 
113  // Check local coordinate systems
114  for ( int i = 1; i <= e->giveNumberOfNodes(); ++i ) {
115  if ( !this->hasSameLCS( e->giveNode(i) ) ) {
116  OOFEM_WARNING("Different lcs for master/slave nodes.");
117  result = false;
118  }
119  }
120  }
121  return result;
122 }
123 
125 {
127  if ( this->qcNodeTypeLabel == 2 ) {
129  }
130 }
131 
133 {
134  // Node :: postInitialize();
135 
136  Element *e;
137  FEInterpolation *fei;
138  FloatArray lcoords, masterContribution;
139 
140 #ifdef __OOFEG
141  if ( initialized ) {
142  return;
143  }
144  initialized = true;
145 #endif
146 
147  // First check element and interpolation
148  if ( masterElement == -1 ) { // Then we find it by taking the closest (probably containing element)
149  FloatArray closest;
151  sp->init();
152  // Closest point or containing point? It should be contained, but with numerical errors it might be slightly outside
153  // so the closest point is more robust.
154  if ( !( e = sp->giveElementClosestToPoint(lcoords, closest, coordinates, this->masterRegion) ) ) {
155  OOFEM_ERROR("Couldn't find closest element (automatically).");
156  }
157  this->masterElement = e->giveNumber();
158  } else if ( !( e = this->giveDomain()->giveElement(this->masterElement) ) ) {
159  OOFEM_ERROR("Requested element %d doesn't exist.", this->masterElement);
160  }
161  if ( !( fei = e->giveInterpolation() ) ) {
162  OOFEM_ERROR("Requested element %d doesn't have a interpolator.", this->masterElement);
163  }
164 
165  if ( lcoords.giveSize() == 0 ) { // we don't need to do this again if the spatial localizer was used.
167  }
168 
169  // Initialize slave dofs (inside check of consistency of receiver and master dof)
170  const IntArray &masterNodes = e->giveDofManArray();
171  for ( Dof *dof : *this ) {
172  SlaveDof *sdof = dynamic_cast< SlaveDof * >(dof);
173  if ( sdof ) {
174  DofIDItem id = sdof->giveDofID();
175  fei = e->giveInterpolation(id);
176  if ( !fei ) {
177  OOFEM_ERROR("Requested interpolation for dof id %d doesn't exist in element %d.",
178  id, this->masterElement);
179  }
180 #if 0 // This won't work (yet), as it requires some more general FEI classes, or something similar.
181  if ( fei->hasMultiField() ) {
182  FloatMatrix multiContribution;
183  IntArray masterDofIDs, masterNodesDup, dofids;
184  fei->evalMultiN(multiContribution, dofids, lcoords, FEIElementGeometryWrapper(e), 0.0);
185  masterContribution.flatten(multiContribution);
186  masterDofIDs.clear();
187  for ( int i = 0; i <= multiContribution.giveNumberOfColumns(); ++i ) {
188  masterDofIDs.followedBy(dofids);
189  masterNodesDup.followedBy(masterNodes);
190  }
191  sdof->initialize(masterNodesDup, & masterDofIDs, masterContribution);
192  } else { }
193 #else
194  // Note: There can be more masterNodes than masterContributions, since all the
195  // FEI classes are based on that the first nodes correspond to the simpler/linear interpolation.
196  // If this assumption is changed in FEIElementGeometryWrapper + friends,
197  // masterNode will also need to be modified for each dof accordingly.
198  fei->evalN( masterContribution, lcoords, FEIElementGeometryWrapper(e) );
199  sdof->initialize(masterNodes, IntArray(), masterContribution);
200 #endif
201  }
202  }
203 }
204 
205 /* Test if node will be initialized as repnode i.e. if node is in fullsolved domain or if has BC or IC
206  */
207 bool
209 {
210  // Nodes with prescribed BC and IC can be set as automatically repnodes here
211  /*
212  * // if node has BC
213  * if (dofBCmap){
214  * if (dofBCmap->size()!=0) {
215  * return true;
216  * }
217  * }
218  * // if node has IC
219  * if (dofICmap){
220  * if (dofICmap->size()!=0) {
221  * return true;
222  * }
223  * }
224  */
225 
226  // if node is in fullsolved domain
227  QClinearStatic *em = dynamic_cast< QClinearStatic * >( this->giveDomain()->giveEngngModel() );
228 #ifdef DEBUG
229  if ( !em ) {
230  OOFEM_ERROR("qcNode is used in unsupported Engineering Models");
231  }
232 #endif
233  if ( em->nodeInFullSolvedDomainTest(this) ) {
234  return true;
235  }
236 
237  //else
238  return false;
239 }
240 
242 {
243  // delete content of DofTypeMap (if exist) // (set all doftype=0 is not enough)
244  if ( this->giveDofTypeMap() != NULL ) {
245  this->giveDofTypeMap()->clear();
246  }
247  this->qcNodeTypeLabel = 1;
248 }
250 {
251  // set all doftype=2 in dofTypemap
252 
253  if ( this->giveDofTypeMap() == NULL ) {
254  this->dofTypemap = new std :: map< int, int >();
255  }
256 
257  int DofTypeMapSize = this->giveDofTypeMap()->size();
258  // insert "2" into new (empty) dofTypemap
259  if ( DofTypeMapSize == 0 ) {
260  for ( int i = 1; i <= this->giveDomain()->giveDefaultNodeDofIDArry().giveSize(); i++ ) {
261  this->giveDofTypeMap()->insert( std :: pair< int, int >(i, 2) );
262  }
263  }
264  // rewrite old dofTypemap by "2"
265  else {
266  for ( int i = 1; i <= DofTypeMapSize; i++ ) {
267  this->giveDofTypeMap()->at(i) = 2;
268  }
269  }
270 
271  this->qcNodeTypeLabel = 2;
272 }
273 
274 
275 void qcNode :: printOutputAt(FILE *stream, TimeStep *tStep)
276 {
277  EngngModel *emodel = this->giveDomain()->giveEngngModel();
278 
279  if ( this->giveQcNodeType() == 1 ) {
280  fprintf( stream, "%-8s R%8d (%8d):\n", this->giveClassName(), this->giveLabel(), this->giveNumber() );
281  for ( Dof *dof : *this ) {
282  emodel->printDofOutputAt(stream, dof, tStep);
283  }
284  } else if ( this->giveQcNodeType() == 2 ) {
285  fprintf( stream, "%-8s H%8d (%8d): el. %8d\n", this->giveClassName(), this->giveLabel(), this->giveNumber(), this->giveMasterElementNumber() );
286  for ( Dof *dof : *this ) {
287  emodel->printDofOutputAt(stream, dof, tStep);
288  }
289  } else {
290  OOFEM_WARNING( "Node %d cannot be printed out: unknown QcNodeType", this->giveGlobalNumber() );
291  }
292 }
293 } // end namespace oofem
The base class for all spatial localizers.
int giveNumberOfColumns() const
Returns number of columns of receiver.
Definition: floatmatrix.h:158
virtual bool nodeInFullSolvedDomainTest(Node *n)
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo)=0
Evaluates the array of interpolation functions (shape functions) at given point.
Class and object Domain.
Definition: domain.h:115
virtual int giveQcNodeType()
Definition: qcnode.h:98
int giveGlobalNumber() const
Definition: dofmanager.h:501
Domain * domain
Link to domain object, useful for communicating with other FEM components.
Definition: femcmpnn.h:82
virtual int giveQcApproachNumber()
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
EngngModel * giveEngngModel()
Returns engineering model to which receiver is associated.
Definition: domain.C:433
void printOutputAt(FILE *stream, TimeStep *tStep)
Prints output of receiver to stream, for given time step.
Definition: qcnode.C:275
const IntArray & giveDefaultNodeDofIDArry()
Returns default DofID array which defines physical meaning of particular DOFs.
Definition: domain.C:1004
Abstract base class for all finite elements.
Definition: element.h:145
virtual int giveMasterElementNumber()
Definition: qcnode.h:99
virtual void printDofOutputAt(FILE *stream, Dof *iDof, TimeStep *tStep)
DOF printing routine.
Definition: engngm.C:798
virtual void setAsRepnode()
Definition: qcnode.C:241
#define _IFT_qcNode_masterElement
Definition: qcnode.h:43
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
virtual FEInterpolation * giveInterpolation() const
Definition: element.h:629
bool hasSameLCS(Node *remote)
Returns true, if the local coordinate systems of receiver and given node are the same.
Definition: node.C:387
virtual int giveNumberOfNodes() const
Returns number of nodes of receiver.
Definition: element.h:662
Class representing a general abstraction for finite element interpolation class.
Definition: feinterpol.h:132
This class implements linear static engineering problem.
std::map< int, int > * giveDofTypeMap()
Returns map from DofIDItem to dofType.
Definition: dofmanager.h:396
virtual void setAsHanging()
Definition: qcnode.C:249
const IntArray & giveDofManArray() const
Definition: element.h:592
Element * giveElement(int n)
Service for accessing particular domain fe element.
Definition: domain.C:160
virtual void postInitializeAsHangingNode()
Definition: qcnode.C:132
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
void clear()
Clears the array (zero size).
Definition: intarray.h:177
int masterRegion
Region of the master element (used for automatic detection).
Definition: qcnode.h:70
int giveLabel() const
Definition: dofmanager.h:502
DofIDItem
Type representing particular dof type.
Definition: dofiditem.h:86
virtual int checkConsistency()
Allows programmer to test some internal data, before computation begins.
Definition: qcnode.C:92
SpatialLocalizer * giveSpatialLocalizer()
Returns receiver&#39;s associated spatial localizer.
Definition: domain.C:1184
DofIDItem giveDofID() const
Returns DofID value of receiver, which determines type of of unknown connected to receiver (e...
Definition: dof.h:276
Wrapper around element definition to provide FEICellGeometry interface.
Definition: feinterpol.h:95
virtual int global2local(FloatArray &answer, const FloatArray &gcoords, const FEICellGeometry &cellgeo)=0
Evaluates local coordinates from given global ones.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: qcnode.C:61
int qcNodeTypeLabel
Type of qcNode (0 deactive, 1 master, 2 hanging)
Definition: qcnode.h:72
FloatArray coordinates
Array storing nodal coordinates.
Definition: node.h:91
Class representing vector of real numbers.
Definition: floatarray.h:82
virtual int init(bool force=false)
Initialize receiver data structure if not done previously If force is set to true, the initialization is enforced (useful if domain geometry has changed)
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
virtual const char * giveClassName() const
Definition: qcnode.h:104
virtual void postInitialize()
Performs post-initialization such like checking if there are any slave dofs etc.
Definition: qcnode.C:124
virtual Element * giveElementClosestToPoint(FloatArray &lcoords, FloatArray &closest, const FloatArray &coords, int region=0)=0
Returns the element closest to a given point.
Class representing the general Input Record.
Definition: inputrecord.h:101
bool initialized
Flag whether node is fully initialized already.
Definition: qcnode.h:75
int masterElement
Number of the master element.
Definition: qcnode.h:68
void followedBy(const IntArray &b, int allocChunk=0)
Appends array b at the end of receiver.
Definition: intarray.C:145
std::map< int, int > * dofTypemap
Map from DofIDItem to dofType.
Definition: dofmanager.h:145
qcNode(int n, Domain *aDomain)
Constructor.
Definition: qcnode.C:54
virtual bool initializeAsRepnode()
Definition: qcnode.C:208
Domain * giveDomain() const
Definition: femcmpnn.h:100
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
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 _IFT_qcNode_masterRegion
Definition: qcnode.h:44
Abstract class Dof represents Degree Of Freedom in finite element mesh.
Definition: dof.h:93
int giveNumber() const
Definition: femcmpnn.h:107
Node * giveNode(int i) const
Returns reference to the i-th node of element.
Definition: element.h:610
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
Class representing solution step.
Definition: timestep.h:80
dofManagerParallelMode giveParallelMode() const
Return dofManagerParallelMode of receiver.
Definition: dofmanager.h:512

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:30 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011