GemaMesh
The GeMA Mesh Plugin
gmpMeshBase.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_MESH_BASE_H_
25 #define _GEMA_PLUGIN_MESH_BASE_H_
26 
27 #include <gmGhostNodeAccessor.h>
28 #include <gmLuaMesh.h>
29 #include <gmShapeOrthogonalPol.h>
30 
31 #include "gmpMeshLoader.h"
32 
33 #include <unitConverter.h>
34 #include <luaTable.h>
35 #include <luaStackBalancer.h>
36 
37 #include <assert.h>
38 
39 #define GEMA_MESH_PLUGIN_DUMP_CODE 0x00AB0000
40 
43 {
44  GMP_GEMA_MESH_DUMP_ITEM = GM_MESH_DUMP_ITEM | GEMA_MESH_PLUGIN_DUMP_CODE | 1,
45  GMP_GEMA_CMESH_DUMP_ITEM = GM_MESH_DUMP_ITEM | GEMA_MESH_PLUGIN_DUMP_CODE | 2,
46  GMP_GEMA_EMESH_DUMP_ITEM = GM_MESH_DUMP_ITEM | GEMA_MESH_PLUGIN_DUMP_CODE | 3,
47  GMP_GEMA_HMESH_DUMP_ITEM = GM_MESH_DUMP_ITEM | GEMA_MESH_PLUGIN_DUMP_CODE | 4,
48 };
49 
66 template <class Mesh, class CoordAcc, class CoordGhostAcc,
67  class Data, class CellData, template <class> class Vector>
68 class GmpMeshBase: public Mesh
69 {
70 public:
72  GmpMeshBase(GmSimulationData* simulation, QString id, QString description, const GmLogCategory& logger)
73  : Mesh(simulation, id, description, logger), _nd(this)
74  {
75  }
76 
78  virtual ~GmpMeshBase()
79  {
80  clearNodeValueSets();
81  }
82 
83  // Comments on the base class
84  virtual const char* pluginName() const { return "GemaMesh"; }
85 
86  // Comments on the base class
87  virtual const char* pluginType() const { if constexpr(std::is_same<Vector<int>, GmSingleVector<int>>::value) return "nodes"; else return "nodesd"; }
88 
89  // Comments on the base class
90  virtual bool hasCapability(QString capabilityName) const
91  {
92  // This implementation has a caveat: If this function is called before loadPrivateData() is called
93  // on the mesh, it will return no support for ghost nodes, regardless of mesh configuration.
94  // This should not be a problem since it can not happend in a normal control flow.
95  return (capabilityName == "addNodes" ||
96  capabilityName == "clear" ||
97  capabilityName == "stateDump" ||
98  (capabilityName == "ghostNodes" && _nd._ghostEnabled));
99  }
100 
101  // Comments on the base class
102  virtual void pushProxy(lua_State* L, const GmLogCategory& logger) { LuaProxy::pushObject(L, new GmLuaMesh(this, logger)); }
103 
108  virtual bool loadPrivateData(LuaTable& table)
109  {
110 #ifdef TRACK_MESHLOAD_TIME
111  GmTimeMsg tmsg(logger(), QObject::tr(" *** Mesh load"));
112 #endif
113 
114  // Inform the mesh data object about the number of mesh coordinates
115  // This is used by the surface mesh plugin to instance the correct mesh object
116  // On the current implementation, MUST be called BEFORE the call to cellData()
117  LuaStackBalancer bal(table.env());
118  if(!_nd.setCoordinateDimension(table.getField("coordinateDim").toInt()))
119  {
120  gmErrorMsg(logger(), QObject::tr("Error loading mesh. Unsuported coordinate dimension."));
121  return false;
122  }
123 
124  // Check if the mesh should support ghost nodes or not. This parameter is read here since
125  // this information is needed in the call to cellAllocator()
126  _nd.setGhostEnabled(table.getField("useGhostNodes").toBool());
127  CellData* cd = cellData();
128  if(cd)
129  cd->setGhostEnabled(_nd.ghostEnabled());
130 
131  // We also need to check if the mesh contains hierarchical elements or not. This is done by
132  // looking for the "hOrder" table and its contents, also before calling cellAllocator()
133  if(cd && (pluginType() == QString("elem") || pluginType() == QString("elemd")))
134  {
135  LuaTable horderTable = table.getField("hOrder").value<LuaTable>();
136  if(horderTable.isValid())
137  {
138  int p = horderTable.getField("P").toInt(); // Mesh script checks that if hOrder exists it contains fields P and Q
139  int q = horderTable.getField("Q").toInt();
140 
141  if(p < 1 || p > GM_MAX_ORTHOGONAL_POL_ORDER || q < 1 || q > GM_MAX_ORTHOGONAL_POL_ORDER)
142  {
143  gmErrorMsg(logger(), QObject::tr("Error loading mesh hierarchical order. Invalid values for P and/or Q.\n"
144  "Maximum supported polynomial order is %1").arg(GM_MAX_ORTHOGONAL_POL_ORDER));
145  return false;
146  }
147 
148  int pqIndex = CellData::hierarchicalOrderIndex(p, q);
149  if(pqIndex == -1)
150  {
151  gmErrorMsg(logger(), QObject::tr("Error loading mesh hierarchical order.\n"
152  "A model can only have %1 different sets of hierarchical orders.")
153  .arg(CellData::maxHTypes));
154  return false;
155  }
156  cd->_hierarchicalIndex = pqIndex;
157  _nd.setGhostEnabled(true); // Using hierarchical elements implies in supporting ghost nodes
158  cd->setGhostEnabled(true);
159  }
160  }
161 
162  // Load mesh data
163  GmpMeshLoader<Vector>* loader = meshLoader();
164  bool ret = loader->loadMeshData(table, this, (GmpMeshData<Vector>*)&_nd, (GmpCellMeshData<Vector>*)cd, cellAllocator(_nd._ghostEnabled, cd && cd->hierarchicalElements()));
165  delete loader;
166  return ret;
167  }
168 
169  // Comments on the base class
170  virtual GmValueInfo* nodeCoordInfo() const { return _nd._coordInfo; }
171 
172  // Comments on the base class
173  virtual GmValueAccessor* nodeCoordAccessor(Unit desiredUnit, const GmLogCategory& logger) const
174  {
175  bool compatibleUnits;
176  UnitConverter* conv = Unit::converter(_nd._coordInfo->unit(), desiredUnit, &compatibleUnits);
177  if(!compatibleUnits) // Conv can be NULL with compatible units if no conversion is needed
178  {
179  gmInfoMsg(logger, QObject::tr("Could not create an accessor for mesh coordinates due to incompatible units.\n"
180  "Data unit = '%1'. Requested unit = '%2'.")
181  .arg(_nd._coordInfo->unit().name(), desiredUnit.name()));
182  return NULL;
183  }
184 
185  if(_nd._ghostEnabled)
186  {
187  UnitConverter* gconv = Unit::converter(_nd._coordInfo->unit(), desiredUnit, &compatibleUnits); // Accessors own converters so no sharing is possible
188 
189  GmValueAccessor* ac = new CoordAcc (const_cast<Data&>(_nd), logger, conv, desiredUnit.name());
190  GmValueAccessor* gac = new CoordGhostAcc(const_cast<Data&>(_nd), logger, gconv, desiredUnit.name());
191 
192  return new GmGhostNodeAccessor(ac, gac);
193  }
194  else
195  return new CoordAcc(const_cast<Data&>(_nd), logger, conv, desiredUnit.name());
196  }
197 
198  // See comments on the base interface class
199  virtual int numNodes() const { assert(_nd.numNodes() >= 0); return _nd.numNodes(); }
200 
201  // See comments on the base interface class
202  virtual int numGhostNodes() const { assert(_nd.numGhostNodes() >= 0); return _nd.numGhostNodes(); }
203 
204  // Comments on the base class
205  virtual const QMap<QString, GmNodeSet*>& nodeSets() const { return _nd._nodeSets; }
206 
207  // See comments on the base interface class
208  virtual int addNodes(int numNodes) { return _nd.addNewNodes(this, numNodes); }
209 
210  // See comments on the base interface class
211  virtual int addGhostNodes(int numNodes) { return _nd.addNewGhostNodes(this, numNodes); }
212 
213  // See comments on the base interface class
214  virtual void clear() { _nd.clear(this); }
215 
217  virtual CellData* cellData() { return NULL; }
218 
219  // See comments on the base interface class
220  virtual size_t nodeMemory() const { return _nd.nodeMemory(); }
221 
222  // See comments on the base interface class
223  virtual size_t nodeSetsMemory() const { return _nd.nodeSetsMemory(); }
224 
225 protected:
232  virtual GmpMeshLoaderCellAllocator cellAllocator(bool ghostSupport, bool hSupport) const { Q_UNUSED(ghostSupport); Q_UNUSED(hSupport); return NULL; }
233 
235  virtual GmpMeshLoader<Vector>* meshLoader() { return new GmpMeshLoader<Vector>(simulationData(), logger()); }
236 
237  //---------------------------------------
238  // State dump control functions
239  //---------------------------------------
240 
241  // See comments on the base class and on the enum definition
242  virtual int controlMapStateItemType() { return GMP_GEMA_MESH_DUMP_ITEM; }
243 
244  // See comments on the base GmMesh class
245  virtual bool addStateGeometryData(GmStateDump* state, int groupId)
246  {
247  return Mesh::addStateGeometryData(state, groupId) && _nd.addStateGeometryData(state, groupId);
248  }
249 
250  // See comments on the base GmMesh class
251  virtual bool fillDumpControlMapData(QVariantMap* map, const GmLogCategory& logger)
252  {
253  return Mesh::fillDumpControlMapData(map, logger) && _nd.fillDumpControlMapData(this, map, logger);
254  }
255 
256  // See comments on the base GmMesh class
257  virtual bool dumpControlMapDataLoaded(QVariantMap* map, const GmLogCategory& logger)
258  {
259  return Mesh::dumpControlMapDataLoaded(map, logger) && _nd.dumpControlMapDataLoaded(this, map, logger);
260  }
261 
262  Data _nd;
263 };
264 
265 
266 #endif
267 
Data _nd
The complete node data.
Definition: gmpMeshBase.h:262
#define GM_MAX_ORTHOGONAL_POL_ORDER
bool isValid() const
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
GmCell *(* GmpMeshLoaderCellAllocator)(GmCellMesh *mesh, int meshId, GmCellType type, int hindex, int id, int offset)
Typedef for a function that can allocate a single cell of the given type and initialize it with the g...
Definition: gmpMeshLoaderAllocator.h:36
Element mesh dump type.
Definition: gmpMeshBase.h:46
T value() const const
GmpMeshBase(GmSimulationData *simulation, QString id, QString description, const GmLogCategory &logger)
Constructor. Will be called by the plugin loading code.
Definition: gmpMeshBase.h:72
QString tr(const char *sourceText, const char *disambiguation, int n)
Element mesh with hierarchical elements dump type.
Definition: gmpMeshBase.h:47
int toInt(bool *ok) const const
GmpGemaMeshStateDumpItemTypes
Dump item type numbers for the different types of the GemaMesh plugin objects.
Definition: gmpMeshBase.h:42
virtual bool loadPrivateData(LuaTable &table)
See behaviour comments on the base class. When inheriting from this class, the idea is that this func...
Definition: gmpMeshBase.h:108
bool hierarchicalElements() const
Returns true if the mesh uses hierarchical elements, false otherwise.
Definition: gmpCellMeshData.h:76
virtual CellData * cellData()
Virtual function that should be overriden for derived classes that need to load cells.
Definition: gmpMeshBase.h:217
static UnitConverter * converter(const Unit &srcUnit, const Unit &dstUnit, bool *compatible=NULL)
Auxiliary class used to load mesh data from a Lua file.
Definition: gmpMeshLoader.h:54
Declaration of the GmpMeshLoader class.
Auxiliar structure used to share data between GmpXxxMeshBase and GmpMeshLoader.
Definition: gmpMeshData.h:43
LuaEnv * env() const
Cell mesh dump type.
Definition: gmpMeshBase.h:45
virtual ~GmpMeshBase()
Destructor.
Definition: gmpMeshBase.h:78
Auxiliar structure used to share data between GmpXxxCellMeshBase and GmpMeshLoader.
Definition: gmpCellMeshData.h:123
Basic class for a plugin mesh. Implements the needed functions for a GmMesh interface,...
Definition: gmpMeshBase.h:68
static void pushObject(lua_State *L, Base *obj)
bool toBool() const const
virtual GmpMeshLoader< Vector > * meshLoader()
Returns the mesh loader used to load mesh data. This function should be replaced for using a custom m...
Definition: gmpMeshBase.h:235
virtual bool loadMeshData(LuaTable &table, GmMesh *mesh, GmpMeshData< Vector > *nd, GmpCellMeshData< Vector > *cd, GmpMeshLoaderCellAllocator cellAllocator)
Loads the mesh data from the supplied Lua table.
Definition: gmpMeshLoader.cpp:165
QVariant getField(const char *name, LuaEnv::StackOption opt=LuaEnv::STACK_AUTO)
QString name() const
GM_MESH_DUMP_ITEM
Node mesh dump type.
Definition: gmpMeshBase.h:44