OOFEM 3.0
Loading...
Searching...
No Matches
set.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 "set.h"
36#include "error.h"
37#include "intarray.h"
38#include "inputrecord.h"
39#include "domain.h"
40#include "element.h"
41#include "node.h"
42#include "range.h"
43#include "feinterpol.h"
44#include "feinterpol2d.h"
45#include "feinterpol3d.h"
46#include "contextioerr.h"
47#include "dynamicinputrecord.h"
48#include <list>
49
50namespace oofem {
51
53#ifdef _OPENMP
54 omp_init_lock(&initLock);
55#endif
56 }
57
58void Set :: initializeFrom(InputRecord &ir)
59{
60 FEMComponent :: initializeFrom(ir);
61
62 IntArray inputNodes;
63 std :: list< Range >inputNodeRanges;
64 if ( ir.hasField(_IFT_Set_allNodes) ) { // generate a list with all the node numbers
65 this->nodes.enumerate(this->giveDomain()->giveNumberOfDofManagers());
66 } else {
68 IR_GIVE_OPTIONAL_FIELD(ir, inputNodeRanges, _IFT_Set_nodeRanges);
69 this->computeIntArray(this->nodes, inputNodes, inputNodeRanges);
70 }
71
72 if ( ir.hasField(_IFT_Set_allElements) ) { // generate a list with all the element numbers
73 this->elements.enumerate(this->giveDomain()->giveNumberOfElements());
75 } else {
76 IntArray inputElements;
77 std :: list< Range >inputElementRanges;
78 IR_GIVE_OPTIONAL_FIELD(ir, inputElements, _IFT_Set_elements);
79 IR_GIVE_OPTIONAL_FIELD(ir, inputElementRanges, _IFT_Set_elementRanges);
80 this->computeIntArray(this->elements, inputElements, inputElementRanges);
82 }
83
84
85 this->elementBoundaries.clear();
87
88 this->elementEdges.clear();
90
91 this->elementSurfaces.clear();
93
94 this->elementInternalNodes.clear();
96
99#if 0
100 this->inputRec = ir.clone();
101#endif
102}
103
104
105void Set :: giveInputRecord(DynamicInputRecord &input)
106{
108
109 if ( this->giveNodeList().giveSize() ) {
110 input.setField(this->nodes, _IFT_Set_nodes);
111 }
112 if ( this->giveElementList().giveSize() ) {
113 input.setField(this->elements, _IFT_Set_elements);
114 }
115 if ( this->giveBoundaryList().giveSize() ) {
117 }
118 if ( this->giveEdgeList().giveSize() ) {
120 }
121 if ( this->giveSurfaceList().giveSize() ) {
123 }
124 if ( this->giveInternalElementDofManagerList().giveSize() ) {
126 }
127 if ( this->elementprops.size() ) {
129 }
130}
131
132
133void Set :: computeIntArray(IntArray &answer, const IntArray &specified, std :: list< Range >ranges)
134{
135 // Find the max value;
136 int maxIndex = specified.giveSize() == 0 ? 0 : specified.maximum();
137 for ( auto &range: ranges ) {
138 if ( range.giveEnd() > maxIndex ) {
139 maxIndex = range.giveEnd();
140 }
141 }
142 IntArray afflictedNodes(maxIndex);
143 afflictedNodes.zero();
144
145 for ( int i = 1; i <= specified.giveSize(); ++i ) {
146 afflictedNodes.at( specified.at(i) ) = 1;
147 }
148
149 for ( auto &range: ranges ) {
150 for ( int i = range.giveStart(); i <= range.giveEnd(); ++i ) {
151 afflictedNodes.at(i) = 1;
152 }
153 }
154 answer.findNonzeros(afflictedNodes);
155}
156
157
158const IntArray &Set :: giveElementList() { return elements; }
159
160const IntArray &Set :: giveBoundaryList() { return elementBoundaries; }
161
162const IntArray &Set :: giveEdgeList() { return elementEdges; }
163
164const IntArray &Set :: giveSurfaceList() { return elementSurfaces; }
165
166const IntArray &Set :: giveInternalElementDofManagerList() { return this->elementInternalNodes;}
167
168const IntArray &Set :: giveNodeList()
169{
170 // Lazy evaluation, we compute the unique set of nodes if needed (and store it).
171 if ( nodalListInitialized) return this->totalNodes;
172
173#ifdef _OPENMP
174 omp_set_lock(&initLock); // if not initialized yet; one thread can proceed with init; others have to wait until init completed
175 if ( this->nodalListInitialized ) {
176 omp_unset_lock(&initLock);
177 return this->totalNodes;
178 }
179#endif
180 IntArray afflictedNodes( this->domain->giveNumberOfDofManagers() );
181 afflictedNodes.zero();
182 for ( int ielem = 1; ielem <= this->elements.giveSize(); ++ielem ) {
183 auto e = this->domain->giveElement( this->elements.at(ielem) );
184 for ( int inode = 1; inode <= e->giveNumberOfNodes(); ++inode ) {
185 afflictedNodes.at( e->giveNode(inode)->giveNumber() ) = 1;
186 }
187 }
188
189 /* boundary entities are obsolete, use edges and/or surfaces instead */
190 for ( int ibnd = 1; ibnd <= this->elementBoundaries.giveSize() / 2; ++ibnd ) {
191 auto e = this->domain->giveElement( this->elementBoundaries.at(ibnd * 2 - 1) );
192 auto boundary = this->elementBoundaries.at(ibnd * 2);
193 auto fei = e->giveInterpolation();
194 auto bNodes = fei->boundaryGiveNodes(boundary, e->giveGeometryType());
195 for ( int inode = 1; inode <= bNodes.giveSize(); ++inode ) {
196 afflictedNodes.at( e->giveNode( bNodes.at(inode) )->giveNumber() ) = 1;
197 }
198 }
199
200 for ( int iedge = 1; iedge <= this->elementEdges.giveSize() / 2; ++iedge ) {
201 auto e = this->domain->giveElement( this->elementEdges.at(iedge * 2 - 1) );
202 auto edge = this->elementEdges.at(iedge * 2);
203 auto eNodes = e->giveBoundaryEdgeNodes(edge, true); // true for including hierarchical nodes
204 for ( int inode = 1; inode <= eNodes.giveSize(); ++inode ) {
205 afflictedNodes.at( e->giveNode( eNodes.at(inode) )->giveNumber() ) = 1;
206 }
207 }
208
209 for ( int isurf = 1; isurf <= this->elementSurfaces.giveSize() / 2; ++isurf ) {
210 auto e = this->domain->giveElement( this->elementSurfaces.at(isurf * 2 - 1) );
211 auto surf = this->elementSurfaces.at(isurf * 2);
212 auto eNodes = e->giveBoundarySurfaceNodes(surf, true); // true for including hierarchical nodes
213 for ( int inode = 1; inode <= eNodes.giveSize(); ++inode ) {
214 afflictedNodes.at( e->giveNode( eNodes.at(inode) )->giveNumber() ) = 1;
215 }
216 }
217
218 for ( int inode = 1; inode <= this->nodes.giveSize(); ++inode ) {
219 afflictedNodes.at( this->nodes.at(inode) ) = 1;
220 }
221 totalNodes.findNonzeros(afflictedNodes);
223#ifdef _OPENMP
224 omp_unset_lock(&initLock);
225#endif
226 return this->totalNodes;
227}
228
229const IntArray &Set :: giveSpecifiedNodeList() { return this->nodes; }
230
231void Set :: setElementList(IntArray newElements) { this->elements = std :: move(newElements); mElementListIsSorted = false; }
232
233void Set :: setBoundaryList(IntArray newBoundaries) { this->elementBoundaries = std :: move(newBoundaries); }
234
235void Set :: setEdgeList(IntArray newEdges) { this->elementEdges = std :: move(newEdges); }
236
237void Set :: setNodeList(IntArray newNodes) { this->nodes = std :: move(newNodes); }
238
239void Set :: addAllElements()
240{
241 this->elements.enumerate(this->giveDomain()->giveNumberOfElements());
242 mElementListIsSorted = false;
243}
244
245bool Set :: hasElement(int number) const
246{
249 mElementsSorted.sort();
251 }
252 return std :: binary_search(mElementsSorted.begin(), mElementsSorted.end(), number);
253}
254
255void Set :: clear()
256{
257 this->elementEdges.clear();
258 this->elementBoundaries.clear();
259 this->elements.clear();
260 this->nodes.clear();
261 this->elementInternalNodes.clear();
262 this->totalNodes.clear();
263}
264
265void Set :: updateLocalNumbering(EntityRenumberingFunctor &f)
266{
269}
270
271void Set :: updateLocalNodeNumbering(EntityRenumberingFunctor &f)
272{
273 int localNum;
274 IntArray mappedNumbers;
275
276 for ( int i = 1; i <= nodes.giveSize(); i++ ) {
277 try {
278 localNum = f(nodes.at(i), ERS_DofManager);
279 } catch ( std :: out_of_range &e ) {
280//#ifndef __MPI_PARALLEL_MODE
281 OOFEM_WARNING("Set :: updateLocalNodeNumbering - Node %d not found", nodes.at(i));
282//#endif
283 continue;
284 }
285 mappedNumbers.followedBy(localNum,10);
286 }
287 nodes = mappedNumbers;
288}
289
290void Set :: updateLocalElementNumbering(EntityRenumberingFunctor &f)
291{
292 int localNum;
293 IntArray mappedNumbers;
294 for ( int i = 1; i <= elements.giveSize(); i++ ) {
295 try {
296 localNum = f(elements.at(i), ERS_Element);
297 } catch ( std :: out_of_range &e ) {
298//#ifndef __MPI_PARALLEL_MODE
299 OOFEM_WARNING("Set :: updateLocalElementNumbering - Element %d with indx %d not found", elements.at(i), i);
300//#endif
301 continue;
302 }
303 mappedNumbers.followedBy(localNum,10);
304 }
305 elements = mappedNumbers;
306
308 mappedNumbers.resize(0);
309 for ( int i = 1; i <= elementBoundaries.giveSize(); i += 2 ) {
310 try {
311 localNum = f(elementBoundaries.at(i), ERS_Element);
312 } catch ( std :: out_of_range &e ) {
313 continue;
314 }
315 mappedNumbers.followedBy(localNum,10);
316 mappedNumbers.followedBy(elementBoundaries.at(i+1));
317 }
318 elementBoundaries = mappedNumbers;
319
320 mappedNumbers.resize(0);
321 for ( int i = 1; i <= elementEdges.giveSize(); i += 2 ) {
322 try {
323 localNum = f(elementEdges.at(i), ERS_Element);
324 } catch ( std :: out_of_range &e ) {
325 continue;
326 }
327 mappedNumbers.followedBy(localNum,10);
328 mappedNumbers.followedBy(elementEdges.at(i+1));
329 }
330 elementEdges = mappedNumbers;
331
332 for ( int i = 1; i <= this->elementInternalNodes.giveSize(); i += 2 ) {
334 }
335
336 mElementListIsSorted = false;
337}
338
339
340void Set :: saveContext(DataStream &stream, ContextMode mode)
341{
342 FEMComponent :: saveContext(stream, mode);
343
344 if ( ( mode & CM_Definition ) ) {
346 if ( ( iores = elements.storeYourself(stream) ) != CIO_OK ) {
347 THROW_CIOERR(iores);
348 }
349 if ( ( iores = elementBoundaries.storeYourself(stream) ) != CIO_OK ) {
350 THROW_CIOERR(iores);
351 }
352 if ( ( iores = elementEdges.storeYourself(stream) ) != CIO_OK ) {
353 THROW_CIOERR(iores);
354 }
355 if ( ( iores = nodes.storeYourself(stream) ) != CIO_OK ) {
356 THROW_CIOERR(iores);
357 }
358 if ( ( iores = this->elementInternalNodes.storeYourself(stream) ) != CIO_OK ) {
359 THROW_CIOERR(iores);
360 }
361 }
362}
363
364void Set :: restoreContext(DataStream &stream, ContextMode mode)
365{
366 FEMComponent :: restoreContext(stream, mode);
367
368 if ( mode & CM_Definition ) {
370 if ( ( iores = elements.restoreYourself(stream) ) != CIO_OK ) {
371 THROW_CIOERR(iores);
372 }
373 if ( ( iores = elementBoundaries.restoreYourself(stream) ) != CIO_OK ) {
374 THROW_CIOERR(iores);
375 }
376 if ( ( iores = elementEdges.restoreYourself(stream) ) != CIO_OK ) {
377 THROW_CIOERR(iores);
378 }
379 if ( ( iores = nodes.restoreYourself(stream) ) != CIO_OK ) {
380 THROW_CIOERR(iores);
381 }
382 if ( ( iores = this->elementInternalNodes.restoreYourself(stream) ) != CIO_OK ) {
383 THROW_CIOERR(iores);
384 }
385 }
386
387 this->totalNodes.clear();
388}
389
390Set dummySet(0, nullptr);
391
392} // end namespace oofem
393
void setRecordKeywordField(std ::string keyword, int number)
void setField(int item, InputFieldType id)
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
FEMComponent(int n, Domain *d)
Definition femcmpnn.h:88
virtual bool hasField(InputFieldType id)=0
Returns true if record contains field identified by idString keyword.
virtual std::shared_ptr< InputRecord > clone() const =0
int maximum() const
Definition intarray.C:144
void followedBy(const IntArray &b, int allocChunk=0)
Definition intarray.C:94
void resize(int n)
Definition intarray.C:73
void zero()
Sets all component to zero.
Definition intarray.C:52
void findNonzeros(const IntArray &logical)
Definition intarray.C:155
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
Set(int n, Domain *d)
Definition set.C:52
IntArray elementEdges
Element numbers + boundary numbers (interleaved).
Definition set.h:88
bool nodalListInitialized
Definition set.h:99
IntArray mElementsSorted
Definition set.h:86
std::string dofmanprops
Dof manager properties.
Definition set.h:94
void computeIntArray(IntArray &answer, const IntArray &specified, std ::list< Range >ranges)
Definition set.C:133
const IntArray & giveInternalElementDofManagerList()
Definition set.C:166
IntArray totalNodes
Unique set of nodes (computed).
Definition set.h:92
const IntArray & giveSurfaceList()
Definition set.C:164
const IntArray & giveEdgeList()
Definition set.C:162
IntArray nodes
Element numbers + internal dof manager numbers (interleaved).
Definition set.h:91
const IntArray & giveBoundaryList()
Definition set.C:160
void updateLocalNodeNumbering(EntityRenumberingFunctor &f)
Definition set.C:271
const IntArray & giveElementList()
Definition set.C:158
IntArray elements
Element numbers.
Definition set.h:84
IntArray elementSurfaces
Element numbers + edge numbers (interleaved).
Definition set.h:89
const IntArray & giveNodeList()
Definition set.C:168
std::string elementprops
Element properties.
Definition set.h:93
bool mElementListIsSorted
Definition set.h:85
void updateLocalElementNumbering(EntityRenumberingFunctor &f)
Definition set.C:290
IntArray elementBoundaries
Definition set.h:87
IntArray elementInternalNodes
Element numbers + surface numbers (interleaved).
Definition set.h:90
#define THROW_CIOERR(e)
#define CM_Definition
Definition contextmode.h:47
#define OOFEM_WARNING(...)
Definition error.h:80
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Definition inputrecord.h:75
long ContextMode
Definition contextmode.h:43
Set dummySet(0, nullptr)
Definition set.h:208
#define _IFT_Set_elementEdges
Interleaved array of element index + edge number.
Definition set.h:58
#define _IFT_Set_elementBoundaries
Interleaved array of element index + boundary number.
Definition set.h:57
#define _IFT_Set_elementRanges
List of element index ranges.
Definition set.h:56
#define _IFT_Set_nodes
List of specific node indices.
Definition set.h:51
#define _IFT_Set_elements
List of specific element indices.
Definition set.h:54
#define _IFT_Set_internalElementNodes
Interleaved array of element index + internal node number.
Definition set.h:60
#define _IFT_Set_nodeRanges
List of node index ranges.
Definition set.h:53
#define _IFT_Set_allNodes
List of specific node indices.
Definition set.h:52
#define _IFT_Set_elementSurfaces
Interleaved array of element index + surface number.
Definition set.h:59
#define _IFT_Set_dofmanprops
Dof manager properties.
Definition set.h:62
#define _IFT_Set_allElements
Will generate a list of all elements in the domain.
Definition set.h:55
#define _IFT_Set_elementprops
Element properties.
Definition set.h:61
#define _IFT_Set_Name
Definition set.h:50

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