OOFEM 3.0
Loading...
Searching...
No Matches
subdivision.h
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#ifndef subdivision_h
36#define subdivision_h
37
38#include "mesherinterface.h"
39#include "floatarray.h"
40#include "intarray.h"
41#include "element.h"
42#include "dofmanager.h"
43#include "connectivitytable.h"
44
45#include <memory>
46#include <vector>
47#include <queue>
48#include <list>
49
50#define _IFT_Subdivision_Name "subdiv"
51
52namespace oofem {
53
54#define SHARED_IRREGULAR_DATA_TAG 7654
55#define SUBDIVISION_SHARED_IRREGULAR_REC_TAG 7655
56#define SUBDIVISION_END_DATA 7656
57#define SUBDIVISION_MIGRATE_REMOTE_ELEMENTS_TAG 7657
58#define SHARED_EDGE_DATA_TAG 7658
59#define SUBDIVISION_SHARED_EDGE_REC_TAG 7659
60
61class TimeStep;
62class ProcessCommunicator;
63
70{
71protected:
72 class RS_Mesh;
73 class RS_Node
74 {
75protected:
78 int number;
79 int parent; // number of parent node or zero for new nodes
81 // mesh
83 // Sorted list of local elements sharing the node
84 // if it is shared (in such a case the list is built a priori)
85 // if it is on boundary of 3D region and incident to edge subjected to bisection
86 // (in such a case the list is built on the fly)
89#ifdef __MPI_PARALLEL_MODE
96#endif
97public:
98 RS_Node(int n, Subdivision :: RS_Mesh * m, int parent, const FloatArray & c, double rd, bool boundary) {
99 this->number = n;
100 this->mesh = m;
101 this->coords = c;
102 this->requiredDensity = rd;
103 this->boundary = boundary;
104 this->parent = parent;
105 this->globalNumber = 0;
106#ifdef __MPI_PARALLEL_MODE
107 this->parallel_mode = DofManager_local;
108#endif
109 }
110 virtual ~RS_Node() { }
113 double giveCoordinate(int i) { return coords.at(i); }
114 int giveParent() { return this->parent; }
115 bool isBoundary() { return this->boundary; }
116 void setBoundary(bool b) { this->boundary = b; }
117 int giveNumber() { return this->number; }
118 void setNumber(int _n) { this->number = _n; }
119 int buildTopLevelNodeConnectivity(ConnectivityTable *ct);
121 void setConnectedElements(IntArray _conn) { connectedElements = std :: move(_conn); }
122 void insertConnectedElement(int num) { connectedElements.insertSorted(num, 10); }
123 void eraseConnectedElement(int num) { connectedElements.eraseSorted(num); }
124 void preallocateConnectedElements(int size) { connectedElements.preallocate(size); }
126 void setGlobalNumber(int gn) { this->globalNumber = gn; }
127 virtual bool isIrregular() { return false; }
128
129#ifdef __MPI_PARALLEL_MODE
130 void numberSharedEdges();
133 const IntArray *givePartitions() { return & partitions; }
134 void setPartitions(IntArray _p) { partitions = std :: move(_p); }
135 int importConnectivity(ConnectivityTable *ct);
136#endif
137#ifdef __OOFEG
138 void drawGeometry();
139#endif
140 };
141
143 {
144protected:
145 int iNode, jNode; // parent edge nodes
146public:
147 RS_IrregularNode(int n, Subdivision :: RS_Mesh * mesh, int parent, FloatArray & c, double rd, bool boundary) : RS_Node(n, mesh, parent, c, rd, boundary) { }
148 void setEdgeNodes(int i, int j) {
149 iNode = i;
150 jNode = j;
151 }
152 void giveEdgeNodes(int &i, int &j) {
153 i = iNode;
154 j = jNode;
155 }
156 bool isIrregular() override { return true; }
157 };
158
160 {
161protected:
163 // element regular nodes
165 // element neighbours (on the same level of refinement)
167 // irregular nodes associated to corresponding element edge
169 // children
171 // parent
173 // longest edge index
175 // mesh
177 // flag whether element is in bisection queue
180#ifdef __MPI_PARALLEL_MODE
182 // numbers of shared edges
184#endif
185public:
186 RS_Element(int number, Subdivision :: RS_Mesh * m, int parent, IntArray & nodes) {
187 this->number = number;
188 this->nodes = nodes;
189 this->leIndex = 0;
190 this->mesh = m;
191 this->parent = parent;
192 this->queue_flag = false;
193 this->globalNumber = -1;
194#ifdef __MPI_PARALLEL_MODE
195 this->parallel_mode = Element_local;
196#endif
197 }
198 virtual ~RS_Element() { }
199
201 bool hasIrregulars() { return !irregular_nodes.containsOnlyZeroes(); }
203 bool isTerminal() { return children.isEmpty(); }
204
205 int giveIrregular(int iedge) { return irregular_nodes.at(iedge); }
206 void setIrregular(int iedge, int ir) { this->irregular_nodes.at(iedge) = ir; }
207
208 virtual int evaluateLongestEdge() { return 0; }
209 virtual void bisect(std :: queue< int > &subdivqueue, std :: list< int > &sharedIrregularsQueue) { }
210 virtual void generate(std :: list< int > &sharedEdgesQueue) { }
211 virtual void update_neighbours() { }
212 virtual double giveDensity() { return 0.0; }
213 virtual double giveRequiredDensity();
214 const IntArray *giveChildren() { return & this->children; }
215 virtual bool isNeighborOf(Subdivision :: RS_Element *elem) = 0;
216 const IntArray *giveNeighbors() { return & this->neghbours_base_elements; }
217 int giveNeighbor(int iside) { return neghbours_base_elements.at(iside); }
218 void setNeighbor(int iside, int nb) { this->neghbours_base_elements.at(iside) = nb; }
219 bool containsNode(int _node) { return nodes.findFirstIndexOf(_node) > 0; }
220 virtual void giveSideNodes(int iside, IntArray &snodes) = 0;
221 int giveParent() { return this->parent; }
222 int giveTopParent();
223 bool giveQueueFlag() { return this->queue_flag; }
224 void setQueueFlag(bool _qf) { this->queue_flag = _qf; }
225 void buildTopLevelNodeConnectivity(Subdivision :: RS_Node *node);
227 const IntArray *giveNodes() { return & this->nodes; }
228 int giveNode(int i) { return this->nodes.at(i); }
229 int giveNumber() { return this->number; }
230 void setNumber(int newNum) { this->number = newNum; }
231 virtual int giveEdgeIndex(int iNode, int jNode) = 0;
233 int giveLeIndex() { return this->leIndex; }
235 void setLeIndex(int _n) { this->leIndex = _n; }
236
237#ifdef __OOFEG
238 virtual void drawGeometry() { }
239#endif
241 void setGlobalNumber(int gn) { this->globalNumber = gn; }
242
243#ifdef __MPI_PARALLEL_MODE
244 virtual void numberSharedEdges(int iNode, IntArray &connNodes) = 0;
245 const IntArray *giveSharedEdges() { return & shared_edges; }
246 virtual void makeSharedEdges() = 0;
247 int giveSharedEdge(int iedge) { return shared_edges.at(iedge); }
248 void setSharedEdge(int iedge, int num) { this->shared_edges.at(iedge) = num; }
250 // Sets parallel mode of element
252#endif
253 };
254
256 {
257public:
258 RS_Triangle(int number, Subdivision :: RS_Mesh * mesh, int parent, IntArray & nodes);
259 int evaluateLongestEdge() override;
260 void bisect(std :: queue< int > &subdivqueue, std :: list< int > &sharedIrregularsQueue) override;
261 void generate(std :: list< int > &sharedEdgesQueue) override;
262 void update_neighbours() override;
263 double giveDensity() override;
264 bool isNeighborOf(Subdivision :: RS_Element *elem) override;
265 void giveSideNodes(int iside, IntArray &snodes) override;
266 int giveEdgeIndex(int iNode, int jNode) override;
267 void importConnectivity(ConnectivityTable *ct) override;
268#ifdef __OOFEG
269 void drawGeometry() override;
270#endif
271#ifdef __MPI_PARALLEL_MODE
272 void numberSharedEdges(int iNode, IntArray &connNodes) override;
273 void makeSharedEdges() override {
274 shared_edges.resize(3);
275 shared_edges.zero();
276 }
277#endif
278 };
279
281 {
282protected:
284public:
285 RS_Tetra(int number, Subdivision :: RS_Mesh * mesh, int parent, IntArray & nodes);
286 int evaluateLongestEdge() override;
287 void bisect(std :: queue< int > &subdivqueue, std :: list< int > &sharedIrregularsQueue) override;
288 void generate(std :: list< int > &sharedEdgesQueue) override;
289 void update_neighbours() override;
290 double giveDensity() override;
291 bool isNeighborOf(Subdivision :: RS_Element *elem) override;
292 void giveSideNodes(int iside, IntArray &snodes) override;
293 int giveEdgeIndex(int iNode, int jNode) override;
294 void importConnectivity(ConnectivityTable *ct) override;
295#ifdef __OOFEG
296 void drawGeometry() override;
297#endif
298#ifdef __MPI_PARALLEL_MODE
299 void numberSharedEdges(int iNode, IntArray &connNodes) override;
300 void makeSharedEdges() override {
301 shared_edges.resize(6);
302 shared_edges.zero();
303 }
304#endif
305 };
306
307#ifdef __MPI_PARALLEL_MODE
309 {
310protected:
311 // parent edge nodes
313 // shared partitions except the local one
315 // mesh
317public:
318 RS_SharedEdge(Subdivision :: RS_Mesh * m) {
319 this->mesh = m;
320 }
321 void setEdgeNodes(int i, int j) {
322 iNode = i;
323 jNode = j;
324 }
325 void giveEdgeNodes(int &i, int &j) {
326 i = iNode;
327 j = jNode;
328 }
329 const IntArray *givePartitions() { return & partitions; }
330 void setPartitions(IntArray _p) { partitions = std :: move(_p); }
331 void addPartition(int _p, int allocChunk) { partitions.followedBy(_p, allocChunk); }
332 void removePartitions() { partitions.clear(); }
333 int giveSharedPartitions(IntArray &partitions);
334 };
335#endif
336
338 {
339 // HUHU protected? private?
340 std :: vector< std :: unique_ptr< Subdivision :: RS_Node > >nodes;
341 std :: vector< std :: unique_ptr< Subdivision :: RS_Element > >elements;
342#ifdef __MPI_PARALLEL_MODE
343 std :: vector< std :: unique_ptr< Subdivision :: RS_SharedEdge > >edges;
344#endif
346
347#ifdef __MPI_PARALLEL_MODE
349 std :: map< int, Subdivision :: RS_Node * >sharedNodeMap;
352#endif
353
354public:
355#ifdef __MPI_PARALLEL_MODE
357 this->subdivision = s;
359 }
360#else
361 RS_Mesh(Subdivision * s) : nodes(), elements() {
362 this->subdivision = s;
363 }
364#endif
366
367 Subdivision :: RS_Node *giveNode(int i) { return nodes[i-1].get(); }
368 Subdivision :: RS_Element *giveElement(int i) { return elements[i-1].get(); }
369 int giveNumberOfNodes() { return (int)nodes.size(); }
370 int giveNumberOfElements() { return (int)elements.size(); }
371 void addNode(Subdivision :: RS_Node *obj) { nodes.emplace_back(obj); }
372 void addElement(Subdivision :: RS_Element *obj) { elements.emplace_back(obj); }
373#ifdef __MPI_PARALLEL_MODE
374 Subdivision :: RS_SharedEdge *giveEdge(int i) { return edges[i-1].get(); }
375 int giveNumberOfEdges() { return (int)edges.size(); }
376 void addEdge(Subdivision :: RS_SharedEdge *obj) { edges.emplace_back(obj); }
378 void insertGlobalSharedNodeMap(Subdivision :: RS_Node *node);
379 int sharedNodeGlobal2Local(int _globnum);
380#endif
381
382 Subdivision *giveSubdivision() { return this->subdivision; }
383 };
384
386 {
388public:
390 m = _m;
391 }
392 int operator() (int i, int j);
393 };
394
396 Domain *d; // HUHU proc, subdivision ma pristup na domain
398 };
399
400 //RS_Mesh *oldMesh, *newMesh;
402 std :: queue< int >subdivqueue;
403 std :: list< int >sharedIrregularsQueue;
404 std :: list< int >sharedEdgesQueue;
405 // smoothing flag
407
408public:
411 mesh = 0;
412 smoothingFlag = false;
413 }
414 virtual ~Subdivision() {
415 if ( mesh ) {
416 delete mesh;
417 }
418 }
419
421 returnCode createMesh(TimeStep *tStep, int domainNumber, int domainSerNum, Domain **dNew) override;
422 const char *giveClassName() { return "Subdivision"; }
423 Domain *giveDomain() { return domain; }
424
425protected:
426 Subdivision :: RS_Mesh *giveMesh() { return mesh; }
427 void bisectMesh();
428 void smoothMesh();
429
430 bool isNodeLocalIrregular(Subdivision :: RS_Node *node, int myrank);
431 void assignGlobalNumbersToElements(Domain *d);
432
433#ifdef __MPI_PARALLEL_MODE
438 bool exchangeSharedIrregulars();
439 int packSharedIrregulars(Subdivision *s, ProcessCommunicator &pc);
440 int unpackSharedIrregulars(Subdivision *s, ProcessCommunicator &pc);
441 void assignGlobalNumbersToSharedIrregulars();
442 int packIrregularSharedGlobnums(Subdivision *s, ProcessCommunicator &pc);
443 int unpackIrregularSharedGlobnums(Subdivision *s, ProcessCommunicator &pc);
444 void exchangeSharedEdges();
445 int packSharedEdges(Subdivision *s, ProcessCommunicator &pc);
446 int unpackSharedEdges(Subdivision *s, ProcessCommunicator &pc);
447
449 bool isNodeLocalSharedIrregular(Subdivision :: RS_Node *node, int myrank);
450
451 int giveRank();
452 int giveNumberOfProcesses();
453
454 void exchangeRemoteElements(Domain *d, IntArray &);
455 int packRemoteElements(RS_packRemoteElemsStruct *s, ProcessCommunicator &pc);
456 int unpackRemoteElements(Domain *d, ProcessCommunicator &pc);
457
458#endif
459};
460} // end namespace oofem
461#endif // subdivision_h
int & at(std::size_t i)
Definition intarray.h:104
MesherInterface(Domain *d)
Constructor.
const IntArray * giveNodes()
const IntArray * giveSharedEdges()
virtual int giveEdgeIndex(int iNode, int jNode)=0
int giveLeIndex()
Returns the longest edge index of the receiver.
void setSharedEdge(int iedge, int num)
virtual void numberSharedEdges(int iNode, IntArray &connNodes)=0
elementParallelMode giveParallelMode() const
elementParallelMode parallel_mode
virtual void importConnectivity(ConnectivityTable *ct)=0
void setNeighbor(int iside, int nb)
RS_Element(int number, Subdivision ::RS_Mesh *m, int parent, IntArray &nodes)
bool isTerminal()
Returns true if receiver is terminal (not further subdivided).
bool hasIrregulars()
Returns true if element has some irregular nodes.
virtual void makeSharedEdges()=0
const IntArray * giveChildren()
const IntArray * giveNeighbors()
void setIrregular(int iedge, int ir)
virtual void bisect(std ::queue< int > &subdivqueue, std ::list< int > &sharedIrregularsQueue)
virtual void generate(std ::list< int > &sharedEdgesQueue)
virtual void giveSideNodes(int iside, IntArray &snodes)=0
void setLeIndex(int _n)
Sets the longest edge index.
virtual bool isNeighborOf(Subdivision ::RS_Element *elem)=0
void setParallelMode(elementParallelMode _mode)
RS_IrregularNode(int n, Subdivision ::RS_Mesh *mesh, int parent, FloatArray &c, double rd, bool boundary)
Subdivision::RS_SharedEdge * giveEdge(int i)
Subdivision::RS_Node * giveNode(int i)
void addElement(Subdivision ::RS_Element *obj)
bool sharedNodeMapInitialized
sharedNodeMap init flag
void addEdge(Subdivision ::RS_SharedEdge *obj)
Subdivision * giveSubdivision()
std ::vector< std ::unique_ptr< Subdivision ::RS_SharedEdge > > edges
std ::map< int, Subdivision ::RS_Node * > sharedNodeMap
Global shared node map (index is global shared node number).
Subdivision::RS_Element * giveElement(int i)
std ::vector< std ::unique_ptr< Subdivision ::RS_Node > > nodes
std ::vector< std ::unique_ptr< Subdivision ::RS_Element > > elements
void addNode(Subdivision ::RS_Node *obj)
void insertConnectedElement(int num)
dofManagerParallelMode parallel_mode
Definition subdivision.h:90
void setConnectedElements(IntArray _conn)
void preallocateConnectedElements(int size)
void eraseConnectedElement(int num)
RS_Node(int n, Subdivision ::RS_Mesh *m, int parent, const FloatArray &c, double rd, bool boundary)
Definition subdivision.h:98
void setParallelMode(dofManagerParallelMode _mode)
void setPartitions(IntArray _p)
dofManagerParallelMode giveParallelMode() const
FloatArray * giveCoordinates()
const IntArray * giveConnectedElements()
const IntArray * givePartitions()
void giveEdgeNodes(int &i, int &j)
RS_SharedEdge(Subdivision ::RS_Mesh *m)
const IntArray * givePartitions()
void addPartition(int _p, int allocChunk)
void importConnectivity(ConnectivityTable *ct) override
void giveSideNodes(int iside, IntArray &snodes) override
int giveEdgeIndex(int iNode, int jNode) override
double giveDensity() override
void makeSharedEdges() override
RS_Tetra(int number, Subdivision ::RS_Mesh *mesh, int parent, IntArray &nodes)
void numberSharedEdges(int iNode, IntArray &connNodes) override
void bisect(std ::queue< int > &subdivqueue, std ::list< int > &sharedIrregularsQueue) override
bool isNeighborOf(Subdivision ::RS_Element *elem) override
void generate(std ::list< int > &sharedEdgesQueue) override
void update_neighbours() override
int evaluateLongestEdge() override
RS_Triangle(int number, Subdivision ::RS_Mesh *mesh, int parent, IntArray &nodes)
void generate(std ::list< int > &sharedEdgesQueue) override
void giveSideNodes(int iside, IntArray &snodes) override
void numberSharedEdges(int iNode, IntArray &connNodes) override
void importConnectivity(ConnectivityTable *ct) override
bool isNeighborOf(Subdivision ::RS_Element *elem) override
int giveEdgeIndex(int iNode, int jNode) override
void bisect(std ::queue< int > &subdivqueue, std ::list< int > &sharedIrregularsQueue) override
Subdivision::RS_Mesh * giveMesh()
std ::queue< int > subdivqueue
std ::list< int > sharedEdgesQueue
Domain * giveDomain()
virtual ~Subdivision()
Subdivision(Domain *d)
Constructor.
const char * giveClassName()
std ::list< int > sharedIrregularsQueue
elementParallelMode
Definition element.h:87
@ Element_local
Element is local, there are no contributions from other domains to this element.
Definition element.h:88
dofManagerParallelMode
In parallel mode, this type indicates the mode of DofManager.
Definition dofmanager.h:66
@ DofManager_local
Definition dofmanager.h:67
#define OOFEM_EXPORT
Definition oofemcfg.h:7

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