OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
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 - 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 #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 
52 namespace 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 
61 class TimeStep;
62 class ProcessCommunicator;
63 
69 class OOFEM_EXPORT Subdivision : public MesherInterface
70 {
71 protected:
72  class RS_Mesh;
73  class RS_Node
74  {
75 protected:
78  int number;
79  int parent; // number of parent node or zero for new nodes
80  bool boundary;
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 __PARALLEL_MODE
96 #endif
97 public:
98  RS_Node(int n, Subdivision :: RS_Mesh * m, int parent, 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 __PARALLEL_MODE
107  this->parallel_mode = DofManager_local;
108 #endif
109  }
110  virtual ~RS_Node() { }
111  double giveRequiredDensity() { return requiredDensity; }
112  FloatArray *giveCoordinates() { return & coords; }
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);
120  const IntArray *giveConnectedElements() { return & connectedElements; }
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); }
125  int giveGlobalNumber() { return globalNumber; }
126  void setGlobalNumber(int gn) { this->globalNumber = gn; }
127  virtual bool isIrregular() { return false; }
128 
129 #ifdef __PARALLEL_MODE
130  void numberSharedEdges();
131  dofManagerParallelMode giveParallelMode() const { return parallel_mode; }
132  void setParallelMode(dofManagerParallelMode _mode) { parallel_mode = _mode; }
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 
142  class RS_IrregularNode : public RS_Node
143  {
144 protected:
145  int iNode, jNode; // parent edge nodes
146 public:
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  virtual bool isIrregular() { return true; }
157  };
158 
160  {
161 protected:
162  int number;
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
172  int parent;
173  // longest edge index
174  int leIndex;
175  // mesh
177  // flag whether element is in bisection queue
180 #ifdef __PARALLEL_MODE
182  // numbers of shared edges
184 #endif
185 public:
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 __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);
226  virtual void importConnectivity(ConnectivityTable *ct) = 0;
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
240  int giveGlobalNumber() { return globalNumber; }
241  void setGlobalNumber(int gn) { this->globalNumber = gn; }
242 
243 #ifdef __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; }
249  elementParallelMode giveParallelMode() const { return parallel_mode; }
250  // Sets parallel mode of element
251  void setParallelMode(elementParallelMode _mode) { parallel_mode = _mode; }
252 #endif
253  };
254 
256  {
257 public:
258  RS_Triangle(int number, Subdivision :: RS_Mesh * mesh, int parent, IntArray & nodes);
259  int evaluateLongestEdge();
260  void bisect(std :: queue< int > &subdivqueue, std :: list< int > &sharedIrregularsQueue);
261  void generate(std :: list< int > &sharedEdgesQueue);
262  void update_neighbours();
263  double giveDensity();
264  bool isNeighborOf(Subdivision :: RS_Element *elem);
265  void giveSideNodes(int iside, IntArray &snodes);
266  int giveEdgeIndex(int iNode, int jNode);
267  virtual void importConnectivity(ConnectivityTable *ct);
268 #ifdef __OOFEG
269  void drawGeometry();
270 #endif
271 #ifdef __PARALLEL_MODE
272  void numberSharedEdges(int iNode, IntArray &connNodes);
274  shared_edges.resize(3);
275  shared_edges.zero();
276  }
277 #endif
278  };
279 
280  class RS_Tetra : public Subdivision :: RS_Element
281  {
282 protected:
284 public:
285  RS_Tetra(int number, Subdivision :: RS_Mesh * mesh, int parent, IntArray & nodes);
286  int evaluateLongestEdge();
287  void bisect(std :: queue< int > &subdivqueue, std :: list< int > &sharedIrregularsQueue);
288  void generate(std :: list< int > &sharedEdgesQueue);
289  void update_neighbours();
290  double giveDensity();
291  bool isNeighborOf(Subdivision :: RS_Element *elem);
292  void giveSideNodes(int iside, IntArray &snodes);
293  int giveEdgeIndex(int iNode, int jNode);
294  virtual void importConnectivity(ConnectivityTable *ct);
295 #ifdef __OOFEG
296  void drawGeometry();
297 #endif
298 #ifdef __PARALLEL_MODE
299  void numberSharedEdges(int iNode, IntArray &connNodes);
301  shared_edges.resize(6);
302  shared_edges.zero();
303  }
304 #endif
305  };
306 
307 #ifdef __PARALLEL_MODE
309  {
310 protected:
311  // parent edge nodes
312  int iNode, jNode;
313  // shared partitions except the local one
315  // mesh
317 public:
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 
337  class RS_Mesh
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 __PARALLEL_MODE
343  std :: vector< std :: unique_ptr< Subdivision :: RS_SharedEdge > >edges;
344 #endif
346 
347 #ifdef __PARALLEL_MODE
348  std :: map< int, Subdivision :: RS_Node * >sharedNodeMap;
352 #endif
353 
354 public:
355 #ifdef __PARALLEL_MODE
356  RS_Mesh(Subdivision * s) : nodes(), elements(), edges() {
357  this->subdivision = s;
358  sharedNodeMapInitialized = false;
359  }
360 #else
361  RS_Mesh(Subdivision * s) : nodes(), elements() {
362  this->subdivision = s;
363  }
364 #endif
365  ~RS_Mesh() {}
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 __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); }
377  void initGlobalSharedNodeMap() { sharedNodeMap.clear(); }
378  void insertGlobalSharedNodeMap(Subdivision :: RS_Node *node);
379  int sharedNodeGlobal2Local(int _globnum);
380 #endif
381 
382  Subdivision *giveSubdivision() { return this->subdivision; }
383  };
384 
386  {
388 public:
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 
408 public:
411  mesh = 0;
412  smoothingFlag = false;
413  }
414  virtual ~Subdivision() {
415  if ( mesh ) {
416  delete mesh;
417  }
418  }
419 
421  virtual returnCode createMesh(TimeStep *tStep, int domainNumber, int domainSerNum, Domain **dNew);
422  const char *giveClassName() { return "Subdivision"; }
423  Domain *giveDomain() { return domain; }
424 
425 protected:
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 __PARALLEL_MODE
434 
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
void eraseSorted(int value)
Erase the element of given value.
Definition: intarray.C:374
Subdivision * giveSubdivision()
Definition: subdivision.h:382
void setEdgeNodes(int i, int j)
Definition: subdivision.h:321
int giveLeIndex()
Returns the longest edge index of the receiver.
Definition: subdivision.h:233
std::list< int > sharedIrregularsQueue
Definition: subdivision.h:403
void setLeIndex(int _n)
Sets the longest edge index.
Definition: subdivision.h:235
Class and object Domain.
Definition: domain.h:115
dofManagerParallelMode giveParallelMode() const
Definition: subdivision.h:131
void eraseConnectedElement(int num)
Definition: subdivision.h:123
virtual void update_neighbours()
Definition: subdivision.h:211
bool hasIrregulars()
Returns true if element has some irregular nodes.
Definition: subdivision.h:201
bool isEmpty() const
Checks if receiver is empty (i.e., zero sized).
Definition: intarray.h:208
bool sharedNodeMapInitialized
sharedNodeMap init flag
Definition: subdivision.h:351
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
const char * giveClassName()
Definition: subdivision.h:422
const IntArray * giveNeighbors()
Definition: subdivision.h:216
std::queue< int > subdivqueue
Definition: subdivision.h:402
virtual void generate(std::list< int > &sharedEdgesQueue)
Definition: subdivision.h:210
void setNeighbor(int iside, int nb)
Definition: subdivision.h:218
RS_IrregularNode(int n, Subdivision::RS_Mesh *mesh, int parent, FloatArray &c, double rd, bool boundary)
Definition: subdivision.h:147
Subdivision(Domain *d)
Constructor.
Definition: subdivision.h:410
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
FloatArray * giveCoordinates()
Definition: subdivision.h:112
IntArray partitions
List of partition sharing the shared dof manager or remote partion containing remote dofmanager count...
Definition: subdivision.h:95
dofManagerParallelMode
In parallel mode, this type indicates the mode of DofManager.
Definition: dofmanager.h:80
bool isTerminal()
Returns true if receiver is terminal (not further subdivided)
Definition: subdivision.h:203
This class represents the Rivara Subdivision algorithm for triangular meshes.
Definition: subdivision.h:69
bool containsOnlyZeroes() const
Checks if receiver is all zero.
Definition: intarray.C:172
void setConnectedElements(IntArray _conn)
Definition: subdivision.h:121
virtual void bisect(std::queue< int > &subdivqueue, std::list< int > &sharedIrregularsQueue)
Definition: subdivision.h:209
void addEdge(Subdivision::RS_SharedEdge *obj)
Definition: subdivision.h:376
void setParallelMode(dofManagerParallelMode _mode)
Definition: subdivision.h:132
double giveCoordinate(int i)
Definition: subdivision.h:113
elementParallelMode giveParallelMode() const
Definition: subdivision.h:249
const IntArray * givePartitions()
Definition: subdivision.h:329
virtual bool isIrregular()
Definition: subdivision.h:127
void insertSorted(int value, int allocChunk=0)
Inserts given value into a receiver, which is assumed to be sorted.
Definition: intarray.C:350
void addPartition(int _p, int allocChunk)
Definition: subdivision.h:331
void setIrregular(int iedge, int ir)
Definition: subdivision.h:206
std::vector< std::unique_ptr< Subdivision::RS_Element > > elements
Definition: subdivision.h:341
void insertConnectedElement(int num)
Definition: subdivision.h:122
void clear()
Clears the array (zero size).
Definition: intarray.h:177
virtual ~Subdivision()
Definition: subdivision.h:414
void addElement(Subdivision::RS_Element *obj)
Definition: subdivision.h:372
Domain * giveDomain()
Definition: subdivision.h:423
RS_Node(int n, Subdivision::RS_Mesh *m, int parent, FloatArray &c, double rd, bool boundary)
Definition: subdivision.h:98
The base class representing the interface to mesh generation package.
Class representing connectivity table.
Class representing process communicator for engineering model.
Definition: processcomm.h:176
void giveEdgeNodes(int &i, int &j)
Definition: subdivision.h:325
dofManagerParallelMode parallel_mode
Definition: subdivision.h:90
elementParallelMode
In parallel mode, this type indicates the mode of element.
Definition: element.h:100
void setSharedEdge(int iedge, int num)
Definition: subdivision.h:248
RS_Element(int number, Subdivision::RS_Mesh *m, int parent, IntArray &nodes)
Definition: subdivision.h:186
Class representing vector of real numbers.
Definition: floatarray.h:82
Subdivision::RS_Mesh * giveMesh()
Definition: subdivision.h:426
Element is local, there are no contributions from other domains to this element.
Definition: element.h:101
const IntArray * giveChildren()
Definition: subdivision.h:214
virtual double giveDensity()
Definition: subdivision.h:212
Subdivision::RS_SharedEdge * giveEdge(int i)
Definition: subdivision.h:374
std::vector< std::unique_ptr< Subdivision::RS_Node > > nodes
Definition: subdivision.h:340
void followedBy(const IntArray &b, int allocChunk=0)
Appends array b at the end of receiver.
Definition: intarray.C:145
const IntArray * givePartitions()
Definition: subdivision.h:133
RS_SharedEdge(Subdivision::RS_Mesh *m)
Definition: subdivision.h:318
void giveEdgeNodes(int &i, int &j)
Definition: subdivision.h:152
void addNode(Subdivision::RS_Node *obj)
Definition: subdivision.h:371
void setParallelMode(elementParallelMode _mode)
Definition: subdivision.h:251
void preallocate(int futureSize)
Preallocates receiver to given futureSize if larger then allocatedSize.
Definition: intarray.C:130
std::list< int > sharedEdgesQueue
Definition: subdivision.h:404
const IntArray * giveNodes()
Definition: subdivision.h:227
elementParallelMode parallel_mode
Definition: subdivision.h:181
the oofem namespace is to define a context or scope in which all oofem names are defined.
DofManager is local, there are no contribution from other domains to this DofManager.
Definition: dofmanager.h:81
Subdivision::RS_Element * giveElement(int i)
Definition: subdivision.h:368
Subdivision::RS_Node * giveNode(int i)
Definition: subdivision.h:367
const IntArray * giveSharedEdges()
Definition: subdivision.h:245
std::vector< std::unique_ptr< Subdivision::RS_SharedEdge > > edges
Definition: subdivision.h:343
Class representing solution step.
Definition: timestep.h:80
void preallocateConnectedElements(int size)
Definition: subdivision.h:124
void setPartitions(IntArray _p)
Definition: subdivision.h:134
int findFirstIndexOf(int value) const
Finds index of first occurrence of given value in array.
Definition: intarray.C:331
const IntArray * giveConnectedElements()
Definition: subdivision.h:120

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