GemaMesh
The GeMA Mesh Plugin
Loading...
Searching...
No Matches
gmpCellMesh.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_MESH_H_
25#define _GEMA_PLUGIN_CELL_MESH_H_
26
27#include "gmpNodeMesh.h"
28#include "gmpCellDataDump.h"
29#include "gmpCell.h"
30
31#include "uibhmTopology.h"
32#include "uibhmQuery.h"
33
34#include <gmElementMesh.h>
35#include <gmElement.h>
36#include <gmLuaCell.h>
37
38#include <assert.h>
39
40
51template <class Mesh, template <class> class Vector>
52class GmpCellMeshBase : public GmpNodeMesh<Mesh, Vector>
53{
54public:
56 GmpCellMeshBase(GmSimulationData* simulation, QString id, QString description, const GmLogCategory& logger)
57 : GmpNodeMesh<Mesh, Vector>(simulation, id, description, logger), _cd(this)
58 {
59 _oldNumCells = -1;
60 }
61
64 {
65 clearCellValueSets();
66 }
67
68 // Comments on the base class
69 virtual bool hasCapability(QString capabilityName) const
70 {
71 return (capabilityName == "addCells" || capabilityName == "editGroups" || capabilityName == "topology" ||
73 }
74
75 // Comments on the base class
76 virtual int numCells() const { return _cd._numCells; }
77
78 // Comments on the base class
79 virtual int numActiveCells() const { return _cd._numActiveCells; }
80
81 // Comments on the base class
82 virtual const GmCell* cell(int cellIndex) const
83 {
84 assert(cellIndex >= 0 && cellIndex < numCells());
85 return _cd.cell(cellIndex);
86 }
87
88 // Comments on the base class
89 virtual GmCell* cell(int cellIndex)
90 {
91 assert(cellIndex >= 0 && cellIndex < numCells());
92 return _cd.cell(cellIndex);
93 }
94
95 // Comments on the base class
96 virtual const GmCellMeshTopology* topology(bool create = true) const
97 {
98 if(!_cd._topology && create)
99 {
101
102 // As commented in GmCellMesh, this function really should not be a const function since it
103 // can spawn the topological data structure build process, BUT it is kept as const since removing
104 // it causes multiple problems with interpolator classes and solving that would require multiple
105 // changes in almost all of them and potentially in their uses throughout the core lib and plugins,
106 // AND THAT would be a real PAIN... :(
108 self->_cd.buildTopologyStructure(this, &self->_nd, simulationData(), logger());
109 }
110 return _cd._topoQuery;
111 }
112
113 // Comments on the base class
114 virtual void clearTopology() { _cd.clearTopology(); }
115
116 // Comments on the base class
117 virtual bool hasSolidElements() const { return _cd._hasSolidElements; }
118
119 // Comments on the base class
120 virtual const int* numCellTypes() const { return _cd._cellsByType; }
121
122 // Comments on the base class
123 virtual const int* numActiveCellTypes() const { return _cd._activeCellsByType; }
124
125 // Comments on the base class
126 virtual int maxNumCellNodes() const { return _cd._maxNumNodes; }
127
128 // Comments on the base class
129 virtual int maxNumCellGhostNodes() const { return _cd._maxNumGhostNodes; }
130
131 // Comments on the base class
132 virtual int maxTotalNumCellNodes() const { return _cd._maxTotalNumNodes; }
133
134 // Comments on the base class
135 virtual void ghostNodesUpdated(int nghost, int ntotal)
136 {
137 if(nghost > _cd._maxNumGhostNodes)
138 _cd._maxNumGhostNodes = nghost;
139 if(ntotal > _cd._maxTotalNumNodes)
140 _cd._maxTotalNumNodes = ntotal;
141 }
142
143 // Comments on the base class
144 virtual void activeCellUpdated(GmCellType type, bool active)
145 {
146 int o = active ? 1 : -1;
147 _cd._numActiveCells += o;
148 _cd._activeCellsByType[type] += o;
149 }
150
151 // Comments on the base class
152 virtual QStringList cellGroupIds() const { return _cd._cellGroupIds; }
153
154 // Comments on the base class
155 virtual int numCellsInGroup(int groupIndex) const
156 {
157 return _cd._numCellsInGroup.at(groupIndex);
158 }
159
160 // Comments on the base class
161 virtual const GmCell* cellInGroup(int groupIndex, int cellIndex) const
162 {
163 assert(cellIndex >= 0 && cellIndex < numCellsInGroup(groupIndex));
164 return cell(_cd._cellGroupCells.at(groupIndex)[cellIndex]);
165 }
166
167 // Comments on the base class
168 virtual GmCell* cellInGroup(int groupIndex, int cellIndex)
169 {
170 assert(cellIndex >= 0 && cellIndex < numCellsInGroup(groupIndex));
171 return cell(_cd._cellGroupCells.at(groupIndex)[cellIndex]);
172 }
173
174 // Comments on the base class
175 virtual int addCellGroup(QString groupName) { return _cd.addCellGroup(groupName); }
176
177 // Comments on the base class
178 virtual bool addCellsToGroup(int groupId, const QVector<int>& cellIds) { return _cd.addCellsToGroup(groupId, cellIds); }
179
180 // Comments on the base class
181 virtual bool addCellsToGroup(int groupId, const QVector<QPair<int, int>>& cellIds) { return _cd.addCellsToGroup(groupId, cellIds); }
182
183 // Comments on the base class
184 virtual const QMap<QString, GmCellBoundary*>& cellBoundaryGroups() const { return _cd._boundaryGroups; }
185
186 // Comments on the base class
187 virtual const QList<GmPropertySet*>& propertySets() const { return _cd._propertySets; }
188
189 // Comments on the base class
190 virtual int propertySetIndex(QString id) const
191 {
192 for(int i = 0, size = _cd._propertySets.size(); i<size; i++)
193 {
194 GmPropertySet* ps = _cd._propertySets.at(i);
195 assert(ps);
196 if(ps->propertyInfo(id))
197 return i;
198 }
199 return -1;
200 }
201
202 // Comments on the base class
203 virtual int addCells(int* numCellTypes)
204 {
205 if(_oldNumCells == -1)
206 _oldNumCells = numCells();
207 clearCellStatistics();
208
209 // Add cells, also updating associated value sets and the PCR object. Makes
210 // consistency checks to verify if the added types are compatible with the
211 // mesh, including _singleCellType checks. If not, logs a message with the
212 // provided logger.
213 return _cd.addCells(this, numCellTypes, true, true, _pcr, logger());
214 }
215
216 // Comments on the base class
217 virtual QList<int> addedCells() const
218 {
219 if(_oldNumCells == -1)
220 return QList<int>();
221
222 QList<int> addedList;
223 for(int i = 0, n = numCells() - _oldNumCells; i<n; i++)
224 addedList.append(_oldNumCells + i);
225 return addedList;
226 }
227
228 // Comments on the base class
229 virtual void clearAddedCells() { _oldNumCells = -1; }
230
231 // Comments on the base class
232 virtual void emitMeshChanged()
233 {
234 if(!_cd.topologyMeshChanged())
235 gmWarnMsg(logger(), QObject::tr("Error updating the topological structure. The structure was removed."));
236 emit meshChanged();
237 }
238
239 // Comments on the base class
240 virtual void clear()
241 {
243 _cd.clear(this);
244 clearAddedCells();
245 clearCellStatistics();
246 }
247
248 // Comments on the base class
249 virtual GmpCellMeshData<Vector>* cellData() { return &_cd; }
250
251 // Comments on the base class
252 virtual size_t cellMemory() const { return _cd.cellMemory(); }
253
254 // Comments on the base class
255 virtual size_t cellGroupsMemory() const { return _cd.cellGroupsMemory(); }
256
257 // Comments on the base class
258 virtual size_t cellBoundariesMemory() const { return _cd.cellBoundariesMemory(); }
259
260protected:
261
265 virtual GmpCellMeshData<Vector>* initCellData(LuaTable& table, bool* ghostSupport, bool* ok)
266 {
267 *ok = false;
268
269 bool hSupport = false;
270
271 if(pluginType() == QString("elem") || pluginType() == QString("elemd"))
272 {
273 LuaTable horderTable = table.getField("hOrder").value<LuaTable>();
274 if(horderTable.isValid())
275 {
276 int p = horderTable.getField("P").toInt(); // Mesh script checks that if hOrder exists it contains fields P and Q
277 int q = horderTable.getField("Q").toInt();
278
279 if(p < 1 || p > GM_MAX_ORTHOGONAL_POL_ORDER || q < 1 || q > GM_MAX_ORTHOGONAL_POL_ORDER)
280 {
281 gmErrorMsg(logger(), QObject::tr("Error loading mesh hierarchical order. Invalid values for P and/or Q.\n"
282 "Maximum supported polynomial order is %1").arg(GM_MAX_ORTHOGONAL_POL_ORDER));
283 return NULL;
284 }
285
286 if(!_cd.setHierarchicalIndex(p, q))
287 {
288 gmErrorMsg(logger(), QObject::tr("Error loading mesh hierarchical order.\n"
289 "A model can only have %1 different sets of hierarchical orders.")
291 return NULL;
292 }
293
294 hSupport = true;
295 *ghostSupport = true; // Using hierarchical elements implies in supporting ghost nodes
296 }
297 }
298
299 // Setup cell size and allocator
300 _cd._cellAllocator = cellAllocator(*ghostSupport, hSupport);
301 _cd._cellSize = cellSize(*ghostSupport, hSupport);
302 assert(_cd._cellSize > 0);
303
304 *ok = true;
305 return &_cd;
306 }
307
308 //---------------------------------------
309 // Cell allocation and size control functions. Must be reimplemented by derived classes.
310 //---------------------------------------
311
318 virtual GmpCellAllocator cellAllocator(bool ghostSupport, bool hSupport) const = 0;
319
323 virtual int cellSize(bool ghostSupport, bool hSupport) const = 0;
324
325
326 //---------------------------------------
327 // State dump control functions
328 //---------------------------------------
329
330 // See comments on the base GmMesh class
331 virtual bool addStateGeometryData(GmStateDump* state, int groupId)
332 {
334 return false;
335 return _cd._dumper->addStateGeometryData(simulationData(), this, state, groupId);
336 }
337
338 // See comments on the base GmMesh class
339 virtual bool fillDumpControlMapData(QVariantMap* map, const GmLogCategory& logger)
340 {
342 return false;
343 map->insert("CellMeshBase_oldNumCells", _oldNumCells);
344 return _cd._dumper->fillDumpControlMapData(this, map, logger);
345 }
346
347 // See comments on the base GmMesh class
348 virtual bool dumpControlMapDataLoaded(QVariantMap* map, const GmLogCategory& logger)
349 {
351 return false;
352 _oldNumCells = (*map)["CellMeshBase_oldNumCells"].toInt();
353 return _cd._dumper->dumpControlMapDataLoaded(this, map, logger);
354 }
355
358};
359
360
362template <template <class> class Vector>
363class GMP_GEMAMESH_API_EXPORT GmpCellMesh : public GmpCellMeshBase<GmCellMesh, Vector>
364{
365public:
367 GmpCellMesh(GmSimulationData* simulation, QString id, QString description, const GmLogCategory& logger)
368 : GmpCellMeshBase<GmCellMesh, Vector>(simulation, id, description, logger) {}
369
370 // Comments on the base class
371 virtual const char* pluginType() const { if constexpr(std::is_same<Vector<int>, GmSingleVector<int>>::value) return "cell"; else return "celld"; }
372
373 // Comments on the base class
374 virtual void pushProxy(lua_State* L, const GmLogCategory& logger) { LuaProxy::pushObject(L, new GmLuaCellMesh(this, logger)); }
375
376protected:
378 virtual GmpCellAllocator cellAllocator(bool ghostSupport, bool hSupport) const
379 {
380 Q_UNUSED(hSupport);
381 assert(!hSupport); // A cell mesh does not support hierarchical elements!
382
383 return ghostSupport ? GmpCellFactory<GmpGhostCell, GmCell, GmLuaCell, GmpCellMeshData<Vector>> :
384 GmpCellFactory<GmpCell, GmCell, GmLuaCell, GmpCellMeshData<Vector>>;
385 }
386
388 virtual int cellSize(bool ghostSupport, bool hSupport) const
389 {
390 Q_UNUSED(hSupport);
391 assert(!hSupport); // A cell mesh does not support hierarchical elements!
392
393 return ghostSupport ? GmpCellSize<GmpGhostCell, GmCell, GmLuaCell, GmpCellMeshData<Vector>>() :
394 GmpCellSize<GmpCell, GmCell, GmLuaCell, GmpCellMeshData<Vector>>();
395 }
396
397 // See comments on the base class and on the enum definition
398 virtual int controlMapStateItemType() { return GMP_GEMA_CMESH_DUMP_ITEM; }
399};
400
402template <template <class> class Vector>
403class GMP_GEMAMESH_API_EXPORT GmpElementMesh: public GmpCellMeshBase<GmElementMesh, Vector>
404{
405public:
407 GmpElementMesh(GmSimulationData* simulation, QString id, QString description, const GmLogCategory& logger)
408 : GmpCellMeshBase<GmElementMesh, Vector>(simulation, id, description, logger) {}
409
410 // Comments on the base class
411 virtual const char* pluginType() const { if constexpr(std::is_same<Vector<int>, GmSingleVector<int>>::value) return "elem"; else return "elemd"; }
412
413 // Comments on the base class
414 virtual void pushProxy(lua_State* L, const GmLogCategory& logger) { LuaProxy::pushObject(L, new GmLuaElementMesh(this, logger)); }
415
416 // Comments on the base class
417 virtual int hPOrder() const { return GmpCellMeshData<Vector>::hierarchicalPOrder(_cd._hierarchicalIndex); }
418
419 // Comments on the base class
420 virtual int hQOrder() const { return GmpCellMeshData<Vector>::hierarchicalQOrder(_cd._hierarchicalIndex); }
421
422protected:
424 virtual GmpCellAllocator cellAllocator(bool ghostSupport, bool hSupport) const
425 {
426 if(hSupport)
427 {
428 assert(ghostSupport); // There is no point in having hierarchical elements without ghost support
429 return GmpHElementFactory<GmpGhostCell, GmpCellMeshData<Vector>>;
430 }
431 else
432 {
433 return ghostSupport ? GmpCellFactory<GmpGhostCell, GmElement, GmLuaElement, GmpCellMeshData<Vector>> :
434 GmpCellFactory<GmpCell, GmElement, GmLuaElement, GmpCellMeshData<Vector>>;
435 }
436 }
437
439 virtual int cellSize(bool ghostSupport, bool hSupport) const
440 {
441 if(hSupport)
442 {
443 assert(ghostSupport); // There is no point in having hierarchical elements without ghost support
444 return GmpHElementSize<GmpGhostCell, GmpCellMeshData<Vector>>();
445 }
446 else
447 {
448 return ghostSupport ? GmpCellSize<GmpGhostCell, GmElement, GmLuaElement, GmpCellMeshData<Vector>>() :
449 GmpCellSize<GmpCell, GmElement, GmLuaElement, GmpCellMeshData<Vector>>();
450 }
451 }
452
453 // See comments on the base class and on the enum definition
454 virtual int controlMapStateItemType()
455 {
456 return _cd.hierarchicalElements() ? GMP_GEMA_HMESH_DUMP_ITEM : GMP_GEMA_EMESH_DUMP_ITEM;
457 }
458};
459
460
461#endif
virtual GmValueInfo * propertyInfo(QString propertyId) const=0
static bool inMainThread()
Basic class for implementing a mesh with support for cells.
Definition gmpCellMesh.h:53
GmpCellMeshBase(GmSimulationData *simulation, QString id, QString description, const GmLogCategory &logger)
Constructor. Will be called by the plugin loading code.
Definition gmpCellMesh.h:56
virtual int cellSize(bool ghostSupport, bool hSupport) const =0
Virtual function that should be overridden by derived classes to specify the concrete "sizeof" of the...
virtual GmpCellAllocator cellAllocator(bool ghostSupport, bool hSupport) const =0
Virtual function that should be overridden by derived classes. The ghostSupport parameter defines if ...
virtual GmpCellMeshData< Vector > * initCellData(LuaTable &table, bool *ghostSupport, bool *ok)
Method called by gmpNodeMesh::loadPrivateData() to initialize the cell data object....
Definition gmpCellMesh.h:265
GmpCellMeshData< Vector > _cd
The complete cell data.
Definition gmpCellMesh.h:356
virtual ~GmpCellMeshBase()
Destructor.
Definition gmpCellMesh.h:63
int _oldNumCells
The old number of cells that the mesh had before calls to addCells()
Definition gmpCellMesh.h:357
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
size_t cellMemory() const
Returns the approximate memory used for storing mesh cells.
Definition gmpCellMeshData.cpp:822
A mesh that supports cell data, parameterized by the vector type (either GmSingleVector or GmDualVect...
Definition gmpCellMesh.h:364
virtual int cellSize(bool ghostSupport, bool hSupport) const
Returns the size of a cell object.
Definition gmpCellMesh.h:388
virtual GmpCellAllocator cellAllocator(bool ghostSupport, bool hSupport) const
Returns the function responsible for allocating and initializing a new cell.
Definition gmpCellMesh.h:378
GmpCellMesh(GmSimulationData *simulation, QString id, QString description, const GmLogCategory &logger)
Constructor. Will be called by the plugin loading code.
Definition gmpCellMesh.h:367
A mesh that supports Element data, parameterized by the vector type (either GmSingleVector or GmDualV...
Definition gmpCellMesh.h:404
virtual int cellSize(bool ghostSupport, bool hSupport) const
Returns the size of a cell object.
Definition gmpCellMesh.h:439
virtual GmpCellAllocator cellAllocator(bool ghostSupport, bool hSupport) const
Returns the function responsible for allocating and initializing a new element.
Definition gmpCellMesh.h:424
GmpElementMesh(GmSimulationData *simulation, QString id, QString description, const GmLogCategory &logger)
Constructor. Will be called by the plugin loading code.
Definition gmpCellMesh.h:407
Basic class for a plugin mesh. Implements the needed functions for a GmMesh interface,...
Definition gmpNodeMesh.h:71
GmPCR * _pcr
PCR object. Not stored inside _nd since that class does not have access to the model data for correct...
Definition gmpNodeMesh.h:248
GmpNodeMeshData< Vector > _nd
The complete node data.
Definition gmpNodeMesh.h:246
bool isValid() const
static void pushObject(lua_State *L, Base *obj)
QVariant getField(const char *name, LuaEnv::StackOption opt=LuaEnv::STACK_AUTO)
GmCellType
#define GM_MAX_ORTHOGONAL_POL_ORDER
GmCell *(* GmpCellAllocator)(void *addr, int meshId, GmCellType type, int hindex, int id, int offset)
Typedef for a function that can construct a single cell of the given type, placing it at the provided...
Definition gmpCellAllocator.h:36
Implementation of the GmpCellDataDump class.
@ GMP_GEMA_CMESH_DUMP_ITEM
Cell mesh dump type.
Definition gmpDataDump.h:35
@ GMP_GEMA_EMESH_DUMP_ITEM
Element mesh dump type.
Definition gmpDataDump.h:36
@ GMP_GEMA_HMESH_DUMP_ITEM
Element mesh with hierarchical elements dump type.
Definition gmpDataDump.h:37
#define GMP_GEMAMESH_MAX_HTYPES
The maximum number of distinct hierarchical type orders that can be used simmultaneously....
Definition gmpGemaMeshConfig.h:63
Declaration of the GmpNodeMesh class.
void append(const T &value)
const T & at(int i) const const
QString tr(const char *sourceText, const char *disambiguation, int n)
int toInt(bool *ok) const const
T value() const const
Declaration of the UibhmQuery familiy of classes.
Declaration of the UibhmTopology familiy of classes.