OOFEM 3.0
Loading...
Searching...
No Matches
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 - 2025 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"
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#include "paramkey.h"
49
50#include "outputmanager.h"
51
52namespace oofem {
54
57
58qcNode :: qcNode(int n, Domain *aDomain) : Node(n, aDomain)
59{
60#ifdef __OOFEG
61 initialized = false;
62#endif
63}
64
65void qcNode :: initializeFrom(InputRecord &ir, int priority)
66{
67 Node :: initializeFrom(ir, priority);
68
69 ParameterManager &ppm = this->giveDomain()->dofmanPPM;
70
73
74
75}
76
77int qcNode :: checkConsistency()
78{
79 // for all nodes
80 int result = Node :: checkConsistency();
81
82 // for hanging nodes only
83 if ( this->qcNodeTypeLabel == 2 ) {
84 Element *e = this->domain->giveElement(this->masterElement);
85
86#if 0
87 // Check if master is in same mode
89 for ( int i = 1; i <= countOfMasterNodes; i++ ) {
90 if ( e->giveNode(i)->giveParallelMode() != parallel_mode ) {
91 OOFEM_WARNING("Mismatch in parallel mode of qcNode and master");
92 return false;
93 }
94 }
95 }
96#endif
97
98 // Check local coordinate systems
99 for ( int i = 1; i <= e->giveNumberOfNodes(); ++i ) {
100 if ( !this->hasSameLCS( e->giveNode(i) ) ) {
101 OOFEM_WARNING("Different lcs for master/slave nodes.");
102 result = false;
103 }
104 }
105 }
106 return result;
107}
108
109void qcNode :: postInitialize()
110{
111 #ifdef __SM_MODULE
112 QClinearStatic *em = dynamic_cast< QClinearStatic * >( this->giveDomain()->giveEngngModel() );
113 if ( em ) {
114 if ( em->giveQcApproachNumber() == 0 ) {
115 this->setAsRepnode();
116 } else {
117 // set node type according to fullsolveddomain
118 if ( this->initializeAsRepnode() ) {
119 this->setAsRepnode();
120 } else {
121 this->setAsHanging();
122 }
123 }
124 } else {
125 OOFEM_ERROR("\"qcNode\" can be used only in \"QClinearStatic\" EngngModel");
126 }
127#else
128 OOFEM_ERROR("\"qcNode\" can be used only in \"QClinearStatic\" EngngModel");
129#endif
130
131
132 Node :: postInitialize();
133 if ( this->qcNodeTypeLabel == 2 ) {
135 }
136}
137
138
139void qcNode :: postInitializeAsHangingNode()
140{
141 // Node :: postInitialize();
142
143 Element *e;
144 FEInterpolation *fei;
145 FloatArray lcoords, masterContribution;
146
147#ifdef __OOFEG
148 if ( initialized ) {
149 return;
150 }
151 initialized = true;
152#endif
153
154 // First check element and interpolation
155 if ( masterElement == -1 ) { // Then we find it by taking the closest (probably containing element)
156 FloatArray closest;
157 SpatialLocalizer *sp = this->domain->giveSpatialLocalizer();
158 sp->init();
159 // Closest point or containing point? It should be contained, but with numerical errors it might be slightly outside
160 // so the closest point is more robust.
161 if ( !( e = sp->giveElementClosestToPoint(lcoords, closest, coordinates, this->masterRegion) ) ) {
162 OOFEM_ERROR("Couldn't find closest element (automatically).");
163 }
164 this->masterElement = e->giveNumber();
165 } else if ( !( e = this->giveDomain()->giveElement(this->masterElement) ) ) {
166 OOFEM_ERROR("Requested element %d doesn't exist.", this->masterElement);
167 }
168 if ( !( fei = e->giveInterpolation() ) ) {
169 OOFEM_ERROR("Requested element %d doesn't have a interpolator.", this->masterElement);
170 }
171
172 if ( lcoords.giveSize() == 0 ) { // we don't need to do this again if the spatial localizer was used.
174 }
175
176 // Initialize slave dofs (inside check of consistency of receiver and master dof)
177 const IntArray &masterNodes = e->giveDofManArray();
178 for ( Dof *dof : *this ) {
179 SlaveDof *sdof = dynamic_cast< SlaveDof * >(dof);
180 if ( sdof ) {
181 DofIDItem id = sdof->giveDofID();
182 fei = e->giveInterpolation(id);
183 if ( !fei ) {
184 OOFEM_ERROR("Requested interpolation for dof id %d doesn't exist in element %d.",
185 id, this->masterElement);
186 }
187#if 0 // This won't work (yet), as it requires some more general FEI classes, or something similar.
188 if ( fei->hasMultiField() ) {
189 FloatMatrix multiContribution;
190 IntArray masterDofIDs, masterNodesDup, dofids;
191 fei->evalMultiN(multiContribution, dofids, lcoords, FEIElementGeometryWrapper(e), 0.0);
192 masterContribution.flatten(multiContribution);
193 masterDofIDs.clear();
194 for ( int i = 0; i <= multiContribution.giveNumberOfColumns(); ++i ) {
195 masterDofIDs.followedBy(dofids);
196 masterNodesDup.followedBy(masterNodes);
197 }
198 sdof->initialize(masterNodesDup, & masterDofIDs, masterContribution);
199 } else { }
200#else
201 // Note: There can be more masterNodes than masterContributions, since all the
202 // FEI classes are based on that the first nodes correspond to the simpler/linear interpolation.
203 // If this assumption is changed in FEIElementGeometryWrapper + friends,
204 // masterNode will also need to be modified for each dof accordingly.
205 fei->evalN( masterContribution, lcoords, FEIElementGeometryWrapper(e) );
206 sdof->initialize(masterNodes, IntArray(), masterContribution);
207#endif
208 }
209 }
210}
211
212/* Test if node will be initialized as repnode i.e. if node is in fullsolved domain or if has BC or IC
213 */
214bool
215qcNode :: initializeAsRepnode()
216{
217 // Nodes with prescribed BC and IC can be set as automatically repnodes here
218 /*
219 * // if node has BC
220 * if (dofBCmap){
221 * if (dofBCmap->size()!=0) {
222 * return true;
223 * }
224 * }
225 * // if node has IC
226 * if (dofICmap){
227 * if (dofICmap->size()!=0) {
228 * return true;
229 * }
230 * }
231 */
232
233 // if node is in fullsolved domain
234
235#ifdef __SM_MODULE
236 QClinearStatic *em = dynamic_cast< QClinearStatic * >( this->giveDomain()->giveEngngModel() );
237 if ( !em ) {
238 OOFEM_ERROR("qcNode is used in unsupported Engineering Models");
239 }
240
241 if ( em->nodeInFullSolvedDomainTest(this) ) {
242 return true;
243 }
244
245 //else
246 return false;
247
248#else
249 OOFEM_ERROR("qcNode is used in unsupported Engineering Models");
250 return false;
251#endif
252
253}
254
255void qcNode :: setAsRepnode()
256{
257 // delete content of DofTypeMap (if exist) // (set all doftype=0 is not enough)
258 if ( this->giveDofTypeMap() != NULL ) {
259 this->giveDofTypeMap()->clear();
260 }
261 this->qcNodeTypeLabel = 1;
262}
263void qcNode :: setAsHanging()
264{
265 // set all doftype=2 in dofTypemap
266
267 if ( this->giveDofTypeMap() == NULL ) {
268 this->dofTypemap.clear();
269 }
270
271 int DofTypeMapSize = this->giveDofTypeMap()->size();
272 // insert "2" into new (empty) dofTypemap
273 if ( DofTypeMapSize == 0 ) {
274 for ( int i = 1; i <= this->giveDomain()->giveDefaultNodeDofIDArry().giveSize(); i++ ) {
275 this->giveDofTypeMap()->insert( std :: pair< int, int >(i, 2) );
276 }
277 }
278 // rewrite old dofTypemap by "2"
279 else {
280 for ( int i = 1; i <= DofTypeMapSize; i++ ) {
281 this->giveDofTypeMap()->at(i) = 2;
282 }
283 }
284
285 this->qcNodeTypeLabel = 2;
286}
287
288
289void qcNode :: printOutputAt(FILE *stream, TimeStep *tStep)
290{
291 EngngModel *emodel = this->giveDomain()->giveEngngModel();
292
293 if ( this->giveQcNodeType() == 1 ) {
294 fprintf( stream, "%-8s R%8d (%8d):\n", this->giveClassName(), this->giveLabel(), this->giveNumber() );
295 for ( Dof *dof : *this ) {
296 emodel->printDofOutputAt(stream, dof, tStep);
297 }
298 } else if ( this->giveQcNodeType() == 2 ) {
299 fprintf( stream, "%-8s H%8d (%8d): el. %8d\n", this->giveClassName(), this->giveLabel(), this->giveNumber(), this->giveMasterElementNumber() );
300 for ( Dof *dof : *this ) {
301 emodel->printDofOutputAt(stream, dof, tStep);
302 }
303 } else {
304 OOFEM_WARNING( "Node %d cannot be printed out: unknown QcNodeType", this->giveGlobalNumber() );
305 }
306}
307} // end namespace oofem
#define REGISTER_DofManager(class)
int giveGlobalNumber() const
Definition dofmanager.h:515
dofManagerParallelMode parallel_mode
Definition dofmanager.h:123
int giveLabel() const
Definition dofmanager.h:516
std ::map< int, int > dofTypemap
Map from DofIDItem to dofType.
Definition dofmanager.h:134
std ::map< int, int > * giveDofTypeMap()
Definition dofmanager.h:409
dofManagerParallelMode giveParallelMode() const
Definition dofmanager.h:526
FloatArray coordinates
Array storing nodal coordinates.
Definition dofmanager.h:103
DofIDItem giveDofID() const
Definition dof.h:276
Node * giveNode(int i) const
Definition element.h:629
virtual FEInterpolation * giveInterpolation() const
Definition element.h:648
virtual int giveNumberOfNodes() const
Definition element.h:703
const IntArray & giveDofManArray() const
Definition element.h:611
virtual void printDofOutputAt(FILE *stream, Dof *iDof, TimeStep *tStep)
Definition engngm.C:884
virtual int global2local(FloatArray &answer, const FloatArray &gcoords, const FEICellGeometry &cellgeo) const =0
virtual void evalN(FloatArray &answer, const FloatArray &lcoords, const FEICellGeometry &cellgeo) const =0
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
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
int giveNumberOfColumns() const
Returns number of columns of receiver.
void followedBy(const IntArray &b, int allocChunk=0)
Definition intarray.C:94
Node(int n, Domain *aDomain)
Definition node.C:73
bool hasSameLCS(Node *remote)
Definition node.C:375
virtual bool nodeInFullSolvedDomainTest(Node *n)
virtual int giveQcApproachNumber()
void initialize(const IntArray &masterNodes, const IntArray &mstrDofID, const FloatArray &mstrContribution)
Definition slavedof.C:52
virtual int init(bool force=false)
virtual Element * giveElementClosestToPoint(FloatArray &lcoords, FloatArray &closest, const FloatArray &coords, int region=0)=0
virtual bool initializeAsRepnode()
Definition qcnode.C:215
static ParamKey IPK_qcNode_masterElement
Static input field keys.
Definition qcnode.h:80
const char * giveClassName() const override
Definition qcnode.h:107
int qcNodeTypeLabel
Type of qcNode (0 deactive, 1 master, 2 hanging).
Definition qcnode.h:73
virtual void setAsHanging()
Definition qcnode.C:263
int giveQcNodeType() override
Definition qcnode.h:102
bool initialized
Flag whether node is fully initialized already.
Definition qcnode.h:76
virtual void setAsRepnode()
Definition qcnode.C:255
virtual int giveMasterElementNumber()
Definition qcnode.h:103
int masterRegion
Region of the master element (used for automatic detection).
Definition qcnode.h:71
int masterElement
Number of the master element.
Definition qcnode.h:69
void postInitializeAsHangingNode()
Definition qcnode.C:139
static ParamKey IPK_qcNode_masterRegion
Definition qcnode.h:81
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
@ DofManager_local
Definition dofmanager.h:67
#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