GemaMesh
The GeMA Mesh Plugin
gmpCellMeshBase.h
Go to the documentation of this file.
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_BASE_H_
25 #define _GEMA_PLUGIN_CELL_MESH_BASE_H_
26 
27 #include "gmpGemaMesh.h"
28 
29 #include "uibhmTopology.h"
30 #include "uibhmQuery.h"
31 
32 #include <gmPropertySet.h>
33 #include <assert.h>
34 
40 template <class BaseMesh, class NodeData, class CellData>
41 class GmpMeshBaseDataInterface : public BaseMesh
42 {
43 public:
44  static_assert(std::is_same<BaseMesh, GmCellMesh>::value || std::is_same<BaseMesh, GmElementMesh>::value,
45  "Unexpected base class");
46 
47  GmpMeshBaseDataInterface(GmSimulationData* simulation, QString id, QString description, const GmLogCategory& logger)
48  : BaseMesh(simulation, id, description, logger) {}
49 
50  virtual NodeData* theNodeData() { return NULL; }
51  virtual CellData* theCellData() { return NULL; }
52 };
53 
54 
65 template <class Mesh, class CoordAcc, class CoordGhostAcc, class Data, class CellData, template <class> class Vector>
66 class GmpCellMeshBase : public GmpMeshBase<Mesh, CoordAcc, CoordGhostAcc, Data, CellData, Vector>
67 {
68 public:
70  GmpCellMeshBase(GmSimulationData* simulation, QString id, QString description, const GmLogCategory& logger)
71  : GmpMeshBase<Mesh, CoordAcc, CoordGhostAcc, Data, CellData, Vector>(simulation, id, description, logger),
72  _cd(this)
73  {
74  _oldNumCells = -1;
75  }
76 
78  virtual ~GmpCellMeshBase()
79  {
80  clearCellAttributeSets();
81  }
82 
83  // Comments on the base class
84  virtual bool hasCapability(QString capabilityName) const
85  {
86  return (capabilityName == "addCells" || capabilityName == "editGroups" || capabilityName == "topology" ||
88  }
89 
90  // Comments on the base class
91  virtual int numCells() const { return _cd._numCells; }
92 
93  // Comments on the base class
94  virtual int numActiveCells() const { return _cd._numActiveCells; }
95 
96  // Comments on the base class
97  virtual const GmCell* cell(int cellIndex) const
98  {
99  assert(cellIndex >= 0 && cellIndex < numCells());
100  return _cd._cells[cellIndex];
101  }
102 
103  // Comments on the base class
104  virtual GmCell* cell(int cellIndex)
105  {
106  assert(cellIndex >= 0 && cellIndex < numCells());
107  return _cd._cells[cellIndex];
108  }
109 
110  // Comments on the base class
111  virtual const GmCellMeshTopology* topology(bool create = true) const
112  {
113  if(!_cd._topology && create)
114  {
115  // As commented in GmCellMesh, this function really should not be a const function since it
116  // can spawn the topological data structure build process, BUT it is kept as const since removing
117  // it causes multiple problems with interpolator classes and solving that would require multiple
118  // changes in almost all of them and potentially in their uses throughout the core libe and plugins,
119  // AND THAT would be a real PAIN... :(
121  MyType* self = const_cast<MyType*>(this);
122  if(!self->_cd.buildTopologyStructure(self))
123  gmErrorMsg(logger(), QObject::tr("Error creating the topological structure for mesh %1.").arg(id()));
124  }
125  assert((_cd._topology && _cd._topoQuery) || (!_cd._topology && !_cd._topoQuery));
126  return _cd._topoQuery;
127  }
128 
129  // Comments on the base class
130  virtual void clearTopology()
131  {
132  assert((_cd._topology && _cd._topoQuery) || (!_cd._topology && !_cd._topoQuery));
133  if(_cd._topology)
134  {
135  delete _cd._topology; _cd._topology = NULL;
136  delete _cd._topoQuery; _cd._topoQuery = NULL;
137  }
138  }
139 
140  // Comments on the base class
141  virtual const int* numCellTypes() const { return _cd._cellsByType; }
142 
143  // Comments on the base class
144  virtual const int* numActiveCellTypes() const { return _cd._activeCellsByType; }
145 
146  // Comments on the base class
147  virtual int maxNumCellNodes() const { return _cd._maxNumNodes; }
148 
149  // Comments on the base class
150  virtual int maxNumCellGhostNodes() const { return _cd._maxNumGhostNodes; }
151 
152  // Comments on the base class
153  virtual int maxTotalNumCellNodes() const { return _cd._maxTotalNumNodes; }
154 
155  // Comments on the base class
156  virtual void ghostNodesUpdated(int nghost, int ntotal)
157  {
158  if(nghost > _cd._maxNumGhostNodes)
159  _cd._maxNumGhostNodes = nghost;
160  if(ntotal > _cd._maxTotalNumNodes)
161  _cd._maxTotalNumNodes = ntotal;
162  }
163 
164  // Comments on the base class
165  virtual void activeCellUpdated(GmCellType type, bool active)
166  {
167  int o = active ? 1 : -1;
168  _cd._numActiveCells += o;
169  _cd._activeCellsByType[type] += o;
170  }
171 
172  // Comments on the base class
173  virtual QStringList cellGroupIds() const { return _cd._cellGroupIds; }
174 
175  // Comments on the base class
176  virtual int numCellsInGroup(int groupIndex) const
177  {
178  return _cd._numCellsInGroup.at(groupIndex);
179  }
180 
181  // Comments on the base class
182  virtual const GmCell* cellInGroup(int groupIndex, int cellIndex) const
183  {
184  assert(cellIndex >= 0 && cellIndex < numCellsInGroup(groupIndex));
185  return cell(_cd._cellGroupCells.at(groupIndex)[cellIndex]);
186  }
187 
188  // Comments on the base class
189  virtual GmCell* cellInGroup(int groupIndex, int cellIndex)
190  {
191  assert(cellIndex >= 0 && cellIndex < numCellsInGroup(groupIndex));
192  return cell(_cd._cellGroupCells.at(groupIndex)[cellIndex]);
193  }
194 
195  // Comments on the base class
196  virtual int addCellGroup(QString groupName) { return _cd.addCellGroup(groupName); }
197 
198  // Comments on the base class
199  virtual bool addCellsToGroup(int groupId, const QVector<int>& cellIds) { return _cd.addCellsToGroup(groupId, cellIds); }
200 
201  // Comments on the base class
202  virtual bool addCellsToGroup(int groupId, const QVector<QPair<int, int>>& cellIds) { return _cd.addCellsToGroup(groupId, cellIds); }
203 
204  // Comments on the base class
205  virtual const QMap<QString, GmCellBoundary*>& cellBoundaryGroups() const { return _cd._boundaryGroups; }
206 
207  // Comments on the base class
208  virtual const QList<GmPropertySet*>& propertySets() const { return _cd._propertySets; }
209 
210  // Comments on the base class
211  virtual int propertySetIndex(QString id) const
212  {
213  for(int i = 0, size = _cd._propertySets.size(); i<size; i++)
214  {
215  GmPropertySet* ps = _cd._propertySets.at(i);
216  assert(ps);
217  if(ps->propertyInfo(id))
218  return i;
219  }
220  return -1;
221  }
222 
223  // Comments on the base class
224  virtual int addCells(int* numCellTypes)
225  {
226  if(_cd._singleCellType)
227  {
228  // Lets make sure that the request only includes the actual cell type
229  int type = -1;
230  for(int i = 0; i<GM_NUM_CELL_TYPES; i++)
231  {
232  if(numCellTypes[i])
233  {
234  if(type != -1)
235  {
236  gmErrorMsg(logger(), QObject::tr("Error trying to add multiple cell types to a single cell type mesh."));
237  return -1;
238  }
239  type = i;
240  }
241  }
242  if(type >= 0 && _cd._cellsByType[type] != _cd._numCells)
243  {
244  gmErrorMsg(logger(), QObject::tr("Cell type mismatch while adding cells to a single cell type mesh."));
245  return -1;
246  }
247  }
248 
249  if(_oldNumCells == -1)
250  _oldNumCells = numCells();
251  clearCellStatistics();
252  return _cd.addCells(this, numCellTypes, cellAllocator(this->_nd.ghostEnabled(), _cd.hierarchicalElements()));
253  }
254 
255  // Comments on the base class
256  virtual QList<int> addedCells() const
257  {
258  if(_oldNumCells == -1)
259  return QList<int>();
260 
261  QList<int> addedList;
262  for(int i = 0, n = numCells() - _oldNumCells; i<n; i++)
263  addedList.append(_oldNumCells + i);
264  return addedList;
265  }
266 
267  // Comments on the base class
268  virtual void clearAddedCells() { _oldNumCells = -1; }
269 
270  // Comments on the base class
271  virtual void emitMeshChanged()
272  {
273  if(_cd._topology)
274  {
275  if(!_cd._topology->addNewCells())
276  {
277  clearTopology();
278  gmWarnMsg(logger(), QObject::tr("Error updating the topological structure. The structure was removed."));
279  }
280  }
281  emit meshChanged();
282  }
283 
284  // Comments on the base class
285  virtual void clear()
286  {
288  _cd.clear(this);
289  clearAddedCells();
290  clearCellStatistics();
291  }
292 
293  // Comments on the base class
294  virtual CellData* cellData() { return &_cd; }
295 
296  // Comments on the base class
297  virtual size_t cellMemory() const { return _cd.cellMemory(); }
298 
299  // Comments on the base class
300  virtual size_t cellGroupsMemory() const { return _cd.cellGroupsMemory(); }
301 
302  // Comments on the base class
303  virtual size_t cellBoundariesMemory() const { return _cd.cellBoundariesMemory(); }
304 
305 protected:
306  //---------------------------------------
307  // State dump control functions
308  //---------------------------------------
309 
310  // See comments on the base GmMesh class
311  virtual bool addStateGeometryData(GmStateDump* state, int groupId)
312  {
314  return false;
315  return _cd.addStateGeometryData(simulationData(), this,
316  cellAllocator(this->_nd.ghostEnabled(), _cd.hierarchicalElements()),
317  state, groupId);
318  }
319 
320  // See comments on the base GmMesh class
321  virtual bool fillDumpControlMapData(QVariantMap* map, const GmLogCategory& logger)
322  {
324  return false;
325  map->insert("CellMeshBase_oldNumCells", _oldNumCells);
326  return _cd.fillDumpControlMapData(this, map, logger);
327  }
328 
329  // See comments on the base GmMesh class
330  virtual bool dumpControlMapDataLoaded(QVariantMap* map, const GmLogCategory& logger)
331  {
333  return false;
334  _oldNumCells = (*map)["CellMeshBase_oldNumCells"].toInt();
335  return _cd.dumpControlMapDataLoaded(this, map, logger);
336  }
337 
338  CellData _cd;
340 };
341 
342 #endif
Data _nd
The complete node data.
Definition: gmpMeshBase.h:262
virtual GmpMeshLoaderCellAllocator cellAllocator(bool ghostSupport, bool hSupport) const
Virtual function that should be overriden for derived classes that need to load cells....
Definition: gmpMeshBase.h:232
GM_NUM_CELL_TYPES
Declaration of the UibhmTopology familiy of classes.
GmpCellMeshBase(GmSimulationData *simulation, QString id, QString description, const GmLogCategory &logger)
Constructor. Will be called by the plugin loading code.
Definition: gmpCellMeshBase.h:70
QString tr(const char *sourceText, const char *disambiguation, int n)
virtual ~GmpCellMeshBase()
Destructor.
Definition: gmpCellMeshBase.h:78
Declaration of the UibhmQuery familiy of classes.
virtual GmValueInfo * propertyInfo(QString propertyId) const=0
void append(const T &value)
virtual CellData * cellData()
Virtual function that should be overriden for derived classes that need to load cells.
Definition: gmpCellMeshBase.h:294
Declaration of the GmpGemaMesh class.
Basic class for implementing a mesh with support for cells.
Definition: gmpCellMeshBase.h:66
CellData _cd
The complete cell data.
Definition: gmpCellMeshBase.h:338
GmCellType
Basic class for a plugin mesh. Implements the needed functions for a GmMesh interface,...
Definition: gmpMeshBase.h:68
An auxiliary class that can be used as a base class for GmpMeshBase so that a GmCellMesh instance can...
Definition: gmpCellMeshBase.h:41
int _oldNumCells
The old number of cells that the mesh had before calls to addCells()
Definition: gmpCellMeshBase.h:339
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const