GemaMesh
The GeMA Mesh Plugin
Loading...
Searching...
No Matches
gmpCell.h
1/************************************************************************
2**
3** Copyright (C) 2014 by Carlos Augusto Teixera Mendes
4** All rights reserved.
5**
6** This file is part of the "GeMA" software. It's use should respect
7** the terms in the license agreement that can be found together
8** with this source code.
9** It is provided AS IS, with NO WARRANTY OF ANY KIND,
10** INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR
11** A PARTICULAR PURPOSE.
12**
13************************************************************************/
14
24#ifndef _GEMA_PLUGIN_CELL_BASE_H_
25#define _GEMA_PLUGIN_CELL_BASE_H_
26
27#include <gmElement.h>
28#include <gmMesh.h>
29#include <assert.h>
30
31#include <gmMemory.h>
32#include <gmPropertySet.h>
33#include <gmCellMesh.h>
34#include <gmLuaCell.h>
35
36#include <luaProxy.h>
37
38#include <QVarLengthArray>
39
40#include "gmpCellMeshData.h"
41
42 // IMPORTANT: If this values are changed, please also change the GmpCell type specification on
43 // the gemaCoreLib.natvis file
44
45
54#define GM_CELLBASE_ACTIVE_MASK (~(~0u >> 1))
55
59#define GM_CELLBASE_MESH_MASK ((~(~0u >> GMP_GEMAMESH_CELL_MESH_BITS)) >> 1)
60
62#define GM_CELLBASE_CELL_MASK (~(GM_CELLBASE_ACTIVE_MASK | GM_CELLBASE_MESH_MASK))
63
64static_assert((GM_CELLBASE_ACTIVE_MASK | GM_CELLBASE_MESH_MASK | GM_CELLBASE_CELL_MASK) == ~0u, "Invalid masks");
65static_assert((GM_CELLBASE_ACTIVE_MASK & GM_CELLBASE_MESH_MASK) == 0, "Invalid masks");
66static_assert((GM_CELLBASE_ACTIVE_MASK & GM_CELLBASE_CELL_MASK) == 0, "Invalid masks");
67static_assert((GM_CELLBASE_MESH_MASK & GM_CELLBASE_CELL_MASK) == 0, "Invalid masks");
68
72static inline bool GmpCellIsActive(int cellId) { return !(cellId & GM_CELLBASE_ACTIVE_MASK); }
73
75static inline int GmpCellMakeActive(int cellId) { return cellId & (~GM_CELLBASE_ACTIVE_MASK); }
76
78static inline int GmpCellMakeInactive(int cellId) { return cellId | GM_CELLBASE_ACTIVE_MASK; }
79
81static inline int GmpCellSetActiveFlag(int cellId, bool active) { return active ? GmpCellMakeActive(cellId) : GmpCellMakeInactive(cellId); }
82
83
85static inline int GmpCellMeshIndex(int cellId) { return (cellId & GM_CELLBASE_MESH_MASK) >> GMP_GEMAMESH_CELL_ID_BITS; }
86
88static inline int GmpCellIndex(int cellId) { return (cellId & GM_CELLBASE_CELL_MASK); }
89
91static inline int GmpCellUpdateMeshIndex(int id, int oldId) { return (id & ~GM_CELLBASE_MESH_MASK) | (oldId & GM_CELLBASE_MESH_MASK); }
92
94static inline int GmpCellEncodeId(int cellIndex, int meshIndex, bool active)
95{
96 assert(cellIndex >= 0 && cellIndex < GMP_GEMAMESH_MAX_NUM_CELLS);
97 assert(meshIndex >= 0 && meshIndex < GMP_GEMAMESH_MAX_NUM_MESHES);
98 return GmpCellSetActiveFlag(cellIndex | (meshIndex << GMP_GEMAMESH_CELL_ID_BITS), active);
99}
100
101
131template <class Base, class Proxy, class CellMeshData, GmCellType T, int N> class GmpCell : public Base
132{
133public:
135 GmpCell(int meshId, int cellId, int offset)
136 {
137 assert(N == geometry().numNodes());
138 _cellId = GmpCellEncodeId(cellId, meshId, true); // cell is initially active
140 }
141
142 // See comments on the base class
143 virtual int cellId() const { return GmpCellIndex(_cellId); }
144
145 // See comments on the base class
146 virtual GmCellMesh* mesh() const { return CellMeshData::mesh(GmpCellMeshIndex(_cellId)); }
147
148 // See comments on the base class
149 virtual bool active() const { return GmpCellIsActive(_cellId); }
150
151 // See comments on the base class
152 virtual void setActive(bool active)
153 {
154 if(active == this->active())
155 return;
156
157 _cellId = GmpCellSetActiveFlag(_cellId, active);
158 mesh()->activeCellUpdated(type(), active);
159 }
160
161 // See comments on the base class
162 virtual void pushProxy(lua_State* L, const GmLogCategory& logger) { LuaProxy::pushObject(L, new Proxy(this, logger)); }
163
164 // See comments on the base class
165 virtual GmCellType type() const { return T; }
166
167 // See comments on the base class
168 virtual int numNodes() const { return N; }
169
170 // See comments on the base class
171 virtual int nodeIndex(int localIndex) const
172 {
173 assert(localIndex >= 0 && localIndex < N);
174 return meshData()->cellNodesPtr(_nodeOffset)[localIndex];
175 }
176
177 // See comments on the base class.
178 virtual void nodes(int* nodeList, bool ghost) const
179 {
180 Q_UNUSED(ghost); assert(!ghost); // This class does not supports ghost nodes. This is handled by GmpGemaGhostCell
181 memcpy(nodeList, meshData()->cellNodesPtr(_nodeOffset), N * sizeof(int));
182 }
183
184 // See comments on the base class
185 virtual bool setNodes(const int* nodeList)
186 {
187 assert(nodeList);
188
189#if 0 // Checked when first reading the mesh. Also tested at the API on the Lua binding.
190 int nnodes = mesh()->numNodes();
191 for(int i = 0; i < N; i++)
192 {
193 int node = nodeList[i];
194 if(node < 0 || node >= nnodes)
195 return false;
196 }
197#endif
198 // If the mesh has a topology structure and the cell has already been added to that structure,
199 // we can't update the set of node cells.
200 if(meshData()->cellIsTopologyIndexed(cellId()))
201 return false;
202
203 // Update!
204 memcpy(meshData()->cellNodesPtr(_nodeOffset), nodeList, N * sizeof(int));
205 return true;
206 }
207
208 // See comments on the base class
209 virtual int propertyIndex(int propertySet) const
210 {
211 assert(propertySet >= 0 && propertySet < mesh()->propertySets().size());
212 return meshData()->cellPropertiesPtr(cellId())[propertySet];
213 }
214
215 // See comments on the base class
216 virtual bool setProperties(const int* propList, int nprop)
217 {
218 assert(propList);
219 assert(nprop == mesh()->propertySets().size());
220
221 memcpy(meshData()->cellPropertiesPtr(cellId()), propList, nprop*sizeof(int));
222 return true;
223 }
224
237 void replaceCellId(int id, bool keepActiveFlag)
238 {
239 id = GmpCellUpdateMeshIndex(id, _cellId);
240 if(keepActiveFlag)
241 _cellId = GmpCellSetActiveFlag(id, active());
242 else
243 _cellId = id;
244 }
245
249 int offset() const { return _nodeOffset; }
250
253
254protected:
256 CellMeshData* meshData() const { return (CellMeshData*)GmpCellMeshDataBase::meshData(GmpCellMeshIndex(_cellId)); }
257
260};
261
262
264template <class Base, class Proxy, class CellMeshData, GmCellType T, int N> class GmpGhostCell
265 : public GmpCell<Base, Proxy, CellMeshData, T, N>
266{
267public:
269 GmpGhostCell(int meshId, int cellId, int offset)
270 : GmpCell<Base, Proxy, CellMeshData, T, N>(meshId, cellId, offset) {}
271
272 // See comments on the base class
273 virtual int numGhostNodes() const { return _ghostList.size(); }
274
275 // See comments on the base class
276 virtual int addGhostNode(int globalIndex)
277 {
278 int index = GmMesh::clearGhostFlag(globalIndex);
279 if(index < 0 || index >= mesh()->numGhostNodes())
280 return -1;
281
283
285 return N + _ghostList.size() - 1;
286 }
287
288 // See comments on the base class
289 virtual void setGhostNodes(int* ghostNodes, int numNodes)
290 {
291 replaceGhostNodes(ghostNodes, numNodes);
293 }
294
295 // See comments on the base class
296 virtual void removeGhostNode(int localIndex)
297 {
298 assert(localIndex >= N && localIndex < N + (int)_ghostList.size());
299 _ghostList.remove(localIndex-N, 1);
300 }
301
302 // See comments on the base class
303 virtual int nodeIndex(int localIndex) const
304 {
305 assert(localIndex >= 0 && localIndex < N + (int)_ghostList.size());
306 return localIndex < N ? GmpCell<Base, Proxy, CellMeshData, T, N>::nodeIndex(localIndex) : _ghostList[localIndex-N];
307 }
308
309 // See comments on the base class.
310 virtual void nodes(int* nodeList, bool ghost) const
311 {
312 GmpCell<Base, Proxy, CellMeshData, T, N>::nodes(nodeList, false); // Copy geometry nodes
313 if(ghost)
314 memcpy(nodeList+N, _ghostList.data(), _ghostList.size()*sizeof(int));
315 }
316
322 void replaceGhostNodes(int* ghostNodes, int numNodes)
323 {
325 memcpy(_ghostList.data(), ghostNodes, numNodes * sizeof(int));
326 }
327
328protected:
329 template <template <class> class Vector> friend class GmpCellMeshData; // Needs access to _ghostList...
330
345};
346
347
353template <int H>
355{
356public:
357 // See comments on GmHElement::POrder()
358 virtual int hPOrder() const { return GmpCellMeshDataBase::hierarchicalPOrder(H); }
359
360 // See comments on GmHElement::QOrder()
361 virtual int hQOrder() const { return GmpCellMeshDataBase::hierarchicalQOrder(H); }
362};
363
364// ---------------------------------------------------------------------------------------------------------------------------
365// VERY IMPORTANT considerations:
366//
367// Sanity checks to make sure that the size and memory layout of a cell object class independs on the base cell class
368// (GmCell or GmElement), cell proxy, mesh data class, celltype (including hierarchical types) and number of nodes
369// template parameters. This should hold true as long as we don't have added attributes to the base class.
370//
371// This is IMPORTANT to enable casting a GmCell* into a GmpCell<GmCell, GmLuaCell, GmpCellMeshData<GmSingleVector>, GM_BAR2, 2>
372// or into a GmpGhostCell<GmCell, GmLuaCell, GmpCellMeshData<GmSingleVector>, GM_BAR2, 2> to have access to the
373// offset field and to the ghost nodes list. We need that on few localized places in GmpCellMeshData and in uibhmGeometry.
374// Look for a cast to GmpCellMeshData::CellPrototype or GhostCellPrototype.
375// Of course an object casted in this way CAN NOT safely access any virtual method. It can only access non virtual functions
376// such as the offset handling methods or attributes directly.
377//
378// Notice that adding an attribute to the derived class is OK, so we can add an attribute to XfemGemaElement,
379// but not to XfemElement!
380//
381// Another assumed constraint (by GmpCellMeshData<Vector>::reorderCells()) is that already constructed cells can
382// be MOVED inside the cell vector by using memcpy(). This is ok for our cell classes, including cells with ghost
383// nodes. Derived classes MUST hold to this constraint.
384//
385// ---------------------------------------------------------------------------------------------------------------------------
386
387// Complete X with a set of common template parameters:
388// STD_TEMPLATE_PARS(GmpCell) expands to GmpCell<GmCell, GmLuaCell, GmpCellMeshData<GmSingleVector>, GM_BAR2, 2>
389#define STD_TEMPLATE_PARS(X) X<GmCell, GmLuaCell, GmpCellMeshData<GmSingleVector>, GM_BAR2, 2>
390
391static_assert(sizeof(GmCell) == sizeof(GmElement), "Unexpected cell base class size");
392static_assert(sizeof(GmCell) == sizeof(GmHElement), "Unexpected cell base class size");
393static_assert(sizeof(STD_TEMPLATE_PARS(GmpCell)) == sizeof(GmpCell <GmElement, GmLuaElement, GmpCellMeshData<GmSingleVector>, GM_BAR2, 2>), "Unexpected cell size");
394static_assert(sizeof(STD_TEMPLATE_PARS(GmpCell)) == sizeof(GmpCell <GmCell, GmLuaCell, GmpCellMeshData<GmSingleVector>, GM_HEX8, 8>), "Unexpected cell size");
395static_assert(sizeof(STD_TEMPLATE_PARS(GmpGhostCell)) == sizeof(GmpGhostCell<GmElement, GmLuaElement, GmpCellMeshData<GmSingleVector>, GM_BAR2, 2>), "Unexpected cell size");
396static_assert(sizeof(STD_TEMPLATE_PARS(GmpGhostCell)) == sizeof(GmpGhostCell<GmCell, GmLuaCell, GmpCellMeshData<GmSingleVector>, GM_HEX8, 8>), "Unexpected cell size");
398
399static_assert(sizeof(STD_TEMPLATE_PARS(GmpCell)) == 16, "Unexpected cell size value");
400static_assert(sizeof(STD_TEMPLATE_PARS(GmpGhostCell)) == 32, "Unexpected cell size value");
401
409template <template<class, class, class, GmCellType, int> class T, class Base, class Proxy, class CellMeshData>
410GmCell* GmpCellFactory(void* addr, int meshId, GmCellType type, int hindex, int id, int offset)
411{
412 Q_UNUSED(hindex);
413 assert(!GmCellGeometry(type).isHierarchical());
414 assert(hindex == -1);
415
416 // Make sure that T inherits from GmpCell or from GmpGhostCell
417 static_assert(std::is_base_of<STD_TEMPLATE_PARS(GmpGhostCell), STD_TEMPLATE_PARS(T)>::value ||
418 std::is_base_of<STD_TEMPLATE_PARS(GmpCell), STD_TEMPLATE_PARS(T)>::value,
419 "Expecting T to inherit from GmpCell or from GmpGhostCell");
420
421 // Make sure that Base has a size equal to GmCell or GmElement
422 static_assert(sizeof(Base) == sizeof(GmCell), "Unexpected cell base class size");
423
424#ifdef CREATE_CELL
425#error Create Cell macro already defined
426#endif
427
428 // Use placement new to call the cell constructor on the given address
429#define CREATE_CELL(type, nn) new (addr) T<Base, Proxy, CellMeshData, type, nn>(meshId, id, offset)
430
431 switch(type)
432 {
433 // The first macro parameter after the cell type is the number of nodes of that type.
434 case GM_BAR2: return CREATE_CELL(GM_BAR2, 2);
435 case GM_BAR3: return CREATE_CELL(GM_BAR3, 3);
436 case GM_BAR3D2: return CREATE_CELL(GM_BAR3D2, 2);
437 case GM_BAR3D3: return CREATE_CELL(GM_BAR3D3, 3);
438 case GM_QUAD4: return CREATE_CELL(GM_QUAD4, 4);
439 case GM_QUAD8: return CREATE_CELL(GM_QUAD8, 8);
440 case GM_QUAD9: return CREATE_CELL(GM_QUAD9, 9);
441 case GM_QUAD3D4: return CREATE_CELL(GM_QUAD3D4, 4);
442 case GM_QUAD3D8: return CREATE_CELL(GM_QUAD3D8, 8);
443 case GM_TRI3: return CREATE_CELL(GM_TRI3, 3);
444 case GM_TRI6: return CREATE_CELL(GM_TRI6, 6);
445 case GM_TRI3D3: return CREATE_CELL(GM_TRI3D3, 3);
446 case GM_TRI3D6: return CREATE_CELL(GM_TRI3D6, 6);
447 case GM_INT2DL4: return CREATE_CELL(GM_INT2DL4, 4);
448 case GM_INT2DL6: return CREATE_CELL(GM_INT2DL6, 6);
449 case GM_INT2DQ6: return CREATE_CELL(GM_INT2DQ6, 6);
450 //case GM_INT2DQ8: return CREATE_CELL(GM_INT2DQ8, 8);
451 case GM_HEX8: return CREATE_CELL(GM_HEX8, 8);
452 case GM_HEX20: return CREATE_CELL(GM_HEX20, 20);
453 case GM_HEX27: return CREATE_CELL(GM_HEX27, 27);
454 case GM_TET4: return CREATE_CELL(GM_TET4, 4);
455 case GM_TET10: return CREATE_CELL(GM_TET10, 10);
456 case GM_INT3DL8: return CREATE_CELL(GM_INT3DL8, 8);
457 case GM_INT3DL12: return CREATE_CELL(GM_INT3DL12, 12);
458 case GM_INT3DQ16: return CREATE_CELL(GM_INT3DQ16, 16);
459 //case GM_INT3DQ20: return CREATE_CELL(GM_INT3DQ20, 20);
460 case GM_INT3DL6: return CREATE_CELL(GM_INT3DL6, 6);
461 case GM_INT3DL9: return CREATE_CELL(GM_INT3DL9, 9);
462 case GM_INT3DQ12: return CREATE_CELL(GM_INT3DQ12, 12);
463 //case GM_INT3DQ15: return CREATE_CELL(GM_INT3DQ15, 15);
464 case GM_WEDGE6: return CREATE_CELL(GM_WEDGE6, 6);
465 case GM_WEDGE15: return CREATE_CELL(GM_WEDGE15, 15);
466 case GM_PYRA5: return CREATE_CELL(GM_PYRA5, 5);
467 case GM_PYRA13: return CREATE_CELL(GM_PYRA13, 13);
468 default:
469 assert(0);
470 }
471
472#undef CREATE_CELL
473 return NULL;
474}
475
477template <template<class, class, class, GmCellType, int> class T, class Base, class Proxy, class CellMeshData>
478int GmpCellSize()
479{
480 // Assumes that the size of a cell independs on its type or number of nodes
481 return sizeof(T<Base, Proxy, CellMeshData, GM_BAR2, 2>);
482}
483
485template <template<class, class, class, GmCellType, int> class T, class CellMeshData>
486GmCell* GmpHElementFactory(void* addr, int meshId, GmCellType type, int hindex, int id, int offset)
487{
488 assert(GmCellGeometry(type).isHierarchical());
489 assert(hindex >= 0 && hindex < GMP_GEMAMESH_MAX_HTYPES);
490
491#if GMP_GEMAMESH_MAX_HTYPES != 3
492#error Unexpected value for GMP_GEMAMESH_MAX_HTYPES
493#endif
494
495#ifdef CREATE_CELL
496#error Create Cell macro already defined
497#endif
498
499 // Use placement new to call the cell constructor on the given address
500#define CREATE_CELL(i, type, nn) new (addr) T<GmpHElementBase<i>, GmLuaHElement, CellMeshData, type, nn>(meshId, id, offset)
501
502 switch(type)
503 {
504 case GM_HQUADP: // Can someone find a better way for doing this? Please, pretty please...
505 if (hindex == 0) return CREATE_CELL(0, GM_HQUADP, 4);
506 else if(hindex == 1) return CREATE_CELL(1, GM_HQUADP, 4);
507 else if(hindex == 2) return CREATE_CELL(2, GM_HQUADP, 4);
508 else
509 assert(0);
510 case GM_DGQUAD:
511 if (hindex == 0) return CREATE_CELL(0, GM_DGQUAD, 4);
512 else if(hindex == 1) return CREATE_CELL(1, GM_DGQUAD, 4);
513 else if(hindex == 2) return CREATE_CELL(2, GM_DGQUAD, 4);
514 else
515 assert(0);
516 case GM_HHEXP:
517 if (hindex == 0) return CREATE_CELL(0, GM_HHEXP, 8);
518 else if(hindex == 1) return CREATE_CELL(1, GM_HHEXP, 8);
519 else if(hindex == 2) return CREATE_CELL(2, GM_HHEXP, 8);
520 else
521 assert(0);
522 case GM_DGHEX:
523 if (hindex == 0) return CREATE_CELL(0, GM_DGHEX, 8);
524 else if(hindex == 1) return CREATE_CELL(1, GM_DGHEX, 8);
525 else if(hindex == 2) return CREATE_CELL(2, GM_DGHEX, 8);
526 else
527 assert(0);
528 default:
529 assert(0);
530 }
531#undef CREATE_CELL
532
533 return NULL;
534}
535
537template <template<class, class, class, GmCellType, int> class T, class CellMeshData>
538int GmpHElementSize()
539{
540 // Assumes that the size of a cell independs on its hierarchical index, type or number of nodes
541 return sizeof(T<GmpHElementBase<0>, GmLuaHElement, CellMeshData, GM_HQUADP, 4>);
542}
543
544
545#endif
virtual void ghostNodesUpdated(int nghost, int ntotal)
virtual void activeCellUpdated(GmCellType type, bool active)=0
virtual int numNodes() const=0
static int clearGhostFlag(int nodeIndex)
static int setGhostFlag(int nodeIndex)
bool resize(ControlSize newSize, GmPODGrowT grow=Grow)
void remove(ControlSize index, ControlSize numValues)
ControlSize size() const
const T * data() const
bool append(const T &v)
Class for storing cell data, without ghost nodes support.
Definition gmpCell.h:132
GmpCell(int meshId, int cellId, int offset)
Constructs a cell given its id, associated mesh id and node offset in the mesh data structure.
Definition gmpCell.h:135
int offset() const
Returns the offset in the global mesh cell nodes vector for this cell. Not part of the GmCell API and...
Definition gmpCell.h:249
int _nodeOffset
Index in the mesh data for the first node for this cell.
Definition gmpCell.h:259
int _cellId
The cell index inside the mesh. MSB is used to control if the cell is active or not.
Definition gmpCell.h:258
CellMeshData * meshData() const
Returns the mesh data object associated with this cell's mesh.
Definition gmpCell.h:256
void replaceCellId(int id, bool keepActiveFlag)
Updates the cell id. For those who really know what they are doing. This function is a very specific ...
Definition gmpCell.h:237
void setOffset(int offset)
Updates the cell offset. Not part of the GmCell API and should NOT be marked as virtual.
Definition gmpCell.h:252
static GmpCellMeshDataBase * meshData(int meshId)
Returns the mesh data pointer associated with the given mesh id.
Definition gmpCellMeshData.h:94
static int hierarchicalPOrder(int index)
Returns the P order for hierarchical elements associated with the given index (returned by hierarchic...
Definition gmpCellMeshData.h:81
static int hierarchicalQOrder(int index)
Returns the Q order for hierarchical elements associated with the given index (returned by hierarchic...
Definition gmpCellMeshData.h:86
Auxiliar structure used to share data between GmpCellMesh and GmpMeshLoader. All fields are public si...
Definition gmpCellMeshData.h:121
Adds ghost node support to GmpCell.
Definition gmpCell.h:266
GmpGhostCell(int meshId, int cellId, int offset)
Constructs a cell given its id, associated mesh id and node offset in the mesh data structure.
Definition gmpCell.h:269
GmPODVector< int, uint32_t, GmPODVectorFastGrow< uint32_t > > _ghostList
List storing cell ghost nodes. Uses a GmPODVector with size control based on a 32 bits value giving a...
Definition gmpCell.h:344
void replaceGhostNodes(int *ghostNodes, int numNodes)
Replaces the full set of ghost nodes of the cell. Unlike setGhostNodes(), does NOT calls GmCellMesh::...
Definition gmpCell.h:322
An auxiliar class that can be used as the base class for GmpCell for Hierarchical elements....
Definition gmpCell.h:355
static void pushObject(lua_State *L, Base *obj)
GmCellType
GM_INT3DL12
GM_INT2DL4
GM_QUAD9
GM_QUAD4
GM_DGQUAD
GM_PYRA5
GM_INT3DL6
GM_BAR2
GM_HQUADP
GM_PYRA13
GM_BAR3D3
GM_HEX20
GM_WEDGE15
GM_INT3DQ16
GM_INT2DL6
GM_HEX27
GM_INT2DQ6
GM_WEDGE6
GM_INT3DQ12
GM_TET10
GM_TET4
GM_HHEXP
GM_BAR3
GM_QUAD3D4
GM_INT3DL8
GM_QUAD3D8
GM_TRI3
GM_HEX8
GM_DGHEX
GM_TRI3D3
GM_INT3DL9
GM_TRI3D6
GM_BAR3D2
GM_QUAD8
GM_TRI6
size_t GmPODVectorTightGrow(size_t s, size_t a)
Declaration of the GmpCellMeshData structure.
#define GMP_GEMAMESH_CELL_ID_BITS
The number of bits effectivelly used to encode the cell id inside a 32 bits integer,...
Definition gmpGemaMeshConfig.h:49
#define GMP_GEMAMESH_MAX_HTYPES
The maximum number of distinct hierarchical type orders that can be used simmultaneously....
Definition gmpGemaMeshConfig.h:63
#define GMP_GEMAMESH_MAX_NUM_MESHES
The maximum number of allowed meshes.
Definition gmpGemaMeshConfig.h:52
#define GMP_GEMAMESH_MAX_NUM_CELLS
The maximum number of allowed cells.
Definition gmpGemaMeshConfig.h:55