2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008,2009 Oliver Gloth +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 #ifndef MESHPARTITION_H
25 #define MESHPARTITION_H
29 #include "egvtkobject.h"
31 class MeshPartition
: public EgVtkObject
34 private: // attributes
37 vtkUnstructuredGrid
* m_Grid
; ///< the grid underlying this mesh partition
38 QVector
<vtkIdType
> m_Cells
; ///< all cells of the mesh partition
39 QVector
<int> m_LCells
; ///< inverse indexing for the cells
40 QVector
<vtkIdType
> m_Nodes
; ///< all nodes of the mesh partition
41 QVector
<int> m_LNodes
; ///< inverse indexing for the nodes
42 QVector
<QVector
<int> > m_N2C
; ///< node to cell information
43 QVector
<QVector
<int> > m_N2N
; ///< node to node information
44 QVector
<QVector
<int> > m_C2C
; ///< cell to cell information
46 int m_CellsStamp
; ///< "time"-stamp
47 int m_LCellsStamp
; ///< "time"-stamp
48 int m_NodesStamp
; ///< "time"-stamp
49 int m_LNodesStamp
; ///< "time"-stamp
50 int m_N2NStamp
; ///< "time"-stamp
51 int m_N2CStamp
; ///< "time"-stamp
52 int m_C2CStamp
; ///< "time"-stamp
56 void resetTimeStamps();
66 /// Create an empty (undefined) mesh partition
70 * Create a mesh partition with the grid set. Optionally all cells can be selected.
71 * @param grid the grid to use
72 * @param use_all_cells if set to true all cells will be selected;
74 MeshPartition(vtkUnstructuredGrid
*grid
, bool use_all_cells
= false);
77 * Create a mesh partition from a global volume definition
78 * @param volume_name the name of the volume
80 MeshPartition(QString volume_name
);
84 * @param a pointer to the grid
86 void setGrid(vtkUnstructuredGrid
*grid
) { m_Grid
= grid
; }
90 * @return a pointer to the grid
92 vtkUnstructuredGrid
* getGrid() const { return m_Grid
; }
95 * Define the mesh partition by defining its cells.
96 * @param cls the cells of the subset
99 void setCells(const C
& cls
);
102 * Define the mesh partition by defining all its cells.
107 * Define the mesh partition by giving a symbolic volume name.
108 * The grid will be changed to the default (main) grid that is currently loaded into ENGRID.
109 * @param volume_name the symbolic volume name
111 void setVolume(QString volume_name
);
114 * Define the mesh partition as the remainder of an existing partition.
115 * @param part the existing partition
117 void setRemainder(const MeshPartition
& part
);
119 const QVector
<vtkIdType
>& getCells() const; ///< Access to the cell indices
120 const QVector
<int>& getLocalCells(); ///< Access to the local cell indices
121 const QVector
<vtkIdType
>& getNodes(); ///< Access to the node indices
122 const QVector
<int>& getLocalNodes(); ///< Access to the local node indices
123 const QVector
<QVector
<int> >& getN2N(); ///< Access to the local node to node structure
124 const QVector
<QVector
<int> >& getN2C(); ///< Access to the local node to cell structure
125 const QVector
<QVector
<int> >& getC2C(); ///< Access to the local cell to cell structure
127 void setVolumeOrientation(); ///< change the face orientation to match the volume definition
128 void setOriginalOrientation(); ///< change the orientation to match the original orientation
131 * Copy the partition to a VTK grid.
132 * @param new_grid the grid to copy the partition to (will be resized accordingly).
134 void extractToVtkGrid(vtkUnstructuredGrid
*new_grid
);
137 * Add another partition to this one.
138 * At the moment overlapping partitions on two different grids will not be handled well.
139 * If both partitions do not have the same underlying grid the grid will be extended in order
140 * to add the other partition.
141 * @param part the partition to add
143 void addPartition(const MeshPartition
& part
);
146 * compute the smallest edge length of the partition
147 * @return the smallest edge length
149 double getSmallestEdgeLength() const;
152 * Get the number of nodes in the partition.
153 * @return the number of nodes
155 int getNumberOfNodes();
158 * Get the number of cells in the partition.
159 * @return the number of cells
161 int getNumberOfCells();
163 int localNode(vtkIdType id_node
);
164 vtkIdType
globalNode(int i
);
165 int localCell(vtkIdType id_cell
);
166 vtkIdType
globalCell(int i
);
169 int n2nLSize(int i_nodes
);
170 int n2nLL(int i_nodes
, int j
);
171 vtkIdType
n2nLG(int i_nodes
, int j
);
172 int n2nGSize(vtkIdType id_node
);
173 int n2nGL(vtkIdType id_node
, int j
);
174 vtkIdType
n2nGG(vtkIdType id_node
, int j
);
175 int n2cLSize(int i_nodes
);
176 int n2cLL(int i_nodes
, int j
);
177 vtkIdType
n2cLG(int i_nodes
, int j
);
178 int n2cGSize(vtkIdType id_node
);
179 int n2cGL(vtkIdType id_node
, int j
);
180 vtkIdType
n2cGG(vtkIdType id_node
, int j
);
181 int c2cLSize(int i_cells
);
182 int c2cLL(int i_cells
, int j
);
183 vtkIdType
c2cLG(int i_cells
, int j
);
184 int c2cGSize(vtkIdType id_cell
);
185 int c2cGL(vtkIdType id_cell
, int j
);
186 vtkIdType
c2cGG(vtkIdType id_cell
, int j
);
192 inline void MeshPartition::setCells(const C
& cls
)
194 m_Cells
.resize(cls
.size());
195 qCopy(cls
.begin(), cls
.end(), m_Cells
.begin());
199 inline void MeshPartition::setAllCells() {
200 QVector
<vtkIdType
> all_cells
;
201 getAllCells(all_cells
, m_Grid
);
202 this->setCells(all_cells
);
205 inline void MeshPartition::checkNodes()
207 if (m_CellsStamp
> m_NodesStamp
) {
208 getNodesFromCells(m_Cells
, m_Nodes
, m_Grid
);
209 m_NodesStamp
= m_CellsStamp
;
213 inline void MeshPartition::checkLCells()
215 if (m_CellsStamp
> m_LCellsStamp
) {
216 createCellMapping(m_Cells
, m_LCells
, m_Grid
);
217 m_LCellsStamp
= m_CellsStamp
;
221 inline void MeshPartition::checkLNodes()
224 if (m_NodesStamp
> m_LNodesStamp
) {
225 createNodeMapping(m_Nodes
, m_LNodes
, m_Grid
);
226 m_LNodesStamp
= m_NodesStamp
;
230 inline void MeshPartition::checkN2N()
233 if (m_LNodesStamp
> m_N2NStamp
) {
234 createNodeToNode(m_Cells
, m_Nodes
, m_LNodes
, m_N2N
, m_Grid
);
235 m_N2NStamp
= m_LNodesStamp
;
239 inline void MeshPartition::checkN2C()
242 if (m_LNodesStamp
> m_N2CStamp
) {
243 createNodeToCell(m_Cells
, m_Nodes
, m_LNodes
, m_N2C
, m_Grid
);
244 m_N2CStamp
= m_LNodesStamp
;
248 inline void MeshPartition::checkC2C()
250 if (m_CellsStamp
> m_C2CStamp
) {
251 createCellToCell(m_Cells
, m_C2C
, m_Grid
);
252 m_C2CStamp
= m_CellsStamp
;
256 inline const QVector
<vtkIdType
>& MeshPartition::getCells() const
261 inline const QVector
<int>& MeshPartition::getLocalCells()
267 inline const QVector
<vtkIdType
>& MeshPartition::getNodes()
273 inline const QVector
<int>& MeshPartition::getLocalNodes()
279 inline const QVector
<QVector
<int> >& MeshPartition::getN2N()
285 inline const QVector
<QVector
<int> >& MeshPartition::getN2C()
291 inline const QVector
<QVector
<int> >& MeshPartition::getC2C()
297 inline int MeshPartition::n2nLSize(int i_nodes
)
300 return m_N2N
[i_nodes
].size();
303 inline int MeshPartition::n2nLL(int i_nodes
, int j
)
306 return m_N2N
[i_nodes
][j
];
309 inline vtkIdType
MeshPartition::n2nLG(int i_nodes
, int j
)
312 return m_Nodes
[m_N2N
[i_nodes
][j
]];
315 inline int MeshPartition::n2nGSize(vtkIdType id_node
)
318 return m_N2N
[m_LNodes
[id_node
]].size();
321 inline int MeshPartition::n2nGL(vtkIdType id_node
, int j
)
324 return m_N2N
[m_LNodes
[id_node
]][j
];
327 inline vtkIdType
MeshPartition::n2nGG(vtkIdType id_node
, int j
)
330 return m_Nodes
[m_N2N
[m_LNodes
[id_node
]][j
]];
333 inline int MeshPartition::n2cLSize(int i_nodes
)
336 return m_N2C
[i_nodes
].size();
339 inline int MeshPartition::n2cLL(int i_nodes
, int j
)
342 return m_N2C
[i_nodes
][j
];
345 inline vtkIdType
MeshPartition::n2cLG(int i_nodes
, int j
)
348 int i_cell
= m_N2C
[i_nodes
][j
];
349 if(i_cell
<0) return(-1);
350 else return m_Cells
[i_cell
];
353 inline int MeshPartition::n2cGSize(vtkIdType id_node
)
356 return m_N2C
[m_LNodes
[id_node
]].size();
359 inline int MeshPartition::n2cGL(vtkIdType id_node
, int j
)
362 return m_N2C
[m_LNodes
[id_node
]][j
];
365 inline vtkIdType
MeshPartition::n2cGG(vtkIdType id_node
, int j
)
368 int i_cell
= m_N2C
[m_LNodes
[id_node
]][j
];
369 if(i_cell
<0) return(-1);
370 else return m_Cells
[i_cell
];
373 inline int MeshPartition::c2cLSize(int i_cells
)
376 return m_C2C
[i_cells
].size();
379 inline int MeshPartition::c2cLL(int i_cells
, int j
)
382 return m_C2C
[i_cells
][j
];
385 inline vtkIdType
MeshPartition::c2cLG(int i_cells
, int j
)
388 int i_cell
= m_C2C
[i_cells
][j
];
389 if(i_cell
<0) return(-1);
390 else return m_Cells
[i_cell
];
393 inline int MeshPartition::c2cGSize(vtkIdType id_cell
)
397 return m_C2C
[m_LCells
[id_cell
]].size();
400 inline int MeshPartition::c2cGL(vtkIdType id_cell
, int j
)
404 return m_C2C
[m_LCells
[id_cell
]][j
];
407 inline vtkIdType
MeshPartition::c2cGG(vtkIdType id_cell
, int j
)
411 int i_cell
= m_C2C
[m_LCells
[id_cell
]][j
];
412 if(i_cell
<0) return(-1);
413 else return m_Cells
[i_cell
];
416 inline int MeshPartition::getNumberOfCells()
418 return m_Cells
.size();
421 inline int MeshPartition::getNumberOfNodes()
424 return m_Nodes
.size();
427 inline int MeshPartition::localNode(vtkIdType id_node
)
430 return m_LNodes
[id_node
];
433 inline vtkIdType
MeshPartition::globalNode(int i
)
439 inline int MeshPartition::localCell(vtkIdType id_cell
)
442 return m_LCells
[id_cell
];
445 inline vtkIdType
MeshPartition::globalCell(int i
)
448 else return m_Cells
[i
];
451 #endif // MESHPARTITION_H