gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
gmsh.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include <sstream>
7 #include <regex>
8 
9 #include "GmshConfig.h"
10 #include "GmshDefines.h"
11 #include "GmshGlobal.h"
12 #include "MallocUtils.h"
13 #include "GModel.h"
14 #include "GModelIO_GEO.h"
15 #include "GModelIO_OCC.h"
16 #include "GVertex.h"
17 #include "GEdge.h"
18 #include "GFace.h"
19 #include "GRegion.h"
20 #include "discreteVertex.h"
21 #include "discreteEdge.h"
22 #include "discreteFace.h"
23 #include "discreteRegion.h"
24 #include "partitionVertex.h"
25 #include "partitionEdge.h"
26 #include "partitionFace.h"
27 #include "partitionRegion.h"
28 #include "ghostEdge.h"
29 #include "ghostFace.h"
30 #include "ghostRegion.h"
31 #include "gmshSurface.h"
32 #include "MVertex.h"
33 #include "MPoint.h"
34 #include "MLine.h"
35 #include "MTriangle.h"
36 #include "MQuadrangle.h"
37 #include "MTetrahedron.h"
38 #include "MHexahedron.h"
39 #include "MPrism.h"
40 #include "MPyramid.h"
41 #include "MVertexRTree.h"
42 #include "ExtrudeParams.h"
43 #include "StringUtils.h"
44 #include "Context.h"
45 #include "polynomialBasis.h"
46 #include "pyramidalBasis.h"
47 #include "Numeric.h"
48 #include "OS.h"
49 #include "OpenFile.h"
55 #include "HierarchicalBasisH1Pri.h"
63 
64 #if defined(HAVE_MESH)
65 #include "Field.h"
66 #include "meshGFace.h"
68 #include "meshGFaceOptimize.h"
70 #include "meshGRegionHxt.h"
71 #include "gmshCrossFields.h"
72 #endif
73 
74 #if defined(HAVE_POST)
75 #include "PView.h"
76 #include "PViewData.h"
77 #include "PViewDataList.h"
78 #include "PViewDataGModel.h"
79 #include "PViewOptions.h"
80 #endif
81 
82 #if defined(HAVE_PLUGINS)
83 #include "PluginManager.h"
84 #endif
85 
86 #if defined(HAVE_OPENGL)
87 #include "drawContext.h"
88 #endif
89 
90 #if defined(HAVE_FLTK)
91 #include "FlGui.h"
92 #endif
93 
94 #if defined(HAVE_PARSER)
95 #include "Parser.h"
96 #endif
97 
98 #if defined(HAVE_ONELAB)
99 #include "onelab.h"
100 #include "onelabUtils.h"
101 #endif
102 
103 // automatically generated C++ and C headers (in gmsh/api)
104 #include "gmsh.h"
105 extern "C" {
106 #include "gmshc.h"
107 }
108 
109 static int _initialized = 0;
110 static int _argc = 0;
111 static char **_argv = nullptr;
112 
113 static bool _checkInit()
114 {
115  if(!_initialized) {
116  CTX::instance()->terminal = 1;
117  Msg::Error("Gmsh has not been initialized");
118  return false;
119  }
120  if(!GModel::current()) {
121  Msg::Error("Gmsh has no current model");
122  return false;
123  }
124  return true;
125 }
126 
127 // gmsh
128 
129 GMSH_API void gmsh::initialize(int argc, char ** argv,
130  const bool readConfigFiles, const bool run)
131 {
132  if(_initialized) {
133  Msg::Warning("Gmsh has aleady been initialized");
134  return;
135  }
136 
137  // when running the app, create a model (that will be used in GmshInitialize
138  // to e.g. set the project name)
139  if(run) new GModel();
140 
141  if(GmshInitialize(argc, argv, readConfigFiles, false)) {
142  _initialized = 1;
143  _argc = argc;
144  _argv = new char *[_argc + 1];
145  for(int i = 0; i < argc; i++) _argv[i] = argv[i];
146 
147 #if defined(HAVE_FLTK)
148  // if the GUI is already running (rare case, but could happen), we're done
149  if(FlGui::available()) return;
150 #endif
151 
152  if(run) {
153  if(CTX::instance()->batch) {
155  GmshBatch();
156  }
157  else {
158  GmshFLTK(argc, argv);
159  }
160  }
161  else {
162  // throw an exception as soon as an error occurs, unless the GUI is
163  // running (by default the Gmsh app - and thus also when "run" is set -
164  // always keeps going after errors)
166  // show messages on the terminal
167  CTX::instance()->terminal = 1;
168  }
169  return;
170  }
171  Msg::Error("Something went wrong when initializing Gmsh");
172 }
173 
175 {
176  return _initialized;
177 }
178 
179 GMSH_API void gmsh::finalize()
180 {
181  if(!_checkInit()) return;
182  if(GmshFinalize()) {
183  _argc = 0;
184  if(_argv) delete[] _argv;
185  _argv = nullptr;
186  _initialized = 0;
187  return;
188  }
189  Msg::Error("Something went wrong when finalizing Gmsh");
190 }
191 
192 GMSH_API void gmsh::open(const std::string &fileName)
193 {
194  if(!_checkInit()) return;
195  if(!GmshOpenProject(fileName))
196  Msg::Error("Could not open file '%s'", fileName.c_str());
197 }
198 
199 GMSH_API void gmsh::merge(const std::string &fileName)
200 {
201  if(!_checkInit()) return;
202  if(!GmshMergeFile(fileName))
203  Msg::Error("Could not merge file '%s'", fileName.c_str());
204 }
205 
206 GMSH_API void gmsh::write(const std::string &fileName)
207 {
208  if(!_checkInit()) return;
209  if(!GmshWriteFile(fileName))
210  Msg::Error("Could not write file '%s'", fileName.c_str());
211 }
212 
213 GMSH_API void gmsh::clear()
214 {
215  if(!_checkInit()) return;
216  if(!GmshClearProject()) Msg::Error("Could not clear project");
217 }
218 
219 // gmsh::option
220 
221 GMSH_API void gmsh::option::setNumber(const std::string &name,
222  const double value)
223 {
224  if(!_checkInit()) return;
225  std::string c, n;
226  int i;
227  SplitOptionName(name, c, n, i);
228  if(!GmshSetOption(c, n, value, i))
229  Msg::Error("Could not set option '%s'", name.c_str());
230 }
231 
232 GMSH_API void gmsh::option::getNumber(const std::string &name, double &value)
233 {
234  if(!_checkInit()) return;
235  std::string c, n;
236  int i;
237  SplitOptionName(name, c, n, i);
238  if(!GmshGetOption(c, n, value, i))
239  Msg::Error("Could not get option '%s'", name.c_str());
240 }
241 
242 GMSH_API void gmsh::option::setString(const std::string &name,
243  const std::string &value)
244 {
245  if(!_checkInit()) return;
246  std::string c, n;
247  int i;
248  SplitOptionName(name, c, n, i);
249  if(!GmshSetOption(c, n, value, i))
250  Msg::Error("Could not set option '%s'", name.c_str());
251 }
252 
253 GMSH_API void gmsh::option::getString(const std::string &name,
254  std::string &value)
255 {
256  if(!_checkInit()) return;
257  std::string c, n;
258  int i;
259  SplitOptionName(name, c, n, i);
260  if(!GmshGetOption(c, n, value, i))
261  Msg::Error("Could not get option '%s'", name.c_str());
262 }
263 
264 GMSH_API void gmsh::option::setColor(const std::string &name, const int r,
265  const int g, const int b, const int a)
266 {
267  if(!_checkInit()) return;
268  std::string c, n;
269  int i;
270  SplitOptionName(name, c, n, i);
271  // allow "Category.Color.Option" name for compatibility with .geo parser
272  n = ReplaceSubString("Color.", "", n);
273  unsigned int value = CTX::instance()->packColor(r, g, b, a);
274  if(!GmshSetOption(c, n, value, i))
275  Msg::Error("Could not set option '%s'", name.c_str());
276 }
277 
278 GMSH_API void gmsh::option::getColor(const std::string &name, int &r, int &g,
279  int &b, int &a)
280 {
281  if(!_checkInit()) return;
282  std::string c, n;
283  int i;
284  SplitOptionName(name, c, n, i);
285  // allow "Category.Color.Option" name for compatibility with .geo parser
286  n = ReplaceSubString("Color.", "", n);
287  unsigned int value;
288  if(GmshGetOption(c, n, value, i)) {
289  r = CTX::instance()->unpackRed(value);
290  g = CTX::instance()->unpackGreen(value);
291  b = CTX::instance()->unpackBlue(value);
292  a = CTX::instance()->unpackAlpha(value);
293  }
294  else {
295  Msg::Error("Could not get option '%s'", name.c_str());
296  }
297 }
298 
299 // gmsh::model
300 
301 GMSH_API void gmsh::model::add(const std::string &name)
302 {
303  if(!_checkInit()) return;
304  GModel *m = new GModel(name);
305  GModel::current(GModel::list.size() - 1);
306  if(!m) Msg::Error("Could not add model '%s'", name.c_str());
307 }
308 
309 GMSH_API void gmsh::model::remove()
310 {
311  if(!_checkInit()) return;
312  GModel *m = GModel::current();
313  if(m)
314  delete m;
315  else
316  Msg::Error("Could not remove current model");
317 }
318 
319 GMSH_API void gmsh::model::list(std::vector<std::string> &names)
320 {
321  if(!_checkInit()) return;
322  for(std::size_t i = 0; i < GModel::list.size(); i++)
323  names.push_back(GModel::list[i]->getName());
324 }
325 
326 GMSH_API void gmsh::model::getCurrent(std::string &name)
327 {
328  if(!_checkInit()) return;
329  name = GModel::current()->getName();
330 }
331 
332 GMSH_API void gmsh::model::setCurrent(const std::string &name)
333 {
334  if(!_checkInit()) return;
335  GModel *m = GModel::findByName(name);
336  if(!m) {
337  Msg::Error("Could not find model '%s'", name.c_str());
338  return;
339  }
341  for(std::size_t i = 0; i < GModel::list.size(); i++)
345 }
346 
347 GMSH_API void gmsh::model::getFileName(std::string &fileName)
348 {
349  if(!_checkInit()) return;
350  fileName = GModel::current()->getFileName();
351 }
352 
353 GMSH_API void gmsh::model::setFileName(const std::string &fileName)
354 {
355  if(!_checkInit()) return;
356  GModel::current()->setFileName(fileName);
357 }
358 
359 GMSH_API void gmsh::model::getEntities(vectorpair &dimTags, const int dim)
360 {
361  if(!_checkInit()) return;
362  dimTags.clear();
363  std::vector<GEntity *> entities;
364  GModel::current()->getEntities(entities, dim);
365  for(std::size_t i = 0; i < entities.size(); i++)
366  dimTags.push_back(
367  std::make_pair(entities[i]->dim(), entities[i]->tag()));
368 }
369 
370 GMSH_API void gmsh::model::setEntityName(const int dim, const int tag,
371  const std::string &name)
372 {
373  if(!_checkInit()) return;
374  GModel::current()->setElementaryName(dim, tag, name);
375 }
376 
377 GMSH_API void gmsh::model::getEntityName(const int dim, const int tag,
378  std::string &name)
379 {
380  if(!_checkInit()) return;
381  name = GModel::current()->getElementaryName(dim, tag);
382 }
383 
384 GMSH_API void gmsh::model::getPhysicalGroups(vectorpair &dimTags, const int dim)
385 {
386  if(!_checkInit()) return;
387  dimTags.clear();
388  std::map<int, std::vector<GEntity *> > groups[4];
390  for(int d = 0; d < 4; d++) {
391  if(dim < 0 || d == dim) {
392  for(auto it = groups[d].begin(); it != groups[d].end(); it++)
393  dimTags.push_back(std::make_pair(d, it->first));
394  }
395  }
396 }
397 
398 static std::string _getEntityName(int dim, int tag)
399 {
400  std::stringstream stream;
401  switch(dim) {
402  case 0: stream << "Point "; break;
403  case 1: stream << "Curve "; break;
404  case 2: stream << "Surface "; break;
405  case 3: stream << "Volume "; break;
406  }
407  stream << tag;
408  return stream.str();
409 }
410 
411 GMSH_API void gmsh::model::getEntitiesForPhysicalGroup(const int dim,
412  const int tag,
413  std::vector<int> &tags)
414 {
415  if(!_checkInit()) return;
416  tags.clear();
417  std::map<int, std::vector<GEntity *> > groups;
418  GModel::current()->getPhysicalGroups(dim, groups);
419  auto it = groups.find(tag);
420  if(it != groups.end()) {
421  for(std::size_t j = 0; j < it->second.size(); j++)
422  tags.push_back(it->second[j]->tag());
423  }
424  else {
425  Msg::Error("Physical %s does not exist", _getEntityName(dim, tag).c_str());
426  }
427 }
428 
429 GMSH_API void
430 gmsh::model::getPhysicalGroupsForEntity(const int dim, const int tag,
431  std::vector<int> &physicalTags)
432 {
433  if(!_checkInit()) return;
434  physicalTags.clear();
435  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
436  if(!ge) {
437  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
438  return;
439  }
440  std::vector<int> phy = ge->getPhysicalEntities();
441  if(phy.empty()) return;
442  physicalTags.resize(phy.size());
443  for(std::size_t i = 0; i < phy.size(); i++) { physicalTags[i] = phy[i]; }
444 }
445 
446 GMSH_API int gmsh::model::addPhysicalGroup(const int dim,
447  const std::vector<int> &tags,
448  const int tag,
449  const std::string &name)
450 {
451  // FIXME: 1) the "master" physical group definitions are still stored in the
452  // buil-in CAD kernel, so that built-in CAD operations (e.g. Coherence) can
453  // track physical groups; and 2) the synchronization of the built-in CAD
454  // kernel triggers a reset of physical groups in GModel, followed by a
455  // copy. So we currently need to maintain both copies when playing with
456  // physical groups in the api at the model level.
457  if(!_checkInit()) return -1;
458  int outTag = tag;
459  if(outTag < 0) {
460  outTag =
461  std::max(GModel::current()->getMaxPhysicalNumber(dim),
462  GModel::current()->getGEOInternals()->getMaxPhysicalTag()) +
463  1;
464  }
465  if(!GModel::current()->getGEOInternals()->modifyPhysicalGroup(dim, outTag, 0,
466  tags)) {
467  Msg::Error("Could not add physical group");
468  return -1;
469  }
470  GModel::current()->addPhysicalGroup(dim, outTag, tags);
471  if(!name.empty()) GModel::current()->setPhysicalName(name, dim, outTag);
472  return outTag;
473 }
474 
475 GMSH_API void gmsh::model::removePhysicalGroups(const vectorpair &dimTags)
476 {
477  if(!_checkInit()) return;
478  if(dimTags.empty()) {
481  }
482  else {
483  // FIXME: rewrite the unerlying code: it's slow
484  for(std::size_t i = 0; i < dimTags.size(); i++) {
485  std::vector<int> tags; // empty to delete the group
487  dimTags[i].first, dimTags[i].second, 2, tags);
488  GModel::current()->removePhysicalGroup(dimTags[i].first,
489  dimTags[i].second);
490  }
491  }
492 }
493 
494 GMSH_API void gmsh::model::setPhysicalName(const int dim, const int tag,
495  const std::string &name)
496 {
497  if(!_checkInit()) return;
498  GModel::current()->setPhysicalName(name, dim, tag);
499 }
500 
501 GMSH_API void gmsh::model::removePhysicalName(const std::string &name)
502 {
503  if(!_checkInit()) return;
505 }
506 
507 GMSH_API void gmsh::model::getPhysicalName(const int dim, const int tag,
508  std::string &name)
509 {
510  if(!_checkInit()) return;
511  name = GModel::current()->getPhysicalName(dim, tag);
512 }
513 
514 GMSH_API void gmsh::model::setTag(const int dim, const int tag, const int newTag)
515 {
516  if(!_checkInit()) return;
517  GModel::current()->changeEntityTag(dim, tag, newTag);
518 }
519 
520 GMSH_API void gmsh::model::getBoundary(const vectorpair &dimTags,
521  vectorpair &outDimTags,
522  const bool combined, const bool oriented,
523  const bool recursive)
524 {
525  if(!_checkInit()) return;
526  outDimTags.clear();
527  if(!GModel::current()->getBoundaryTags(dimTags, outDimTags, combined,
528  oriented, recursive)) {
529  Msg::Error("Could not get boundary");
530  }
531 }
532 
533 GMSH_API void gmsh::model::getAdjacencies(const int dim, const int tag,
534  std::vector<int> &upward,
535  std::vector<int> &downward)
536 {
537  if(!_checkInit()) return;
538  upward.clear();
539  downward.clear();
540  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
541  if(!ge) {
542  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
543  return;
544  }
545  switch(dim) {
546  case 0:
547  for(auto &e : static_cast<GVertex *>(ge)->edges())
548  upward.push_back(e->tag());
549  break;
550  case 1:
551  for(auto &e : static_cast<GEdge *>(ge)->faces()) upward.push_back(e->tag());
552  for(auto &e : static_cast<GEdge *>(ge)->vertices())
553  downward.push_back(e->tag());
554  break;
555  case 2:
556  for(auto &e : static_cast<GFace *>(ge)->regions())
557  upward.push_back(e->tag());
558  for(auto &e : static_cast<GFace *>(ge)->edges())
559  downward.push_back(e->tag());
560  break;
561  case 3:
562  for(auto &e : static_cast<GRegion *>(ge)->faces())
563  downward.push_back(e->tag());
564  break;
565  }
566 }
567 
568 GMSH_API void gmsh::model::getEntitiesInBoundingBox(
569  const double xmin, const double ymin, const double zmin, const double xmax,
570  const double ymax, const double zmax, vectorpair &dimTags, const int dim)
571 {
572  if(!_checkInit()) return;
573  dimTags.clear();
574  SBoundingBox3d box(xmin, ymin, zmin, xmax, ymax, zmax);
575  std::vector<GEntity *> entities;
576  GModel::current()->getEntitiesInBox(entities, box, dim);
577  for(std::size_t i = 0; i < entities.size(); i++)
578  dimTags.push_back(
579  std::make_pair(entities[i]->dim(), entities[i]->tag()));
580 }
581 
582 GMSH_API void gmsh::model::getBoundingBox(const int dim, const int tag,
583  double &xmin, double &ymin,
584  double &zmin, double &xmax,
585  double &ymax, double &zmax)
586 {
587  if(!_checkInit()) return;
588 
590  if(dim < 0 && tag < 0) {
591  box = GModel::current()->bounds();
592  if(box.empty()) {
593  Msg::Error("Empty bounding box");
594  return;
595  }
596  }
597  else {
598  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
599  if(!ge) {
600  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
601  return;
602  }
603  box = ge->bounds();
604  }
605  if(box.empty()) {
606  Msg::Error("Empty bounding box");
607  return;
608  }
609  xmin = box.min().x();
610  ymin = box.min().y();
611  zmin = box.min().z();
612  xmax = box.max().x();
613  ymax = box.max().y();
614  zmax = box.max().z();
615 }
616 
618 {
619  if(!_checkInit()) return -1;
620  return GModel::current()->getDim();
621 }
622 
623 GMSH_API int gmsh::model::addDiscreteEntity(const int dim, const int tag,
624  const std::vector<int> &boundary)
625 {
626  if(!_checkInit()) return -1;
627  int outTag = tag;
628  if(outTag < 0) {
629  outTag = GModel::current()->getMaxElementaryNumber(dim) + 1;
630  }
631  GEntity *e = GModel::current()->getEntityByTag(dim, outTag);
632  if(e) {
633  Msg::Error("%s already exists", _getEntityName(dim, outTag).c_str());
634  return -1;
635  }
636  switch(dim) {
637  case 0: {
638  discreteVertex *gv = new discreteVertex(GModel::current(), outTag);
639  GModel::current()->add(gv);
640  break;
641  }
642  case 1: {
643  GVertex *v0 = nullptr, *v1 = nullptr;
644  if(boundary.size() >= 1)
645  v0 = GModel::current()->getVertexByTag(boundary[0]);
646  if(boundary.size() >= 2)
647  v1 = GModel::current()->getVertexByTag(boundary[1]);
648  discreteEdge *ge = new discreteEdge(GModel::current(), outTag, v0, v1);
649  GModel::current()->add(ge);
650  break;
651  }
652  case 2: {
653  discreteFace *gf = new discreteFace(GModel::current(), outTag);
654  std::vector<int> tagEdges, signEdges;
655  for(std::size_t i = 0; i < boundary.size(); i++) {
656  tagEdges.push_back(std::abs(boundary[i]));
657  signEdges.push_back(gmsh_sign(boundary[i]));
658  }
659  if(!tagEdges.empty()) gf->setBoundEdges(tagEdges, signEdges);
660  GModel::current()->add(gf);
661  break;
662  }
663  case 3: {
664  discreteRegion *gr = new discreteRegion(GModel::current(), outTag);
665  std::vector<int> tagFaces, signFaces;
666  for(std::size_t i = 0; i < boundary.size(); i++) {
667  tagFaces.push_back(std::abs(boundary[i]));
668  signFaces.push_back(gmsh_sign(boundary[i]));
669  }
670  if(!tagFaces.empty()) gr->setBoundFaces(tagFaces, signFaces);
671  GModel::current()->add(gr);
672  break;
673  }
674  }
675  return outTag;
676 }
677 
678 GMSH_API void gmsh::model::removeEntities(const vectorpair &dimTags,
679  const bool recursive)
680 {
681  if(!_checkInit()) return;
682  std::vector<GEntity*> removed;
683  GModel::current()->remove(dimTags, removed, recursive);
684  Msg::Debug("Destroying %lu entities in model", removed.size());
685  for(std::size_t i = 0; i < removed.size(); i++) delete removed[i];
686 }
687 
688 GMSH_API void gmsh::model::removeEntityName(const std::string &name)
689 {
690  if(!_checkInit()) return;
692 }
693 
694 GMSH_API void gmsh::model::getType(const int dim, const int tag,
695  std::string &entityType)
696 {
697  if(!_checkInit()) return;
698  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
699  if(!ge) {
700  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
701  return;
702  }
703  entityType = ge->getTypeString();
704 }
705 
706 GMSH_API void gmsh::model::getParent(const int dim, const int tag,
707  int &parentDim, int &parentTag)
708 {
709  if(!_checkInit()) return;
710  parentDim = -1;
711  parentTag = -1;
712  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
713  if(!ge) {
714  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
715  return;
716  }
717  GEntity *parent = ge->getParentEntity();
718  if(parent) {
719  parentDim = parent->dim();
720  parentTag = parent->tag();
721  }
722 }
723 
724 GMSH_API void gmsh::model::getPartitions(const int dim, const int tag,
725  std::vector<int> &partitions)
726 {
727  if(!_checkInit()) return;
728  partitions.clear();
729  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
730  if(!ge) {
731  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
732  return;
733  }
734  std::vector<int> p;
735  if(ge->geomType() == GEntity::PartitionPoint)
736  p = static_cast<partitionVertex *>(ge)->getPartitions();
737  else if(ge->geomType() == GEntity::PartitionCurve)
738  p = static_cast<partitionEdge *>(ge)->getPartitions();
739  else if(ge->geomType() == GEntity::PartitionSurface)
740  p = static_cast<partitionFace *>(ge)->getPartitions();
741  else if(ge->geomType() == GEntity::PartitionVolume)
742  p = static_cast<partitionRegion *>(ge)->getPartitions();
743  else if(ge->geomType() == GEntity::GhostCurve)
744  p.push_back(static_cast<ghostEdge *>(ge)->getPartition());
745  else if(ge->geomType() == GEntity::GhostSurface)
746  p.push_back(static_cast<ghostFace *>(ge)->getPartition());
747  else if(ge->geomType() == GEntity::GhostVolume)
748  p.push_back(static_cast<ghostRegion *>(ge)->getPartition());
749 
750  for(std::size_t i = 0; i < p.size(); i++) partitions.push_back(p[i]);
751 }
752 
753 GMSH_API int gmsh::model::getNumberOfPartitions()
754 {
755  if(!_checkInit()) return 0;
756  return GModel::current()->getNumPartitions();
757 }
758 
759 GMSH_API void gmsh::model::getValue(const int dim, const int tag,
760  const std::vector<double> &parametricCoord,
761  std::vector<double> &coord)
762 {
763  if(!_checkInit()) return;
764  coord.clear();
765  GEntity *entity = GModel::current()->getEntityByTag(dim, tag);
766  if(!entity) {
767  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
768  return;
769  }
770  if(dim == 0) {
771  coord.push_back(static_cast<GVertex *>(entity)->x());
772  coord.push_back(static_cast<GVertex *>(entity)->y());
773  coord.push_back(static_cast<GVertex *>(entity)->z());
774  }
775  else if(dim == 1) {
776  GEdge *ge = static_cast<GEdge *>(entity);
777  for(std::size_t i = 0; i < parametricCoord.size(); i++) {
778  GPoint gp = ge->point(parametricCoord[i]);
779  coord.push_back(gp.x());
780  coord.push_back(gp.y());
781  coord.push_back(gp.z());
782  }
783  }
784  else if(dim == 2) {
785  if(parametricCoord.size() % 2) {
786  Msg::Error("Number of parametric coordinates should be even");
787  return;
788  }
789  GFace *gf = static_cast<GFace *>(entity);
790  for(std::size_t i = 0; i < parametricCoord.size(); i += 2) {
791  SPoint2 param(parametricCoord[i], parametricCoord[i + 1]);
792  GPoint gp = gf->point(param);
793  coord.push_back(gp.x());
794  coord.push_back(gp.y());
795  coord.push_back(gp.z());
796  }
797  }
798 }
799 
800 GMSH_API void
801 gmsh::model::getDerivative(const int dim, const int tag,
802  const std::vector<double> &parametricCoord,
803  std::vector<double> &deriv)
804 {
805  if(!_checkInit()) return;
806  deriv.clear();
807  GEntity *entity = GModel::current()->getEntityByTag(dim, tag);
808  if(!entity) {
809  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
810  return;
811  }
812  if(dim == 1) {
813  GEdge *ge = static_cast<GEdge *>(entity);
814  for(std::size_t i = 0; i < parametricCoord.size(); i++) {
815  SVector3 d = ge->firstDer(parametricCoord[i]);
816  deriv.push_back(d.x());
817  deriv.push_back(d.y());
818  deriv.push_back(d.z());
819  }
820  }
821  else if(dim == 2) {
822  if(parametricCoord.size() % 2) {
823  Msg::Error("Number of parametric coordinates should be even");
824  return;
825  }
826  GFace *gf = static_cast<GFace *>(entity);
827  for(std::size_t i = 0; i < parametricCoord.size(); i += 2) {
828  SPoint2 param(parametricCoord[i], parametricCoord[i + 1]);
829  Pair<SVector3, SVector3> d = gf->firstDer(param);
830  deriv.push_back(d.left().x());
831  deriv.push_back(d.left().y());
832  deriv.push_back(d.left().z());
833  deriv.push_back(d.right().x());
834  deriv.push_back(d.right().y());
835  deriv.push_back(d.right().z());
836  }
837  }
838 }
839 
840 GMSH_API void
841 gmsh::model::getSecondDerivative(const int dim, const int tag,
842  const std::vector<double> &parametricCoord,
843  std::vector<double> &deriv)
844 {
845  if(!_checkInit()) return;
846  deriv.clear();
847  GEntity *entity = GModel::current()->getEntityByTag(dim, tag);
848  if(!entity) {
849  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
850  return;
851  }
852  if(dim == 1) {
853  GEdge *ge = static_cast<GEdge *>(entity);
854  for(std::size_t i = 0; i < parametricCoord.size(); i++) {
855  SVector3 d = ge->secondDer(parametricCoord[i]);
856  deriv.push_back(d.x());
857  deriv.push_back(d.y());
858  deriv.push_back(d.z());
859  }
860  }
861  else if(dim == 2) {
862  if(parametricCoord.size() % 2) {
863  Msg::Error("Number of parametric coordinates should be even");
864  return;
865  }
866  GFace *gf = static_cast<GFace *>(entity);
867  for(std::size_t i = 0; i < parametricCoord.size(); i += 2) {
868  SPoint2 param(parametricCoord[i], parametricCoord[i + 1]);
869  SVector3 dudu, dvdv, dudv;
870  gf->secondDer(param, dudu, dvdv, dudv);
871  deriv.push_back(dudu.x());
872  deriv.push_back(dudu.y());
873  deriv.push_back(dudu.z());
874  deriv.push_back(dvdv.x());
875  deriv.push_back(dvdv.y());
876  deriv.push_back(dvdv.z());
877  deriv.push_back(dudv.x());
878  deriv.push_back(dudv.y());
879  deriv.push_back(dudv.z());
880  }
881  }
882 }
883 
884 GMSH_API void
885 gmsh::model::getCurvature(const int dim, const int tag,
886  const std::vector<double> &parametricCoord,
887  std::vector<double> &curvatures)
888 {
889  if(!_checkInit()) return;
890  curvatures.clear();
891  GEntity *entity = GModel::current()->getEntityByTag(dim, tag);
892  if(!entity) {
893  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
894  return;
895  }
896  if(dim == 1) {
897  GEdge *ge = static_cast<GEdge *>(entity);
898  for(std::size_t i = 0; i < parametricCoord.size(); i++)
899  curvatures.push_back(ge->curvature(parametricCoord[i]));
900  }
901  else if(dim == 2) {
902  if(parametricCoord.size() % 2) {
903  Msg::Error("Number of parametric coordinates should be even");
904  return;
905  }
906  GFace *gf = static_cast<GFace *>(entity);
907  for(std::size_t i = 0; i < parametricCoord.size(); i += 2) {
908  SPoint2 param(parametricCoord[i], parametricCoord[i + 1]);
909  curvatures.push_back(gf->curvatureMax(param));
910  }
911  }
912 }
913 
914 GMSH_API void gmsh::model::getPrincipalCurvatures(
915  const int tag, const std::vector<double> &parametricCoord,
916  std::vector<double> &curvaturesMax, std::vector<double> &curvaturesMin,
917  std::vector<double> &directionsMax, std::vector<double> &directionsMin)
918 {
919  if(!_checkInit()) return;
920  GFace *gf = GModel::current()->getFaceByTag(tag);
921  if(!gf) {
922  Msg::Error("%s does not exist", _getEntityName(2, tag).c_str());
923  return;
924  }
925  curvaturesMax.clear();
926  curvaturesMin.clear();
927  directionsMax.clear();
928  directionsMin.clear();
929  if(parametricCoord.size() % 2) {
930  Msg::Error("Number of parametric coordinates should be even");
931  return;
932  }
933  for(std::size_t i = 0; i < parametricCoord.size(); i += 2) {
934  SPoint2 param(parametricCoord[i], parametricCoord[i + 1]);
935  double cmin, cmax;
936  SVector3 dmin, dmax;
937  gf->curvatures(param, dmax, dmin, cmax, cmin);
938  curvaturesMax.push_back(cmax);
939  curvaturesMin.push_back(cmin);
940  directionsMax.push_back(dmax.x());
941  directionsMax.push_back(dmax.y());
942  directionsMax.push_back(dmax.z());
943  directionsMin.push_back(dmin.x());
944  directionsMin.push_back(dmin.y());
945  directionsMin.push_back(dmin.z());
946  }
947 }
948 
949 GMSH_API void gmsh::model::getNormal(const int tag,
950  const std::vector<double> &parametricCoord,
951  std::vector<double> &normals)
952 {
953  if(!_checkInit()) return;
954  GFace *gf = GModel::current()->getFaceByTag(tag);
955  if(!gf) {
956  Msg::Error("%s does not exist", _getEntityName(2, tag).c_str());
957  return;
958  }
959  normals.clear();
960  if(parametricCoord.size() % 2) {
961  Msg::Error("Number of parametric coordinates should be even");
962  return;
963  }
964  for(std::size_t i = 0; i < parametricCoord.size(); i += 2) {
965  SPoint2 param(parametricCoord[i], parametricCoord[i + 1]);
966  SVector3 n = gf->normal(param);
967  normals.push_back(n.x());
968  normals.push_back(n.y());
969  normals.push_back(n.z());
970  }
971 }
972 
973 GMSH_API void
974 gmsh::model::getParametrization(const int dim, const int tag,
975  const std::vector<double> &coord,
976  std::vector<double> &parametricCoord)
977 {
978  if(!_checkInit()) return;
979  parametricCoord.clear();
980  GEntity *entity = GModel::current()->getEntityByTag(dim, tag);
981  if(!entity) {
982  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
983  return;
984  }
985  if(coord.size() % 3) {
986  Msg::Error("Number of coordinates should be a multiple of 3");
987  return;
988  }
989  if(dim == 1) {
990  GEdge *ge = static_cast<GEdge *>(entity);
991  for(std::size_t i = 0; i < coord.size(); i += 3) {
992  SPoint3 p(coord[i], coord[i + 1], coord[i + 2]);
993  double t = ge->parFromPoint(p);
994  parametricCoord.push_back(t);
995  }
996  }
997  else if(dim == 2) {
998  GFace *gf = static_cast<GFace *>(entity);
999  for(std::size_t i = 0; i < coord.size(); i += 3) {
1000  SPoint3 p(coord[i], coord[i + 1], coord[i + 2]);
1001  SPoint2 uv = gf->parFromPoint(p, true, true);
1002  parametricCoord.push_back(uv.x());
1003  parametricCoord.push_back(uv.y());
1004  }
1005  }
1006 }
1007 
1008 GMSH_API void gmsh::model::getParametrizationBounds(const int dim,
1009  const int tag,
1010  std::vector<double> &min,
1011  std::vector<double> &max)
1012 {
1013  if(!_checkInit()) return;
1014  min.clear();
1015  max.clear();
1016  GEntity *entity = GModel::current()->getEntityByTag(dim, tag);
1017  if(!entity) {
1018  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1019  return;
1020  }
1021  for(int dim = 0; dim < entity->dim(); dim++) {
1022  Range<double> r = entity->parBounds(dim);
1023  min.push_back(r.low());
1024  max.push_back(r.high());
1025  }
1026 }
1027 
1028 GMSH_API int gmsh::model::isInside(const int dim, const int tag,
1029  const std::vector<double> &coord,
1030  const bool parametric)
1031 {
1032  if(!_checkInit()) return -1;
1033  GEntity *entity = GModel::current()->getEntityByTag(dim, tag);
1034  if(!entity) {
1035  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1036  return 0;
1037  }
1038  int num = 0;
1039  if(parametric) {
1040  if(dim == 1) {
1041  GEdge *ge = static_cast<GEdge *>(entity);
1042  for(std::size_t i = 0; i < coord.size(); i++) {
1043  if(ge->containsParam(coord[i])) num++;
1044  }
1045  }
1046  else if(dim == 2) {
1047  GFace *gf = static_cast<GFace *>(entity);
1048  if(coord.size() % 2) {
1049  Msg::Error("Number of parametric coordinates should be even");
1050  return num;
1051  }
1052  for(std::size_t i = 0; i < coord.size(); i += 2) {
1053  SPoint2 param(coord[i], coord[i + 1]);
1054  if(gf->containsParam(param)) num++;
1055  }
1056  }
1057  }
1058  else {
1059  if(coord.size() % 3) {
1060  Msg::Error("Number of coordinates should be a multiple of 3");
1061  return 0;
1062  }
1063  for(std::size_t i = 0; i < coord.size(); i += 3) {
1064  SPoint3 pt(coord[i], coord[i + 1], coord[i + 2]);
1065  if(entity->isFullyDiscrete()) { // query the mesh
1066  SPoint3 uvw;
1068  entity->dim());
1069  if(e) {
1070  int entityTag;
1071  e = GModel::current()->getMeshElementByTag(e->getNum(), entityTag);
1072  if(e && entityTag == entity->tag()) num++;
1073  }
1074  }
1075  else { // query the CAD
1076  if(entity->containsPoint(pt)) num++;
1077  }
1078  }
1079  }
1080  return num;
1081 }
1082 
1083 GMSH_API void gmsh::model::reparametrizeOnSurface(
1084  const int dim, const int tag, const std::vector<double> &parametricCoord,
1085  const int surfaceTag, std::vector<double> &surfaceParametricCoord,
1086  const int which)
1087 {
1088  if(!_checkInit()) return;
1089  surfaceParametricCoord.clear();
1090  GEntity *entity = GModel::current()->getEntityByTag(dim, tag);
1091  if(!entity) {
1092  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1093  return;
1094  }
1095  GFace *gf = GModel::current()->getFaceByTag(surfaceTag);
1096  if(!gf) {
1097  Msg::Error("%s does not exist", _getEntityName(2, surfaceTag).c_str());
1098  return;
1099  }
1100  if(dim == 0) {
1101  GVertex *gv = static_cast<GVertex *>(entity);
1102  SPoint2 p = gv->reparamOnFace(gf, which);
1103  surfaceParametricCoord.push_back(p.x());
1104  surfaceParametricCoord.push_back(p.y());
1105  }
1106  else if(dim == 1) {
1107  GEdge *ge = static_cast<GEdge *>(entity);
1108  for(std::size_t i = 0; i < parametricCoord.size(); i++) {
1109  SPoint2 p = ge->reparamOnFace(gf, parametricCoord[i], which);
1110  surfaceParametricCoord.push_back(p.x());
1111  surfaceParametricCoord.push_back(p.y());
1112  }
1113  }
1114 }
1115 
1116 GMSH_API void gmsh::model::getClosestPoint(const int dim, const int tag,
1117  const std::vector<double> &coord,
1118  std::vector<double> &closestCoord,
1119  std::vector<double> &parametricCoord)
1120 {
1121  if(!_checkInit()) return;
1122  closestCoord.clear();
1123  parametricCoord.clear();
1124  GEntity *entity = GModel::current()->getEntityByTag(dim, tag);
1125  if(!entity) {
1126  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1127  return;
1128  }
1129  if(coord.size() % 3) {
1130  Msg::Error("Number of coordinates should be a multiple of 3");
1131  return;
1132  }
1133  if(dim == 1) {
1134  GEdge *ge = static_cast<GEdge *>(entity);
1135  for(std::size_t i = 0; i < coord.size(); i += 3) {
1136  SPoint3 p(coord[i], coord[i + 1], coord[i + 2]);
1137  double t;
1138  GPoint pp = ge->closestPoint(p, t);
1139  closestCoord.push_back(pp.x());
1140  closestCoord.push_back(pp.y());
1141  closestCoord.push_back(pp.z());
1142  parametricCoord.push_back(t);
1143  }
1144  }
1145  else if(dim == 2) {
1146  GFace *gf = static_cast<GFace *>(entity);
1147  for(std::size_t i = 0; i < coord.size(); i += 3) {
1148  SPoint3 p(coord[i], coord[i + 1], coord[i + 2]);
1149  double uv[2] = {0, 0};
1150  GPoint pp = gf->closestPoint(p, uv);
1151  closestCoord.push_back(pp.x());
1152  closestCoord.push_back(pp.y());
1153  closestCoord.push_back(pp.z());
1154  parametricCoord.push_back(uv[0]);
1155  parametricCoord.push_back(uv[1]);
1156  }
1157  }
1158 }
1159 
1160 GMSH_API void gmsh::model::setVisibility(const vectorpair &dimTags,
1161  const int value, const bool recursive)
1162 {
1163  if(!_checkInit()) return;
1164  for(std::size_t i = 0; i < dimTags.size(); i++) {
1166  dimTags[i].first, std::abs(dimTags[i].second));
1167  if(ge) ge->setVisibility(value, recursive);
1168  }
1169 }
1170 
1171 GMSH_API void gmsh::model::getVisibility(const int dim, const int tag,
1172  int &value)
1173 {
1174  if(!_checkInit()) return;
1175  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
1176  if(!ge) {
1177  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1178  return;
1179  }
1180  value = ge->getVisibility();
1181 }
1182 
1183 GMSH_API void gmsh::model::setVisibilityPerWindow(const int value,
1184  const int windowIndex)
1185 {
1186  if(!_checkInit()) return;
1187 #if defined(HAVE_FLTK)
1188  FlGui::instance()->setCurrentOpenglWindow(windowIndex);
1189  drawContext *ctx = FlGui::instance()->getCurrentDrawContext();
1190  GModel *m = GModel::current();
1191  if(value)
1192  ctx->show(m);
1193  else
1194  ctx->hide(m);
1195 #endif
1196 }
1197 
1198 GMSH_API void gmsh::model::setColor(const vectorpair &dimTags, const int r,
1199  const int g, const int b, const int a,
1200  const bool recursive)
1201 {
1202  if(!_checkInit()) return;
1203  for(std::size_t i = 0; i < dimTags.size(); i++) {
1205  dimTags[i].first, std::abs(dimTags[i].second));
1206  if(ge) {
1207  unsigned int val = CTX::instance()->packColor(r, g, b, a);
1208  ge->setColor(val, recursive);
1209  }
1210  }
1211 }
1212 
1213 GMSH_API void gmsh::model::getColor(const int dim, const int tag, int &r,
1214  int &g, int &b, int &a)
1215 {
1216  if(!_checkInit()) return;
1217  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
1218  if(!ge) {
1219  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1220  return;
1221  }
1222  unsigned int value = ge->getColor();
1223  r = CTX::instance()->unpackRed(value);
1224  g = CTX::instance()->unpackGreen(value);
1225  b = CTX::instance()->unpackBlue(value);
1226  a = CTX::instance()->unpackAlpha(value);
1227 }
1228 
1229 GMSH_API void gmsh::model::setCoordinates(const int tag, const double x,
1230  const double y, const double z)
1231 {
1232  if(!_checkInit()) return;
1233  GVertex *gv = GModel::current()->getVertexByTag(tag);
1234  if(!gv) {
1235  Msg::Error("%s does not exist", _getEntityName(0, tag).c_str());
1236  return;
1237  }
1238  GPoint p(x, y, z);
1239  gv->setPosition(p);
1240 }
1241 
1242 GMSH_API void gmsh::model::getAttributeNames(std::vector<std::string> &names)
1243 {
1244  if(!_checkInit()) return;
1245  names.clear();
1246  for(auto a : GModel::current()->getAttributes())
1247  names.push_back(a.first);
1248 }
1249 
1250 GMSH_API void gmsh::model::getAttribute(const std::string &name,
1251  std::vector<std::string> &values)
1252 {
1253  if(!_checkInit()) return;
1254  values = GModel::current()->getAttributes()[name];
1255 }
1256 
1257 GMSH_API void gmsh::model::setAttribute(const std::string &name,
1258  const std::vector<std::string> &values)
1259 {
1260  if(!_checkInit()) return;
1261  GModel::current()->getAttributes()[name] = values;
1262 }
1263 
1264 GMSH_API void gmsh::model::removeAttribute(const std::string &name)
1265 {
1266  if(!_checkInit()) return;
1267  GModel::current()->getAttributes().erase(name);
1268 }
1269 
1270 // gmsh::model::mesh
1271 
1272 GMSH_API void gmsh::model::mesh::generate(const int dim)
1273 {
1274  if(!_checkInit()) return;
1275  GModel::current()->mesh(dim);
1277 }
1278 
1279 GMSH_API void
1280 gmsh::model::mesh::partition(const int numPart,
1281  const std::vector<std::size_t> &elementTags,
1282  const std::vector<int> &partitions)
1283 {
1284  if(!_checkInit()) return;
1285  std::vector<std::pair<MElement *, int> > epart;
1286  if(elementTags.size()) {
1287  if(elementTags.size() != partitions.size()) {
1288  Msg::Error("Number of element tags (%d) does not match number of "
1289  "partitions (%d)",
1290  elementTags.size(), partitions.size());
1291  return;
1292  }
1293  epart.reserve(elementTags.size());
1294  for(std::size_t i = 0; i < elementTags.size(); i++) {
1295  MElement *el = GModel::current()->getMeshElementByTag(elementTags[i]);
1296  if(el)
1297  epart.push_back(std::make_pair(el, partitions[i]));
1298  else
1299  Msg::Error("Unknown element %d", elementTags[i]);
1300  }
1301  }
1303  numPart >= 0 ? numPart : CTX::instance()->mesh.numPartitions, epart);
1305 }
1306 
1307 GMSH_API void gmsh::model::mesh::unpartition()
1308 {
1309  if(!_checkInit()) return;
1312 }
1313 
1314 GMSH_API void gmsh::model::mesh::refine()
1315 {
1316  if(!_checkInit()) return;
1317  GModel::current()->refineMesh(CTX::instance()->mesh.secondOrderLinear,
1320  CTX::instance()->mesh.algoSubdivide == 3);
1322 }
1323 
1324 GMSH_API void gmsh::model::mesh::recombine()
1325 {
1326  if(!_checkInit()) return;
1329 }
1330 
1331 GMSH_API void gmsh::model::mesh::optimize(const std::string &how,
1332  const bool force, const int niter,
1333  const vectorpair &dimTags)
1334 {
1335  if(!_checkInit()) return;
1336  if(dimTags.size()) {
1337  Msg::Warning(
1338  "Optimization of specified model entities is not interfaced yet");
1339  }
1340  GModel::current()->optimizeMesh(how, force, niter);
1342 }
1343 
1344 GMSH_API void gmsh::model::mesh::computeCrossField(std::vector<int> &tags)
1345 {
1346  if(!_checkInit()) return;
1347 #if defined(HAVE_MESH)
1349  Msg::Error("Could not compute cross field");
1350  return;
1351  }
1352 #else
1353  Msg::Error("computeCrossField requires the mesh module");
1354 #endif
1355 }
1356 
1357 GMSH_API void gmsh::model::mesh::splitQuadrangles(const double quality,
1358  const int tag)
1359 {
1360  if(!_checkInit()) return;
1361 #if defined(HAVE_MESH)
1362  std::vector<GEntity *> entities;
1363  if(tag < 0) { GModel::current()->getEntities(entities, 2); }
1364  else {
1365  GEntity *ge = GModel::current()->getEntityByTag(2, tag);
1366  if(!ge) {
1367  Msg::Error("%s does not exist", _getEntityName(2, tag).c_str());
1368  return;
1369  }
1370  entities.push_back(ge);
1371  }
1372  for(std::size_t i = 0; i < entities.size(); i++) {
1373  GFace *gf = static_cast<GFace *>(entities[i]);
1374  quadsToTriangles(gf, quality);
1375  }
1377 #else
1378  Msg::Error("splitQuadrangles requires the mesh module");
1379 #endif
1380 }
1381 
1382 GMSH_API void gmsh::model::mesh::setOrder(const int order)
1383 {
1384  if(!_checkInit()) return;
1385  GModel::current()->setOrderN(order, CTX::instance()->mesh.secondOrderLinear,
1389 }
1390 
1391 GMSH_API void gmsh::model::mesh::getLastEntityError(vectorpair &dimTags)
1392 {
1393  if(!_checkInit()) return;
1394  std::vector<GEntity *> e = GModel::current()->getLastMeshEntityError();
1395  dimTags.clear();
1396  for(std::size_t i = 0; i < e.size(); i++)
1397  dimTags.push_back(std::make_pair(e[i]->dim(), e[i]->tag()));
1398 }
1399 
1400 GMSH_API void
1401 gmsh::model::mesh::getLastNodeError(std::vector<std::size_t> &nodeTags)
1402 {
1403  if(!_checkInit()) return;
1404  std::vector<MVertex *> v = GModel::current()->getLastMeshVertexError();
1405  nodeTags.clear();
1406  for(std::size_t i = 0; i < v.size(); i++) nodeTags.push_back(v[i]->getNum());
1407 }
1408 
1409 GMSH_API void gmsh::model::mesh::clear(const vectorpair &dimTags)
1410 {
1411  if(!_checkInit()) return;
1412  std::vector<GEntity *> entities;
1413  for(std::size_t i = 0; i < dimTags.size(); i++) {
1414  int dim = dimTags[i].first;
1415  int tag = dimTags[i].second;
1416  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
1417  if(!ge) {
1418  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1419  return;
1420  }
1421  entities.push_back(ge);
1422  }
1423  GModel::current()->deleteMesh(entities);
1424 }
1425 
1426 static void _getEntities(const gmsh::vectorpair &dimTags,
1427  std::vector<GEntity *> &entities)
1428 {
1429  if(dimTags.empty()) { GModel::current()->getEntities(entities); }
1430  else {
1431  for(auto dimTag : dimTags) {
1432  int dim = dimTag.first, tag = dimTag.second;
1433  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
1434  if(!ge) {
1435  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1436  return;
1437  }
1438  entities.push_back(ge);
1439  }
1440  }
1441 }
1442 
1443 GMSH_API void gmsh::model::mesh::reverse(const vectorpair &dimTags)
1444 {
1445  if(!_checkInit()) return;
1446  std::vector<GEntity *> entities;
1447  _getEntities(dimTags, entities);
1448  for(auto ge : entities) {
1449  for(std::size_t j = 0; j < ge->getNumMeshElements(); j++) {
1450  ge->getMeshElement(j)->reverse();
1451  }
1452  }
1454 }
1455 
1456 GMSH_API void
1457 gmsh::model::mesh::affineTransform(const std::vector<double> &affineTransform,
1458  const vectorpair &dimTags)
1459 {
1460  if(!_checkInit()) return;
1461  std::vector<GEntity *> entities;
1462  _getEntities(dimTags, entities);
1463  for(auto ge : entities) {
1464  for(std::size_t j = 0; j < ge->getNumMeshVertices(); j++) {
1465  MVertex *v = ge->getMeshVertex(j);
1466  SPoint3 pt = v->point();
1467  if(pt.transform(affineTransform))
1468  v->setXYZ(pt);
1469  else
1470  Msg::Error("Could not transform node %d (%g, %g, %g) on %s",
1471  v->getNum(), v->x(), v->y(), v->z(),
1472  _getEntityName(ge->dim(), ge->tag()).c_str());
1473  }
1474  }
1475 }
1476 
1478  std::vector<std::size_t> &nodeTags,
1479  std::vector<double> &coord,
1480  std::vector<double> &parametricCoord,
1481  bool parametric)
1482 {
1483  std::vector<GFace *> f;
1484  std::vector<GEdge *> e;
1485  std::vector<GVertex *> v;
1486  if(entity->dim() > 2) f = entity->faces();
1487  if(entity->dim() > 1) e = entity->edges();
1488  if(entity->dim() > 0) v = entity->vertices();
1489  for(auto it = f.begin(); it != f.end(); it++) {
1490  GFace *gf = *it;
1491  for(std::size_t j = 0; j < gf->mesh_vertices.size(); j++) {
1492  MVertex *v = gf->mesh_vertices[j];
1493  nodeTags.push_back(v->getNum());
1494  coord.push_back(v->x());
1495  coord.push_back(v->y());
1496  coord.push_back(v->z());
1497  }
1498  }
1499  for(auto it = e.begin(); it != e.end(); it++) {
1500  GEdge *ge = *it;
1501  for(std::size_t j = 0; j < ge->mesh_vertices.size(); j++) {
1502  MVertex *v = ge->mesh_vertices[j];
1503  nodeTags.push_back(v->getNum());
1504  coord.push_back(v->x());
1505  coord.push_back(v->y());
1506  coord.push_back(v->z());
1507  if(entity->dim() == 2 && parametric) {
1508  SPoint2 param;
1509  if(!reparamMeshVertexOnFace(v, (GFace *)entity, param, true, false))
1510  Msg::Warning("Failed to compute parameters of node %d on surface %d",
1511  v->getNum(), entity->tag());
1512  parametricCoord.push_back(param.x());
1513  parametricCoord.push_back(param.y());
1514  }
1515  }
1516  }
1517  for(auto it = v.begin(); it != v.end(); it++) {
1518  GVertex *gv = *it;
1519  for(std::size_t j = 0; j < gv->mesh_vertices.size(); j++) {
1520  MVertex *v = gv->mesh_vertices[j];
1521  nodeTags.push_back(v->getNum());
1522  coord.push_back(v->x());
1523  coord.push_back(v->y());
1524  coord.push_back(v->z());
1525  if(entity->dim() == 2 && parametric) {
1526  SPoint2 param;
1527  if(!reparamMeshVertexOnFace(v, (GFace *)entity, param, true, false))
1528  Msg::Warning("Failed to compute parameters of node %d on surface %d",
1529  v->getNum(), entity->tag());
1530  parametricCoord.push_back(param.x());
1531  parametricCoord.push_back(param.y());
1532  }
1533  else if(entity->dim() == 1 && parametric) {
1534  double param;
1535  if(!reparamMeshVertexOnEdge(v, (GEdge *)entity, param))
1536  Msg::Warning("Failed to compute parameters of node %d on curve %d",
1537  v->getNum(), entity->tag());
1538  parametricCoord.push_back(param);
1539  }
1540  }
1541  }
1542 }
1543 
1544 GMSH_API void gmsh::model::mesh::getNodes(std::vector<std::size_t> &nodeTags,
1545  std::vector<double> &coord,
1546  std::vector<double> &parametricCoord,
1547  const int dim, const int tag,
1548  const bool includeBoundary,
1549  const bool returnParametricCoord)
1550 {
1551  if(!_checkInit()) return;
1552  nodeTags.clear();
1553  coord.clear();
1554  parametricCoord.clear();
1555  std::vector<GEntity *> entities;
1556  if(dim >= 0 && tag >= 0) {
1557  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
1558  if(!ge) {
1559  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1560  return;
1561  }
1562  entities.push_back(ge);
1563  }
1564  else {
1565  GModel::current()->getEntities(entities, dim);
1566  }
1567  for(std::size_t i = 0; i < entities.size(); i++) {
1568  GEntity *ge = entities[i];
1569  for(std::size_t j = 0; j < ge->mesh_vertices.size(); j++) {
1570  MVertex *v = ge->mesh_vertices[j];
1571  nodeTags.push_back(v->getNum());
1572  coord.push_back(v->x());
1573  coord.push_back(v->y());
1574  coord.push_back(v->z());
1575  if(dim > 0 && returnParametricCoord) {
1576  double par;
1577  for(int k = 0; k < dim; k++) {
1578  if(v->getParameter(k, par)) parametricCoord.push_back(par);
1579  }
1580  }
1581  }
1582  if(includeBoundary)
1583  _getAdditionalNodesOnBoundary(ge, nodeTags, coord, parametricCoord,
1584  dim > 0 && returnParametricCoord);
1585  }
1586 }
1587 
1588 GMSH_API void gmsh::model::mesh::getNodesByElementType(
1589  const int elementType, std::vector<std::size_t> &nodeTags,
1590  std::vector<double> &coord, std::vector<double> &parametricCoord,
1591  const int tag, const bool returnParametricCoord)
1592 {
1593  if(!_checkInit()) return;
1594  nodeTags.clear();
1595  coord.clear();
1596  parametricCoord.clear();
1597  std::vector<GEntity *> entities;
1598  int dim = ElementType::getDimension(elementType);
1599  if(dim >= 0 && tag >= 0) {
1600  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
1601  if(!ge) {
1602  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1603  return;
1604  }
1605  entities.push_back(ge);
1606  }
1607  else {
1608  GModel::current()->getEntities(entities, dim);
1609  }
1610 
1611  int familyType = ElementType::getParentType(elementType);
1612  int numNodesByElements = ElementType::getNumVertices(elementType);
1613  std::size_t numElements = 0;
1614  for(std::size_t i = 0; i < entities.size(); ++i) {
1615  numElements += entities[i]->getNumMeshElementsByType(familyType);
1616  }
1617  std::size_t numNodes = numElements * numNodesByElements;
1618 
1619  nodeTags.reserve(numNodes);
1620  coord.reserve(numNodes * 3);
1621  if(returnParametricCoord) { parametricCoord.reserve(numNodes * 3); }
1622 
1623  for(std::size_t i = 0; i < entities.size(); i++) {
1624  GEntity *ge = entities[i];
1625  for(std::size_t j = 0;
1626  j < entities[i]->getNumMeshElementsByType(familyType); j++) {
1627  MElement *e = ge->getMeshElementByType(familyType, j);
1628  for(std::size_t k = 0; k < e->getNumVertices(); ++k) {
1629  MVertex *v = e->getVertex(k);
1630  nodeTags.push_back(v->getNum());
1631  coord.push_back(v->x());
1632  coord.push_back(v->y());
1633  coord.push_back(v->z());
1634  if(dim > 0 && returnParametricCoord) {
1635  double par;
1636  for(int k = 0; k < dim; k++) {
1637  if(v->getParameter(k, par)) parametricCoord.push_back(par);
1638  }
1639  }
1640  }
1641  }
1642  }
1643 }
1644 
1645 GMSH_API void gmsh::model::mesh::getNode(const std::size_t nodeTag,
1646  std::vector<double> &coord,
1647  std::vector<double> &parametricCoord,
1648  int &dim, int &tag)
1649 {
1650  if(!_checkInit()) return;
1651  MVertex *v = GModel::current()->getMeshVertexByTag(nodeTag);
1652  if(!v) {
1653  Msg::Error("Unknown node %d", nodeTag);
1654  return;
1655  }
1656  coord.resize(3);
1657  coord[0] = v->x();
1658  coord[1] = v->y();
1659  coord[2] = v->z();
1660  parametricCoord.reserve(2);
1661  double u;
1662  if(v->getParameter(0, u)) parametricCoord.push_back(u);
1663  if(v->getParameter(1, u)) parametricCoord.push_back(u);
1664  if(v->onWhat()) {
1665  dim = v->onWhat()->dim();
1666  tag = v->onWhat()->tag();
1667  }
1668  else {
1669  Msg::Warning("Node %d is not classified on any entity", nodeTag);
1670  dim = -1;
1671  tag = -1;
1672  }
1673 }
1674 
1675 GMSH_API void
1676 gmsh::model::mesh::setNode(const std::size_t nodeTag,
1677  const std::vector<double> &coord,
1678  const std::vector<double> &parametricCoord)
1679 {
1680  if(!_checkInit()) return;
1681  MVertex *v = GModel::current()->getMeshVertexByTag(nodeTag);
1682  if(!v) {
1683  Msg::Error("Unknown node %d", nodeTag);
1684  return;
1685  }
1686  if(coord.size() < 3) {
1687  Msg::Error("Less than three coordinates provided for node %d", nodeTag);
1688  return;
1689  }
1690  v->setXYZ(coord[0], coord[1], coord[2]);
1691  if(parametricCoord.size() >= 1) v->setParameter(0, parametricCoord[0]);
1692  if(parametricCoord.size() >= 2) v->setParameter(1, parametricCoord[1]);
1693 }
1694 
1695 GMSH_API void gmsh::model::mesh::rebuildNodeCache(bool onlyIfNecessary)
1696 {
1697  if(!_checkInit()) return;
1698  GModel::current()->rebuildMeshVertexCache(onlyIfNecessary);
1699 }
1700 
1701 GMSH_API void gmsh::model::mesh::rebuildElementCache(bool onlyIfNecessary)
1702 {
1703  if(!_checkInit()) return;
1704  GModel::current()->rebuildMeshElementCache(onlyIfNecessary);
1705 }
1706 
1707 GMSH_API void
1708 gmsh::model::mesh::getNodesForPhysicalGroup(const int dim, const int tag,
1709  std::vector<std::size_t> &nodeTags,
1710  std::vector<double> &coord)
1711 {
1712  if(!_checkInit()) return;
1713  nodeTags.clear();
1714  coord.clear();
1715  std::vector<MVertex *> v;
1717  if(v.empty()) return;
1718  nodeTags.resize(v.size());
1719  coord.resize(v.size() * 3);
1720  for(std::size_t i = 0; i < v.size(); i++) {
1721  nodeTags[i] = v[i]->getNum();
1722  coord[3 * i + 0] = v[i]->x();
1723  coord[3 * i + 1] = v[i]->y();
1724  coord[3 * i + 2] = v[i]->z();
1725  }
1726 }
1727 
1728 GMSH_API void gmsh::model::mesh::getMaxNodeTag(std::size_t &maxTag)
1729 {
1730  if(!_checkInit()) return;
1731  maxTag = GModel::current()->getMaxVertexNumber();
1732 }
1733 
1734 GMSH_API void gmsh::model::mesh::addNodes(
1735  const int dim, const int tag, const std::vector<std::size_t> &nodeTags,
1736  const std::vector<double> &coord, const std::vector<double> &parametricCoord)
1737 {
1738  if(!_checkInit()) return;
1739  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
1740  if(!ge) {
1741  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1742  return;
1743  }
1744  int numNodeTags = nodeTags.size(), numNodes = nodeTags.size();
1745  if(!numNodeTags) { // this is allowed: we will assign new tags
1746  numNodes = coord.size() / 3;
1747  }
1748  if((int)coord.size() != 3 * numNodes) {
1749  Msg::Error("Wrong number of coordinates");
1750  return;
1751  }
1752  bool param = false;
1753  if(parametricCoord.size()) {
1754  if((int)parametricCoord.size() != dim * numNodes) {
1755  Msg::Error("Wrong number of parametric coordinates");
1756  return;
1757  }
1758  param = true;
1759  }
1760  for(int i = 0; i < numNodes; i++) {
1761  std::size_t tag = (numNodeTags ? nodeTags[i] : 0); // 0 = automatic tag
1762  double x = coord[3 * i];
1763  double y = coord[3 * i + 1];
1764  double z = coord[3 * i + 2];
1765  MVertex *vv = nullptr;
1766  if(param && dim == 1) {
1767  double u = parametricCoord[i];
1768  vv = new MEdgeVertex(x, y, z, ge, u, tag);
1769  }
1770  else if(param && dim == 2) {
1771  double u = parametricCoord[2 * i];
1772  double v = parametricCoord[2 * i + 1];
1773  vv = new MFaceVertex(x, y, z, ge, u, v, tag);
1774  }
1775  else
1776  vv = new MVertex(x, y, z, ge, tag);
1777  ge->mesh_vertices.push_back(vv);
1778  }
1780 }
1781 
1782 GMSH_API void gmsh::model::mesh::reclassifyNodes()
1783 {
1784  if(!_checkInit()) return;
1786 }
1787 
1788 GMSH_API void gmsh::model::mesh::relocateNodes(const int dim, const int tag)
1789 {
1790  if(!_checkInit()) return;
1791  std::vector<GEntity *> entities;
1792  if(dim >= 0 && tag >= 0) {
1793  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
1794  if(!ge) {
1795  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1796  return;
1797  }
1798  entities.push_back(ge);
1799  }
1800  else {
1801  GModel::current()->getEntities(entities, dim);
1802  }
1803  for(std::size_t i = 0; i < entities.size(); i++)
1804  entities[i]->relocateMeshVertices();
1805 }
1806 
1807 static void
1809  std::map<int, std::vector<GEntity *> > &typeEnt)
1810 {
1811  std::vector<GEntity *> entities;
1812  if(dim >= 0 && tag >= 0) {
1813  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
1814  if(!ge) {
1815  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
1816  return;
1817  }
1818  entities.push_back(ge);
1819  }
1820  else {
1821  GModel::current()->getEntities(entities, dim);
1822  }
1823  for(std::size_t i = 0; i < entities.size(); i++) {
1824  GEntity *ge = entities[i];
1825  switch(ge->dim()) {
1826  case 0: {
1827  GVertex *v = static_cast<GVertex *>(ge);
1828  if(v->points.size())
1829  typeEnt[v->points.front()->getTypeForMSH()].push_back(ge);
1830  break;
1831  }
1832  case 1: {
1833  GEdge *e = static_cast<GEdge *>(ge);
1834  if(e->lines.size())
1835  typeEnt[e->lines.front()->getTypeForMSH()].push_back(ge);
1836  break;
1837  }
1838  case 2: {
1839  GFace *f = static_cast<GFace *>(ge);
1840  if(f->triangles.size())
1841  typeEnt[f->triangles.front()->getTypeForMSH()].push_back(ge);
1842  if(f->quadrangles.size())
1843  typeEnt[f->quadrangles.front()->getTypeForMSH()].push_back(ge);
1844  break;
1845  }
1846  case 3: {
1847  GRegion *r = static_cast<GRegion *>(ge);
1848  if(r->tetrahedra.size())
1849  typeEnt[r->tetrahedra.front()->getTypeForMSH()].push_back(ge);
1850  if(r->hexahedra.size())
1851  typeEnt[r->hexahedra.front()->getTypeForMSH()].push_back(ge);
1852  if(r->prisms.size())
1853  typeEnt[r->prisms.front()->getTypeForMSH()].push_back(ge);
1854  if(r->pyramids.size())
1855  typeEnt[r->pyramids.front()->getTypeForMSH()].push_back(ge);
1856  break;
1857  }
1858  }
1859  }
1860 }
1861 
1862 GMSH_API void gmsh::model::mesh::getElements(
1863  std::vector<int> &elementTypes,
1864  std::vector<std::vector<std::size_t> > &elementTags,
1865  std::vector<std::vector<std::size_t> > &nodeTags, const int dim,
1866  const int tag)
1867 {
1868  if(!_checkInit()) return;
1869  elementTypes.clear();
1870  elementTags.clear();
1871  nodeTags.clear();
1872  std::map<int, std::vector<GEntity *> > typeEnt;
1873  _getEntitiesForElementTypes(dim, tag, typeEnt);
1874  for(auto it = typeEnt.begin(); it != typeEnt.end(); it++) {
1875  elementTypes.push_back(it->first);
1876  elementTags.push_back(std::vector<std::size_t>());
1877  nodeTags.push_back(std::vector<std::size_t>());
1878  int elementType = it->first;
1879  for(std::size_t i = 0; i < it->second.size(); i++) {
1880  GEntity *ge = it->second[i];
1881  for(std::size_t j = 0; j < ge->getNumMeshElements(); j++) {
1882  MElement *e = ge->getMeshElement(j);
1883  if(e->getTypeForMSH() == elementType) {
1884  elementTags.back().push_back(e->getNum());
1885  for(std::size_t k = 0; k < e->getNumVertices(); k++) {
1886  nodeTags.back().push_back(e->getVertex(k)->getNum());
1887  }
1888  }
1889  }
1890  }
1891  }
1892 }
1893 
1894 GMSH_API void gmsh::model::mesh::getElement(const std::size_t elementTag,
1895  int &elementType,
1896  std::vector<std::size_t> &nodeTags,
1897  int &dim, int &tag)
1898 {
1899  if(!_checkInit()) return;
1900  int entityTag;
1901  MElement *e = GModel::current()->getMeshElementByTag(elementTag, entityTag);
1902  if(!e) {
1903  Msg::Error("Unknown element %d", elementTag);
1904  return;
1905  }
1906  elementType = e->getTypeForMSH();
1907  nodeTags.clear();
1908  for(std::size_t i = 0; i < e->getNumVertices(); i++) {
1909  MVertex *v = e->getVertex(i);
1910  if(!v) {
1911  Msg::Error("Unknown node in element %d", elementTag);
1912  return;
1913  }
1914  nodeTags.push_back(v->getNum());
1915  }
1916  dim = e->getDim();
1917  tag = entityTag;
1918 }
1919 
1920 GMSH_API void gmsh::model::mesh::getElementByCoordinates(
1921  const double x, const double y, const double z, std::size_t &elementTag,
1922  int &elementType, std::vector<std::size_t> &nodeTags, double &u, double &v,
1923  double &w, const int dim, const bool strict)
1924 {
1925  if(!_checkInit()) return;
1926  nodeTags.clear();
1927  SPoint3 xyz(x, y, z), uvw;
1928  MElement *e = GModel::current()->getMeshElementByCoord(xyz, uvw, dim, strict);
1929  if(!e) {
1930  elementTag = 0;
1931  elementType = 0;
1932  u = v = w = 0.;
1933  Msg::Error("No element found at (%g, %g, %g)", x, y, z);
1934  return;
1935  }
1936  elementTag = e->getNum();
1937  elementType = e->getTypeForMSH();
1938  for(std::size_t i = 0; i < e->getNumVertices(); i++) {
1939  MVertex *v = e->getVertex(i);
1940  if(!v) {
1941  Msg::Error("Unknown node in element %d", elementTag);
1942  return;
1943  }
1944  nodeTags.push_back(v->getNum());
1945  }
1946  u = uvw.x();
1947  v = uvw.y();
1948  w = uvw.z();
1949 }
1950 
1951 GMSH_API void gmsh::model::mesh::getElementsByCoordinates(
1952  const double x, const double y, const double z,
1953  std::vector<std::size_t> &elementTags, const int dim, const bool strict)
1954 {
1955  if(!_checkInit()) return;
1956  SPoint3 xyz(x, y, z), uvw;
1957  elementTags.clear();
1958  std::vector<MElement *> e =
1959  GModel::current()->getMeshElementsByCoord(xyz, dim, strict);
1960  if(e.empty()) {
1961  Msg::Error("No element found at (%g, %g, %g)", x, y, z);
1962  return;
1963  }
1964  for(std::size_t i = 0; i < e.size(); i++) {
1965  elementTags.push_back(e[i]->getNum());
1966  }
1967 }
1968 
1969 GMSH_API void gmsh::model::mesh::getLocalCoordinatesInElement(
1970  const std::size_t elementTag, const double x, const double y, const double z,
1971  double &u, double &v, double &w)
1972 {
1973  if(!_checkInit()) return;
1974  MElement *e = GModel::current()->getMeshElementByTag(elementTag);
1975  if(!e) {
1976  Msg::Error("Unknown element %d", elementTag);
1977  return;
1978  }
1979  double xyz[3] = {x, y, z}, uvw[3];
1980  e->xyz2uvw(xyz, uvw);
1981  u = uvw[0];
1982  v = uvw[1];
1983  w = uvw[2];
1984 }
1985 
1986 template <class T>
1987 static void _addElements(int dim, int tag, const std::vector<MElement *> &src,
1988  std::vector<T *> &dst)
1989 {
1990  for(std::size_t i = 0; i < src.size(); i++)
1991  dst.push_back(static_cast<T *>(src[i]));
1992 }
1993 
1994 static void _addElements(int dim, int tag, GEntity *ge, int type,
1995  const std::vector<std::size_t> &elementTags,
1996  const std::vector<std::size_t> &nodeTags)
1997 {
1998  unsigned int numNodesPerEle = MElement::getInfoMSH(type);
1999  if(!numNodesPerEle) return;
2000  std::size_t numEleTags = elementTags.size();
2001  std::size_t numEle = numEleTags;
2002  if(!numEle) { numEle = nodeTags.size() / numNodesPerEle; }
2003  if(!numEle) return;
2004  if(numEle * numNodesPerEle != nodeTags.size()) {
2005  Msg::Error("Wrong number of node tags for element type %d", type);
2006  return;
2007  }
2008  std::vector<MElement *> elements(numEle);
2009  std::vector<MVertex *> nodes(numNodesPerEle);
2010  for(std::size_t j = 0; j < numEle; j++) {
2011  std::size_t etag = (numEleTags ? elementTags[j] : 0); // 0 = automatic tag
2013  for(std::size_t k = 0; k < numNodesPerEle; k++) {
2014  std::size_t vtag = nodeTags[numNodesPerEle * j + k];
2015  // this will rebuild the node cache if necessary
2016  nodes[k] = GModel::current()->getMeshVertexByTag(vtag);
2017  if(!nodes[k]) {
2018  Msg::Error("Unknown node %d", vtag);
2019  return;
2020  }
2021  }
2022  elements[j] = f.create(type, nodes, etag);
2023  }
2024  bool ok = true;
2025  switch(dim) {
2026  case 0:
2027  if(elements[0]->getType() == TYPE_PNT)
2028  _addElements(dim, tag, elements, static_cast<GVertex *>(ge)->points);
2029  else
2030  ok = false;
2031  break;
2032  case 1:
2033  if(elements[0]->getType() == TYPE_LIN)
2034  _addElements(dim, tag, elements, static_cast<GEdge *>(ge)->lines);
2035  else
2036  ok = false;
2037  break;
2038  case 2:
2039  if(elements[0]->getType() == TYPE_TRI)
2040  _addElements(dim, tag, elements, static_cast<GFace *>(ge)->triangles);
2041  else if(elements[0]->getType() == TYPE_QUA)
2042  _addElements(dim, tag, elements, static_cast<GFace *>(ge)->quadrangles);
2043  else
2044  ok = false;
2045  break;
2046  case 3:
2047  if(elements[0]->getType() == TYPE_TET)
2048  _addElements(dim, tag, elements, static_cast<GRegion *>(ge)->tetrahedra);
2049  else if(elements[0]->getType() == TYPE_HEX)
2050  _addElements(dim, tag, elements, static_cast<GRegion *>(ge)->hexahedra);
2051  else if(elements[0]->getType() == TYPE_PRI)
2052  _addElements(dim, tag, elements, static_cast<GRegion *>(ge)->prisms);
2053  else if(elements[0]->getType() == TYPE_PYR)
2054  _addElements(dim, tag, elements, static_cast<GRegion *>(ge)->pyramids);
2055  else
2056  ok = false;
2057  break;
2058  }
2059  if(!ok)
2060  Msg::Error("Wrong type of element for %s",
2061  _getEntityName(dim, tag).c_str());
2062 }
2063 
2064 GMSH_API void gmsh::model::mesh::getMaxElementTag(std::size_t &maxTag)
2065 {
2066  if(!_checkInit()) return;
2067  maxTag = GModel::current()->getMaxElementNumber();
2068 }
2069 
2070 GMSH_API void gmsh::model::mesh::addElements(
2071  const int dim, const int tag, const std::vector<int> &elementTypes,
2072  const std::vector<std::vector<std::size_t> > &elementTags,
2073  const std::vector<std::vector<std::size_t> > &nodeTags)
2074 {
2075  if(!_checkInit()) return;
2076  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
2077  if(!ge) {
2078  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
2079  return;
2080  }
2081  if(elementTypes.size() != elementTags.size()) {
2082  Msg::Error("Wrong number of element tags");
2083  return;
2084  }
2085  if(elementTypes.size() != nodeTags.size()) {
2086  Msg::Error("Wrong number of node tags");
2087  return;
2088  }
2089 
2090  for(std::size_t i = 0; i < elementTypes.size(); i++)
2091  _addElements(dim, tag, ge, elementTypes[i], elementTags[i], nodeTags[i]);
2093 }
2094 
2095 GMSH_API void gmsh::model::mesh::addElementsByType(
2096  const int tag, const int elementType,
2097  const std::vector<std::size_t> &elementTags,
2098  const std::vector<std::size_t> &nodeTags)
2099 {
2100  if(!_checkInit()) return;
2101  int dim = ElementType::getDimension(elementType);
2102  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
2103  if(!ge) {
2104  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
2105  return;
2106  }
2107  _addElements(dim, tag, ge, elementType, elementTags, nodeTags);
2109 }
2110 
2111 GMSH_API void gmsh::model::mesh::getElementTypes(std::vector<int> &elementTypes,
2112  const int dim, const int tag)
2113 {
2114  if(!_checkInit()) return;
2115  elementTypes.clear();
2116  std::map<int, std::vector<GEntity *> > typeEnt;
2117  _getEntitiesForElementTypes(dim, tag, typeEnt);
2118  for(auto it = typeEnt.begin(); it != typeEnt.end(); it++) {
2119  elementTypes.push_back(it->first);
2120  }
2121 }
2122 
2123 GMSH_API int gmsh::model::mesh::getElementType(const std::string &family,
2124  const int order,
2125  const bool serendip)
2126 {
2127  if(!_checkInit()) return -1;
2128  int familyType =
2129  (family == "Point" || family == "point") ? TYPE_PNT :
2130  (family == "Line" || family == "line") ? TYPE_LIN :
2131  (family == "Triangle" || family == "triangle") ? TYPE_TRI :
2132  (family == "Quadrangle" || family == "quadrangle") ? TYPE_QUA :
2133  (family == "Tetrahedron" || family == "tetrahedron") ? TYPE_TET :
2134  (family == "Pyramid" || family == "pyramid") ? TYPE_PYR :
2135  (family == "Prism" || family == "prism") ? TYPE_PRI :
2136  (family == "Hexahedron" || family == "hexahedron") ? TYPE_HEX :
2137  (family == "Polygon" || family == "polygon") ? TYPE_POLYG :
2138  (family == "Polyhedron" || family == "polyhedron") ? TYPE_POLYH :
2139  (family == "Trihedron" || family == "trihedron") ? TYPE_TRIH :
2140  -1;
2141  return ElementType::getType(familyType, order, serendip);
2142 }
2143 
2144 GMSH_API void gmsh::model::mesh::getElementProperties(
2145  const int elementType, std::string &name, int &dim, int &order, int &numNodes,
2146  std::vector<double> &localNodeCoord, int &numPrimaryNodes)
2147 {
2148  if(!_checkInit()) return;
2149  const char *n;
2150  MElement::getInfoMSH(elementType, &n);
2151  name = n;
2152  int parentType = ElementType::getParentType(elementType);
2153  nodalBasis *basis = nullptr;
2154  if(parentType == TYPE_PYR)
2155  basis = new pyramidalBasis(elementType);
2156  else
2157  basis = new polynomialBasis(elementType);
2158  dim = basis->dimension;
2159  order = basis->order;
2160  numNodes = basis->points.size1();
2161  if(numNodes != ElementType::getNumVertices(elementType)) {
2162  Msg::Error("Size of basis incompatible with element type");
2163  return;
2164  }
2165  for(int i = 0; i < basis->points.size1(); i++)
2166  for(int j = 0; j < basis->points.size2(); j++)
2167  localNodeCoord.push_back(basis->points(i, j));
2168  delete basis;
2169  numPrimaryNodes =
2171 }
2172 
2173 GMSH_API void gmsh::model::mesh::getElementsByType(
2174  const int elementType, std::vector<std::size_t> &elementTags,
2175  std::vector<std::size_t> &nodeTags, const int tag, const std::size_t task,
2176  const std::size_t numTasks)
2177 {
2178  if(!_checkInit()) return;
2179  int dim = ElementType::getDimension(elementType);
2180  std::map<int, std::vector<GEntity *> > typeEnt;
2181  _getEntitiesForElementTypes(dim, tag, typeEnt);
2182  const std::vector<GEntity *> &entities(typeEnt[elementType]);
2183  int familyType = ElementType::getParentType(elementType);
2184  std::size_t numElements = 0;
2185  for(std::size_t i = 0; i < entities.size(); i++)
2186  numElements += entities[i]->getNumMeshElementsByType(familyType);
2187  const int numNodes = ElementType::getNumVertices(elementType);
2188  if(!numTasks) {
2189  Msg::Error("Number of tasks should be > 0");
2190  return;
2191  }
2192  // check arrays
2193  bool haveElementTags = !elementTags.empty();
2194  bool haveNodeTags = !nodeTags.empty();
2195  if((!haveElementTags && !haveNodeTags) ||
2196  (haveElementTags && (elementTags.size() != numElements)) ||
2197  (haveNodeTags && (nodeTags.size() != numElements * numNodes))) {
2198  if(numTasks > 1)
2199  Msg::Warning("ElementTags and nodeTags should be preallocated "
2200  "if numTasks > 1");
2201  haveElementTags = haveNodeTags = true;
2202  preallocateElementsByType(elementType, haveElementTags, haveNodeTags,
2203  elementTags, nodeTags, tag);
2204  }
2205  const std::size_t begin = (task * numElements) / numTasks;
2206  const std::size_t end = ((task + 1) * numElements) / numTasks;
2207  size_t o = 0;
2208  size_t idx = begin * numNodes;
2209  for(std::size_t i = 0; i < entities.size(); i++) {
2210  GEntity *ge = entities[i];
2211  for(std::size_t j = 0; j < ge->getNumMeshElementsByType(familyType); j++) {
2212  if(o >= begin && o < end) {
2213  MElement *e = ge->getMeshElementByType(familyType, j);
2214  if(haveElementTags) elementTags[o] = e->getNum();
2215  if(haveNodeTags) {
2216  for(std::size_t k = 0; k < e->getNumVertices(); k++) {
2217  nodeTags[idx++] = e->getVertex(k)->getNum();
2218  }
2219  }
2220  }
2221  o++;
2222  }
2223  }
2224 }
2225 
2226 GMSH_API void gmsh::model::mesh::preallocateElementsByType(
2227  const int elementType, const bool elementTag, const bool nodeTag,
2228  std::vector<std::size_t> &elementTags, std::vector<std::size_t> &nodeTags,
2229  const int tag)
2230 {
2231  if(!_checkInit()) return;
2232  int dim = ElementType::getDimension(elementType);
2233  std::map<int, std::vector<GEntity *> > typeEnt;
2234  _getEntitiesForElementTypes(dim, tag, typeEnt);
2235  const std::vector<GEntity *> &entities(typeEnt[elementType]);
2236  int familyType = ElementType::getParentType(elementType);
2237  std::size_t numElements = 0;
2238  for(std::size_t i = 0; i < entities.size(); i++)
2239  numElements += entities[i]->getNumMeshElementsByType(familyType);
2240  const int numNodesPerEle = ElementType::getNumVertices(elementType);
2241  if(!numElements) return;
2242  if(elementTag) {
2243  elementTags.clear();
2244  elementTags.resize(numElements, 0);
2245  }
2246  if(nodeTag) {
2247  nodeTags.clear();
2248  nodeTags.resize(numElements * numNodesPerEle, 0);
2249  }
2250 }
2251 
2252 GMSH_API void gmsh::model::mesh::getElementQualities(
2253  const std::vector<std::size_t> &elementTags,
2254  std::vector<double> &elementQualities, const std::string &qualityName,
2255  const std::size_t task, const std::size_t numTasks)
2256 {
2257  if(!_checkInit()) return;
2258 
2259  if(!numTasks) {
2260  Msg::Error("Number of tasks should be > 0");
2261  return;
2262  }
2263 
2264  std::size_t numElements = elementTags.size();
2265  bool haveElementQualities = elementQualities.size();
2266  if(!haveElementQualities ||
2267  (haveElementQualities && (elementQualities.size() < numElements))) {
2268  if(numTasks > 1)
2269  Msg::Warning("elementQualities should be preallocated "
2270  "if numTasks > 1");
2271  haveElementQualities = true;
2272  elementQualities.clear();
2273  elementQualities.resize(numElements, 0.);
2274  }
2275 
2276  const std::size_t begin = (task * numElements) / numTasks;
2277  const std::size_t end = ((task + 1) * numElements) / numTasks;
2278  for(size_t k = begin; k < end; k++){
2279  MElement *e = GModel::current()->getMeshElementByTag(elementTags[k]);
2280  if(!e) {
2281  Msg::Error("Unknown element %d", elementTags[k]);
2282  elementQualities[k] = 0.;
2283  continue;
2284  }
2285  if(qualityName == "minSICN"){
2286  elementQualities[k] = e->minSICNShapeMeasure();
2287  }
2288  else if(qualityName == "minSIGE"){
2289  elementQualities[k] = e->minSIGEShapeMeasure();
2290  }
2291  else if(qualityName == "minSJ"){
2292  elementQualities[k] = e->distoShapeMeasure();
2293  }
2294  else if(qualityName == "gamma"){
2295  elementQualities[k] = e->gammaShapeMeasure();
2296  }
2297  else if(qualityName == "eta"){
2298  elementQualities[k] = e->etaShapeMeasure();
2299  }
2300  else if(qualityName == "minIsotropy"){
2301  elementQualities[k] = e->minIsotropyMeasure();
2302  }
2303  else if(qualityName == "angleShape"){
2304  elementQualities[k] = e->angleShapeMeasure();
2305  }
2306  else if(qualityName == "volume"){
2307  elementQualities[k] = e->getVolume();
2308  }
2309  else{
2310  if(k == begin) {
2311  Msg::Error("Unknown quality name '%s'", qualityName.c_str());
2312  }
2313  elementQualities[k] = 0.;
2314  }
2315  }
2316 }
2317 
2318 static bool _getFunctionSpaceInfo(const std::string &fsType,
2319  std::string &fsName, int &fsOrder,
2320  int &fsComp)
2321 {
2322  if(fsType.empty() || fsType == "None") {
2323  fsName = "";
2324  fsOrder = 0;
2325  fsComp = 0;
2326  return true;
2327  }
2328  if(fsType.size() > 8 && fsType.substr(0,8) == "Lagrange") {
2329  fsName = "Lagrange";
2330  fsOrder = atoi(fsType.substr(8).c_str());
2331  fsComp = 1;
2332  return true;
2333  }
2334  if(fsType.size() > 12 && fsType.substr(0,12) == "GradLagrange") {
2335  fsName = "GradLagrange";
2336  fsOrder = atoi(fsType.substr(12).c_str());
2337  fsComp = 3;
2338  return true;
2339  }
2340  if(fsType == "IsoParametric" || fsType == "Lagrange") {
2341  fsName = "Lagrange";
2342  fsOrder = -1;
2343  fsComp = 1;
2344  return true;
2345  }
2346  if(fsType == "GradIsoParametric" || fsType == "GradLagrange") {
2347  fsName = "GradLagrange";
2348  fsOrder = -1;
2349  fsComp = 3;
2350  return true;
2351  }
2352  if(fsType.substr(0, 10) == "H1Legendre") {
2353  fsName = "H1Legendre";
2354  fsOrder = atoi(fsType.substr(10).c_str());
2355  fsComp = 1;
2356  return true;
2357  }
2358  if(fsType.substr(0, 14) == "GradH1Legendre") {
2359  fsName = "GradH1Legendre";
2360  fsOrder = atoi(fsType.substr(14).c_str());
2361  fsComp = 3;
2362  return true;
2363  }
2364  if(fsType.substr(0, 13) == "HcurlLegendre") {
2365  fsName = "HcurlLegendre";
2366  fsOrder = atoi(fsType.substr(13).c_str());
2367  fsComp = 3;
2368  return true;
2369  }
2370  if(fsType.substr(0, 17) == "CurlHcurlLegendre") {
2371  fsName = "CurlHcurlLegendre";
2372  fsOrder = atoi(fsType.substr(17).c_str());
2373  fsComp = 3;
2374  return true;
2375  }
2376  return false;
2377 }
2378 
2379 GMSH_API void gmsh::model::mesh::getJacobians(
2380  const int elementType, const std::vector<double> &localCoord,
2381  std::vector<double> &jacobians, std::vector<double> &determinants,
2382  std::vector<double> &coord, const int tag, const std::size_t task,
2383  const std::size_t numTasks)
2384 {
2385  if(!_checkInit()) return;
2386  int numPoints = localCoord.size() / 3;
2387  if(!numPoints) {
2388  Msg::Warning("No evaluation points in getJacobians");
2389  return;
2390  }
2391  int dim = ElementType::getDimension(elementType);
2392  std::map<int, std::vector<GEntity *> > typeEnt;
2393  _getEntitiesForElementTypes(dim, tag, typeEnt);
2394  const std::vector<GEntity *> &entities(typeEnt[elementType]);
2395  int familyType = ElementType::getParentType(elementType);
2396  std::size_t numElements = 0;
2397  for(std::size_t i = 0; i < entities.size(); i++) {
2398  GEntity *ge = entities[i];
2399  numElements += ge->getNumMeshElementsByType(familyType);
2400  }
2401  if(!numTasks) {
2402  Msg::Error("Number of tasks should be > 0");
2403  return;
2404  }
2405 
2406  // check arrays
2407  bool haveJacobians = !jacobians.empty();
2408  bool haveDeterminants = !determinants.empty();
2409  bool havePoints = !coord.empty();
2410  if((!haveDeterminants && !haveJacobians && !havePoints) ||
2411  (haveDeterminants && (numElements * numPoints != determinants.size())) ||
2412  (haveJacobians && (9 * numElements * numPoints != jacobians.size())) ||
2413  (havePoints && (3 * numElements * numPoints > coord.size()))) {
2414  if(numTasks > 1)
2415  Msg::Warning("Jacobians, determinants and points should be preallocated "
2416  "if numTasks > 1");
2417  haveJacobians = haveDeterminants = havePoints = true;
2418  preallocateJacobians(elementType, numPoints, haveJacobians,
2419  haveDeterminants, havePoints, jacobians, determinants,
2420  coord, tag);
2421  }
2422  // get data
2423  {
2424  const size_t begin = (task * numElements) / numTasks;
2425  const size_t end = ((task + 1) * numElements) / numTasks;
2426  if(haveDeterminants && haveJacobians && havePoints) {
2427  std::vector<std::vector<SVector3> > gsf;
2428  size_t o = 0;
2429  size_t idx = begin * numPoints;
2430  for(std::size_t i = 0; i < entities.size(); i++) {
2431  GEntity *ge = entities[i];
2432  for(std::size_t j = 0; j < ge->getNumMeshElementsByType(familyType);
2433  j++) {
2434  if(o >= begin && o < end) {
2435  MElement *e = ge->getMeshElementByType(familyType, j);
2436  if(gsf.size() == 0) {
2437  gsf.resize(numPoints);
2438  for(int k = 0; k < numPoints; k++) {
2439  double value[1256][3];
2440  e->getGradShapeFunctions(localCoord[3 * k],
2441  localCoord[3 * k + 1],
2442  localCoord[3 * k + 2], value);
2443  gsf[k].resize(e->getNumShapeFunctions());
2444  for(std::size_t l = 0; l < e->getNumShapeFunctions(); l++) {
2445  gsf[k][l][0] = value[l][0];
2446  gsf[k][l][1] = value[l][1];
2447  gsf[k][l][2] = value[l][2];
2448  }
2449  }
2450  }
2451  for(int k = 0; k < numPoints; k++) {
2452  e->pnt(localCoord[3 * k], localCoord[3 * k + 1],
2453  localCoord[3 * k + 2], &coord[idx * 3]);
2454  determinants[idx] = e->getJacobian(gsf[k], &jacobians[idx * 9]);
2455  idx++;
2456  }
2457  }
2458  o++;
2459  }
2460  }
2461  }
2462  else if(haveDeterminants && haveJacobians && !havePoints) {
2463  std::vector<std::vector<SVector3> > gsf;
2464  size_t o = 0;
2465  size_t idx = begin * numPoints;
2466  for(std::size_t i = 0; i < entities.size(); i++) {
2467  GEntity *ge = entities[i];
2468  for(std::size_t j = 0; j < ge->getNumMeshElementsByType(familyType);
2469  j++) {
2470  if(o >= begin && o < end) {
2471  MElement *e = ge->getMeshElementByType(familyType, j);
2472  if(gsf.size() == 0) {
2473  gsf.resize(numPoints);
2474  for(int k = 0; k < numPoints; k++) {
2475  double value[1256][3];
2476  e->getGradShapeFunctions(localCoord[3 * k],
2477  localCoord[3 * k + 1],
2478  localCoord[3 * k + 2], value);
2479  gsf[k].resize(e->getNumShapeFunctions());
2480  for(std::size_t l = 0; l < e->getNumShapeFunctions(); l++) {
2481  gsf[k][l][0] = value[l][0];
2482  gsf[k][l][1] = value[l][1];
2483  gsf[k][l][2] = value[l][2];
2484  }
2485  }
2486  }
2487  for(int k = 0; k < numPoints; k++) {
2488  determinants[idx] = e->getJacobian(gsf[k], &jacobians[idx * 9]);
2489  idx++;
2490  }
2491  }
2492  o++;
2493  }
2494  }
2495  }
2496  else if(haveDeterminants && !haveJacobians && havePoints) {
2497  std::vector<double> jac(9, 0.);
2498  std::vector<std::vector<SVector3> > gsf;
2499  size_t o = 0;
2500  size_t idx = begin * numPoints;
2501  for(std::size_t i = 0; i < entities.size(); i++) {
2502  GEntity *ge = entities[i];
2503  for(std::size_t j = 0; j < ge->getNumMeshElementsByType(familyType);
2504  j++) {
2505  if(o >= begin && o < end) {
2506  MElement *e = ge->getMeshElementByType(familyType, j);
2507  if(gsf.size() == 0) {
2508  gsf.resize(numPoints);
2509  for(int k = 0; k < numPoints; k++) {
2510  double value[1256][3];
2511  e->getGradShapeFunctions(localCoord[3 * k],
2512  localCoord[3 * k + 1],
2513  localCoord[3 * k + 2], value);
2514  gsf[k].resize(e->getNumShapeFunctions());
2515  for(std::size_t l = 0; l < e->getNumShapeFunctions(); l++) {
2516  gsf[k][l][0] = value[l][0];
2517  gsf[k][l][1] = value[l][1];
2518  gsf[k][l][2] = value[l][2];
2519  }
2520  }
2521  }
2522  for(int k = 0; k < numPoints; k++) {
2523  e->pnt(localCoord[3 * k], localCoord[3 * k + 1],
2524  localCoord[3 * k + 2], &coord[idx * 3]);
2525  determinants[idx] = e->getJacobian(gsf[k], &jac[0]);
2526  idx++;
2527  }
2528  }
2529  o++;
2530  }
2531  }
2532  }
2533  else if(haveDeterminants && !haveJacobians && !havePoints) {
2534  std::vector<double> jac(9, 0.);
2535  std::vector<std::vector<SVector3> > gsf;
2536  size_t o = 0;
2537  size_t idx = begin * numPoints;
2538  for(std::size_t i = 0; i < entities.size(); i++) {
2539  GEntity *ge = entities[i];
2540  for(std::size_t j = 0; j < ge->getNumMeshElementsByType(familyType);
2541  j++) {
2542  if(o >= begin && o < end) {
2543  MElement *e = ge->getMeshElementByType(familyType, j);
2544  if(gsf.size() == 0) {
2545  gsf.resize(numPoints);
2546  for(int k = 0; k < numPoints; k++) {
2547  double value[1256][3];
2548  e->getGradShapeFunctions(localCoord[3 * k],
2549  localCoord[3 * k + 1],
2550  localCoord[3 * k + 2], value);
2551  gsf[k].resize(e->getNumShapeFunctions());
2552  for(std::size_t l = 0; l < e->getNumShapeFunctions(); l++) {
2553  gsf[k][l][0] = value[l][0];
2554  gsf[k][l][1] = value[l][1];
2555  gsf[k][l][2] = value[l][2];
2556  }
2557  }
2558  }
2559  for(int k = 0; k < numPoints; k++) {
2560  determinants[idx] = e->getJacobian(gsf[k], &jac[0]);
2561  idx++;
2562  }
2563  }
2564  o++;
2565  }
2566  }
2567  }
2568  else if(!haveDeterminants && haveJacobians && !havePoints) {
2569  std::vector<std::vector<SVector3> > gsf;
2570  size_t o = 0;
2571  size_t idx = begin * numPoints;
2572  for(std::size_t i = 0; i < entities.size(); i++) {
2573  GEntity *ge = entities[i];
2574  for(std::size_t j = 0; j < ge->getNumMeshElementsByType(familyType);
2575  j++) {
2576  if(o >= begin && o < end) {
2577  MElement *e = ge->getMeshElementByType(familyType, j);
2578  if(gsf.size() == 0) {
2579  gsf.resize(numPoints);
2580  for(int k = 0; k < numPoints; k++) {
2581  double value[1256][3];
2582  e->getGradShapeFunctions(localCoord[3 * k],
2583  localCoord[3 * k + 1],
2584  localCoord[3 * k + 2], value);
2585  gsf[k].resize(e->getNumShapeFunctions());
2586  for(std::size_t l = 0; l < e->getNumShapeFunctions(); l++) {
2587  gsf[k][l][0] = value[l][0];
2588  gsf[k][l][1] = value[l][1];
2589  gsf[k][l][2] = value[l][2];
2590  }
2591  }
2592  }
2593  for(int k = 0; k < numPoints; k++) {
2594  e->getJacobian(gsf[k], &jacobians[idx * 9]);
2595  idx++;
2596  }
2597  }
2598  o++;
2599  }
2600  }
2601  }
2602  else {
2603  Msg::Error("The case with 'haveDeterminants = %s', `haveJacobians = %s` "
2604  "and 'havePoints = %s' is not yet implemented",
2605  (haveDeterminants ? "true" : "false"),
2606  (haveJacobians ? "true" : "false"),
2607  (havePoints ? "true" : "false"));
2608  return;
2609  }
2610  // Add other combinaisons if necessary
2611  }
2612 }
2613 
2614 GMSH_API void gmsh::model::mesh::preallocateJacobians(
2615  const int elementType, const int numPoints, const bool allocateJacobians,
2616  const bool allocateDeterminants, const bool allocateCoord,
2617  std::vector<double> &jacobians, std::vector<double> &determinants,
2618  std::vector<double> &coord, const int tag)
2619 {
2620  if(!_checkInit()) return;
2621  int dim = ElementType::getDimension(elementType);
2622  BasisFactory::getNodalBasis(elementType);
2623  std::map<int, std::vector<GEntity *> > typeEnt;
2624  _getEntitiesForElementTypes(dim, tag, typeEnt);
2625  const std::vector<GEntity *> &entities(typeEnt[elementType]);
2626  int familyType = ElementType::getParentType(elementType);
2627  std::size_t numElements = 0;
2628  for(std::size_t i = 0; i < entities.size(); i++)
2629  numElements += entities[i]->getNumMeshElementsByType(familyType);
2630  if(!numElements) return;
2631  if(allocateJacobians) {
2632  jacobians.clear();
2633  jacobians.resize(9 * numElements * numPoints);
2634  }
2635  if(allocateDeterminants) {
2636  determinants.clear();
2637  determinants.resize(numElements * numPoints);
2638  }
2639  if(allocateCoord) {
2640  coord.clear();
2641  coord.resize(3 * numElements * numPoints);
2642  }
2643 }
2644 
2645 GMSH_API void gmsh::model::mesh::getJacobian(
2646  const std::size_t elementTag, const std::vector<double> &localCoord,
2647  std::vector<double> &jacobians, std::vector<double> &determinants,
2648  std::vector<double> &coord)
2649 {
2650  if(!_checkInit()) return;
2651  MElement *e = GModel::current()->getMeshElementByTag(elementTag);
2652  if(!e) {
2653  Msg::Error("Unknown element %d", elementTag);
2654  return;
2655  }
2656  int numPoints = localCoord.size() / 3;
2657  if(!numPoints) {
2658  Msg::Warning("No evaluation points in getJacobian");
2659  return;
2660  }
2661  std::vector<std::vector<SVector3> > gsf;
2662  gsf.resize(numPoints);
2663  jacobians.resize(9 * numPoints);
2664  determinants.resize(numPoints);
2665  coord.resize(3 * numPoints);
2666  for(int k = 0; k < numPoints; k++) {
2667  double value[1256][3];
2668  e->getGradShapeFunctions(localCoord[3 * k], localCoord[3 * k + 1],
2669  localCoord[3 * k + 2], value);
2670  gsf[k].resize(e->getNumShapeFunctions());
2671  for(std::size_t l = 0; l < e->getNumShapeFunctions(); l++) {
2672  gsf[k][l][0] = value[l][0];
2673  gsf[k][l][1] = value[l][1];
2674  gsf[k][l][2] = value[l][2];
2675  }
2676  }
2677  for(int k = 0; k < numPoints; k++) {
2678  e->pnt(localCoord[3 * k], localCoord[3 * k + 1], localCoord[3 * k + 2],
2679  &coord[3 * k]);
2680  determinants[k] = e->getJacobian(gsf[k], &jacobians[9 * k]);
2681  }
2682 }
2683 
2684 GMSH_API void gmsh::model::mesh::getBasisFunctions(
2685  const int elementType, const std::vector<double> &localCoord,
2686  const std::string &functionSpaceType, int &numComponents,
2687  std::vector<double> &basisFunctions, int &numOrientations,
2688  const std::vector<int> &wantedOrientations)
2689 {
2690  if(!_checkInit()) return;
2691  numComponents = 0;
2692  basisFunctions.clear();
2693  std::string fsName = "";
2694  int fsOrder = 0;
2695  if(!_getFunctionSpaceInfo(functionSpaceType, fsName, fsOrder,
2696  numComponents)) {
2697  Msg::Error("Unknown function space type '%s'", functionSpaceType.c_str());
2698  return;
2699  }
2700 
2701  const std::size_t numberOfGaussPoints = localCoord.size() / 3;
2702  const int familyType = ElementType::getParentType(elementType);
2703 
2704  if(fsName == "Lagrange" || fsName == "GradLagrange") { // Lagrange type
2705  // Check if there is no error in wantedOrientations
2706  if(wantedOrientations.size() != 0) {
2707  if(wantedOrientations.size() > 1) {
2708  Msg::Error("Asking for more orientation that there exist");
2709  return;
2710  }
2711 
2712  if(wantedOrientations[0] != 0) {
2713  Msg::Error(
2714  "Orientation %i does not exist for function stace named '%s' on %s",
2715  wantedOrientations[0], fsName.c_str(),
2716  ElementType::nameOfParentType(familyType, true).c_str());
2717  return;
2718  }
2719  }
2720 
2721  const nodalBasis *basis = nullptr;
2722  if(numComponents) {
2723  if(fsOrder == -1) { // isoparametric
2724  basis = BasisFactory::getNodalBasis(elementType);
2725  }
2726  else {
2727  int newType = ElementType::getType(familyType, fsOrder, false);
2728  basis = BasisFactory::getNodalBasis(newType);
2729  }
2730  }
2731  if(basis) {
2732  const std::size_t n = basis->getNumShapeFunctions();
2733  basisFunctions.resize(n * numComponents * numberOfGaussPoints, 0.);
2734  double s[1256], ds[1256][3];
2735  for(std::size_t i = 0; i < numberOfGaussPoints; i++) {
2736  double u = localCoord[i * 3];
2737  double v = localCoord[i * 3 + 1];
2738  double w = localCoord[i * 3 + 2];
2739  switch(numComponents) {
2740  case 1:
2741  basis->f(u, v, w, s);
2742  for(std::size_t j = 0; j < n; j++) basisFunctions[n * i + j] = s[j];
2743  break;
2744  case 3:
2745  basis->df(u, v, w, ds);
2746  for(std::size_t j = 0; j < n; j++) {
2747  basisFunctions[n * 3 * i + 3 * j] = ds[j][0];
2748  basisFunctions[n * 3 * i + 3 * j + 1] = ds[j][1];
2749  basisFunctions[n * 3 * i + 3 * j + 2] = ds[j][2];
2750  }
2751  break;
2752  }
2753  }
2754  }
2755  numOrientations = 1;
2756  }
2757  else { // Hierarchical type
2758  HierarchicalBasis *basis(nullptr);
2759  if(fsName == "H1Legendre" || fsName == "GradH1Legendre") {
2760  switch(familyType) {
2761  case TYPE_HEX: {
2762  basis = new HierarchicalBasisH1Brick(fsOrder);
2763  } break;
2764  case TYPE_PRI: {
2765  basis = new HierarchicalBasisH1Pri(fsOrder);
2766  } break;
2767  case TYPE_TET: {
2768  basis = new HierarchicalBasisH1Tetra(fsOrder);
2769  } break;
2770  case TYPE_QUA: {
2771  basis = new HierarchicalBasisH1Quad(fsOrder);
2772  } break;
2773  case TYPE_TRI: {
2774  basis = new HierarchicalBasisH1Tria(fsOrder);
2775  } break;
2776  case TYPE_LIN: {
2777  basis = new HierarchicalBasisH1Line(fsOrder);
2778  } break;
2779  case TYPE_PNT: {
2780  basis = new HierarchicalBasisH1Point();
2781  } break;
2782  default:
2783  Msg::Error("Unknown familyType %i for basis function type %s",
2784  familyType, fsName.c_str());
2785  return;
2786  }
2787  }
2788  else if(fsName == "HcurlLegendre" || fsName == "CurlHcurlLegendre") {
2789  switch(familyType) {
2790  case TYPE_QUA: {
2791  basis = new HierarchicalBasisHcurlQuad(fsOrder);
2792  } break;
2793  case TYPE_HEX: {
2794  basis = new HierarchicalBasisHcurlBrick(fsOrder);
2795  } break;
2796  case TYPE_TRI: {
2797  basis = new HierarchicalBasisHcurlTria(fsOrder);
2798  } break;
2799  case TYPE_TET: {
2800  basis = new HierarchicalBasisHcurlTetra(fsOrder);
2801  } break;
2802  case TYPE_PRI: {
2803  basis = new HierarchicalBasisHcurlPri(fsOrder);
2804  } break;
2805  case TYPE_LIN: {
2806  basis = new HierarchicalBasisHcurlLine(fsOrder);
2807  } break;
2808  default:
2809  Msg::Error("Unknown familyType %i for basis function type %s",
2810  familyType, fsName.c_str());
2811  return;
2812  }
2813  }
2814  else {
2815  Msg::Error("Unknown function space named '%s'", fsName.c_str());
2816  return;
2817  }
2818 
2819  const std::size_t vSize = basis->getnVertexFunction();
2820  const std::size_t bSize = basis->getnBubbleFunction();
2821  const std::size_t eSize = basis->getnEdgeFunction();
2822  const std::size_t fSize =
2823  basis->getnTriFaceFunction() + basis->getnQuadFaceFunction();
2824  const std::size_t maxOrientation = basis->getNumberOfOrientations();
2825  numOrientations = maxOrientation;
2826  const std::size_t numFunctionsPerElement = vSize + bSize + eSize + fSize;
2827  const unsigned int numVertices =
2828  ElementType::getNumVertices(ElementType::getType(familyType, 1, false));
2829 
2830  basisFunctions.resize(
2831  (wantedOrientations.size() == 0 ? maxOrientation :
2832  wantedOrientations.size()) *
2833  numberOfGaussPoints * numFunctionsPerElement * numComponents);
2834 
2835  // Check if there is no error in wantedOrientations
2836  if(wantedOrientations.size() != 0) {
2837  if(wantedOrientations.size() > maxOrientation) {
2838  Msg::Error("Asking for more orientation that there exist");
2839  return;
2840  }
2841  for(unsigned int i = 0; i < wantedOrientations.size(); ++i) {
2842  if(wantedOrientations[i] >= static_cast<int>(maxOrientation) ||
2843  wantedOrientations[i] < 0) {
2844  Msg::Error("Orientation %i does not exist for function stace named "
2845  "'%s' on %s",
2846  wantedOrientations[i], fsName.c_str(),
2847  ElementType::nameOfParentType(familyType, true).c_str());
2848  return;
2849  }
2850  }
2851  std::vector<int> sortedWantedOrientations = wantedOrientations;
2852  std::sort(sortedWantedOrientations.begin(),
2853  sortedWantedOrientations.end());
2854  int previousInt = sortedWantedOrientations[0];
2855  for(unsigned int i = 1; i < sortedWantedOrientations.size(); ++i) {
2856  if(previousInt == sortedWantedOrientations[i]) {
2857  Msg::Error("Duplicate wanted orientation found");
2858  return;
2859  }
2860  previousInt = sortedWantedOrientations[i];
2861  }
2862  }
2863 
2864  std::vector<MVertex *> vertices(numVertices);
2865  for(unsigned int i = 0; i < numVertices; ++i) {
2866  vertices[i] = new MVertex(0., 0., 0., nullptr, i + 1);
2867  }
2868  MElement *element = nullptr;
2869  switch(familyType) {
2870  case TYPE_HEX: {
2871  element = new MHexahedron(vertices);
2872  } break;
2873  case TYPE_PRI: {
2874  element = new MPrism(vertices);
2875  } break;
2876  case TYPE_TET: {
2877  element = new MTetrahedron(vertices);
2878  } break;
2879  case TYPE_QUA: {
2880  element = new MQuadrangle(vertices);
2881  } break;
2882  case TYPE_TRI: {
2883  element = new MTriangle(vertices);
2884  } break;
2885  case TYPE_LIN: {
2886  element = new MLine(vertices);
2887  } break;
2888  case TYPE_PNT: {
2889  element = new MPoint(vertices);
2890  } break;
2891  default:
2892  Msg::Error("Unknown familyType %i for basis function type %s", familyType,
2893  fsName.c_str());
2894  return;
2895  }
2896 
2897  switch(numComponents) {
2898  case 1: {
2899  std::vector<std::vector<double> > vTable(
2900  numberOfGaussPoints,
2901  std::vector<double>(vSize)); // Vertex functions of one element
2902  std::vector<std::vector<double> > bTable(
2903  numberOfGaussPoints,
2904  std::vector<double>(bSize)); // bubble functions of one element
2905  std::vector<std::vector<double> > fTable(
2906  numberOfGaussPoints,
2907  std::vector<double>(fSize)); // face functions of one element
2908  std::vector<std::vector<double> > eTable(
2909  numberOfGaussPoints,
2910  std::vector<double>(eSize)); // edge functions of one element
2911 
2912  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
2913  const double u = localCoord[3 * q];
2914  const double v = localCoord[3 * q + 1];
2915  const double w = localCoord[3 * q + 2];
2916 
2917  basis->generateBasis(u, v, w, vTable[q], eTable[q], fTable[q],
2918  bTable[q]);
2919  }
2920  // compute only one time the value of the edge basis functions for
2921  // each possible orientations
2922  std::vector<std::vector<double> > eTableNegativeFlag(eTable);
2923  if(eSize != 0) {
2924  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
2925  basis->orientEdgeFunctionsForNegativeFlag(eTableNegativeFlag[q]);
2926  }
2927  }
2928 
2929  // compute only one time the value of the face basis functions for
2930  // each possible orientations
2931  std::vector<std::vector<double> > quadFaceFunctionsAllOrientations(
2932  numberOfGaussPoints,
2933  std::vector<double>(basis->getnQuadFaceFunction() * 8, 0));
2934  std::vector<std::vector<double> > triFaceFunctionsAllOrientations(
2935  numberOfGaussPoints,
2936  std::vector<double>(basis->getnTriFaceFunction() * 6, 0));
2937  if(fSize != 0) {
2938  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
2939  const double u = localCoord[3 * q];
2940  const double v = localCoord[3 * q + 1];
2941  const double w = localCoord[3 * q + 2];
2942 
2943  basis->addAllOrientedFaceFunctions(
2944  u, v, w, fTable[q], quadFaceFunctionsAllOrientations[q],
2945  triFaceFunctionsAllOrientations[q]);
2946  }
2947  }
2948 
2949  std::vector<std::vector<double> > eTableCopy(
2950  numberOfGaussPoints,
2951  std::vector<double>(eSize, 0)); // use eTableCopy to orient the edges
2952  std::vector<std::vector<double> > fTableCopy(
2953  numberOfGaussPoints,
2954  std::vector<double>(fSize, 0)); // use fTableCopy to orient the faces
2955 
2956  unsigned int iOrientationIndex = 0;
2957  for(unsigned int iOrientation = 0; iOrientation < maxOrientation;
2958  ++iOrientation) {
2959  if(wantedOrientations.size() != 0) {
2960  auto it = std::find(wantedOrientations.begin(),
2961  wantedOrientations.end(), iOrientation);
2962  if(it != wantedOrientations.end()) {
2963  iOrientationIndex = &(*it) - &wantedOrientations[0];
2964  }
2965  else {
2966  MVertexPtrLessThan comp;
2967  std::next_permutation(vertices.begin(), vertices.end(), comp);
2968  for(unsigned int i = 0; i < numVertices; ++i) {
2969  element->setVertex(i, vertices[i]);
2970  }
2971  continue;
2972  }
2973  }
2974  else {
2975  iOrientationIndex = iOrientation;
2976  }
2977 
2978  if(eSize != 0) {
2979  for(int iEdge = 0; iEdge < basis->getNumEdge(); ++iEdge) {
2980  MEdge edge = element->getEdge(iEdge);
2981  MEdge edgeSolin = element->getEdgeSolin(iEdge);
2982  const int orientationFlag =
2983  (edge.getMinVertex() != edgeSolin.getVertex(0)) ? -1 : 1;
2984  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
2985  basis->orientEdge(orientationFlag, iEdge, eTableCopy[q],
2986  eTable[q], eTableNegativeFlag[q]);
2987  }
2988  }
2989  }
2990 
2991  if(fSize != 0) {
2992  for(int iFace = 0;
2993  iFace < basis->getNumTriFace() + basis->getNumQuadFace();
2994  ++iFace) {
2995  MFace face = element->getFaceSolin(iFace);
2996  std::vector<int> faceOrientationFlag(3);
2997  face.getOrientationFlagForFace(faceOrientationFlag);
2998  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
2999  basis->orientFace(faceOrientationFlag[0], faceOrientationFlag[1],
3000  faceOrientationFlag[2], iFace,
3001  quadFaceFunctionsAllOrientations[q],
3002  triFaceFunctionsAllOrientations[q],
3003  fTableCopy[q]);
3004  }
3005  }
3006  }
3007 
3008  const std::size_t offsetOrientation =
3009  iOrientationIndex * numberOfGaussPoints * numFunctionsPerElement;
3010  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
3011  const std::size_t offsetGP = q * numFunctionsPerElement;
3012 
3013  for(unsigned int i = 0; i < vSize; ++i) {
3014  basisFunctions[offsetOrientation + offsetGP + i] = vTable[q][i];
3015  }
3016  unsigned int offset = vSize;
3017  for(unsigned int i = 0; i < eSize; ++i) {
3018  basisFunctions[offsetOrientation + offsetGP + offset + i] =
3019  eTableCopy[q][i];
3020  }
3021  offset += eSize;
3022  for(unsigned int i = 0; i < fSize; ++i) {
3023  basisFunctions[offsetOrientation + offsetGP + offset + i] =
3024  fTableCopy[q][i];
3025  }
3026  offset += fSize;
3027  for(unsigned int i = 0; i < bSize; ++i) {
3028  basisFunctions[offsetOrientation + offsetGP + offset + i] =
3029  bTable[q][i];
3030  }
3031  }
3032 
3033  MVertexPtrLessThan comp;
3034  std::next_permutation(vertices.begin(), vertices.end(), comp);
3035  for(unsigned int i = 0; i < numVertices; ++i) {
3036  element->setVertex(i, vertices[i]);
3037  }
3038  }
3039  break;
3040  }
3041  case 3: {
3042  std::vector<std::vector<std::vector<double> > > vTable(
3043  numberOfGaussPoints,
3044  std::vector<std::vector<double> >(
3045  vSize,
3046  std::vector<double>(3, 0.))); // Vertex functions of one element
3047  std::vector<std::vector<std::vector<double> > > bTable(
3048  numberOfGaussPoints,
3049  std::vector<std::vector<double> >(
3050  bSize,
3051  std::vector<double>(3, 0.))); // bubble functions of one element
3052  std::vector<std::vector<std::vector<double> > > fTable(
3053  numberOfGaussPoints,
3054  std::vector<std::vector<double> >(
3055  fSize, std::vector<double>(3, 0.))); // face functions of one element
3056  std::vector<std::vector<std::vector<double> > > eTable(
3057  numberOfGaussPoints,
3058  std::vector<std::vector<double> >(
3059  eSize, std::vector<double>(3, 0.))); // edge functions of one element
3060 
3061  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
3062  const double u = localCoord[3 * q];
3063  const double v = localCoord[3 * q + 1];
3064  const double w = localCoord[3 * q + 2];
3065 
3066  basis->generateBasis(u, v, w, vTable[q], eTable[q], fTable[q],
3067  bTable[q], fsName);
3068  }
3069  // compute only one time the value of the edge basis functions for
3070  // each possible orientations
3071  std::vector<std::vector<std::vector<double> > > eTableNegativeFlag(
3072  eTable);
3073  if(eSize != 0) {
3074  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
3075  basis->orientEdgeFunctionsForNegativeFlag(eTableNegativeFlag[q]);
3076  }
3077  }
3078 
3079  // compute only one time the value of the face basis functions for
3080  // each possible orientations
3081  std::vector<std::vector<std::vector<double> > >
3082  quadFaceFunctionsAllOrientations(
3083  numberOfGaussPoints,
3084  std::vector<std::vector<double> >(basis->getnQuadFaceFunction() * 8,
3085  std::vector<double>(3, 0.)));
3086  std::vector<std::vector<std::vector<double> > >
3087  triFaceFunctionsAllOrientations(
3088  numberOfGaussPoints,
3089  std::vector<std::vector<double> >(basis->getnTriFaceFunction() * 6,
3090  std::vector<double>(3, 0.)));
3091  if(fSize != 0) {
3092  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
3093  const double u = localCoord[3 * q];
3094  const double v = localCoord[3 * q + 1];
3095  const double w = localCoord[3 * q + 2];
3096 
3097  basis->addAllOrientedFaceFunctions(
3098  u, v, w, fTable[q], quadFaceFunctionsAllOrientations[q],
3099  triFaceFunctionsAllOrientations[q], fsName);
3100  }
3101  }
3102 
3103  std::vector<std::vector<std::vector<double> > > eTableCopy(
3104  numberOfGaussPoints,
3105  std::vector<std::vector<double> >(
3106  eSize,
3107  std::vector<double>(3, 0.))); // use eTableCopy to orient the edges
3108  std::vector<std::vector<std::vector<double> > > fTableCopy(
3109  numberOfGaussPoints,
3110  std::vector<std::vector<double> >(
3111  fSize,
3112  std::vector<double>(3, 0.))); // use fTableCopy to orient the faces
3113 
3114  unsigned int iOrientationIndex = 0;
3115  for(unsigned int iOrientation = 0; iOrientation < maxOrientation;
3116  ++iOrientation) {
3117  if(wantedOrientations.size() != 0) {
3118  auto it = std::find(wantedOrientations.begin(),
3119  wantedOrientations.end(), iOrientation);
3120  if(it != wantedOrientations.end()) {
3121  iOrientationIndex = &(*it) - &wantedOrientations[0];
3122  }
3123  else {
3124  MVertexPtrLessThan comp;
3125  std::next_permutation(vertices.begin(), vertices.end(), comp);
3126  for(unsigned int i = 0; i < numVertices; ++i) {
3127  element->setVertex(i, vertices[i]);
3128  }
3129  continue;
3130  }
3131  }
3132  else {
3133  iOrientationIndex = iOrientation;
3134  }
3135 
3136  if(eSize != 0) {
3137  for(int iEdge = 0; iEdge < basis->getNumEdge(); ++iEdge) {
3138  MEdge edge = element->getEdge(iEdge);
3139  MEdge edgeSolin = element->getEdgeSolin(iEdge);
3140  const int orientationFlag =
3141  (edge.getMinVertex() != edgeSolin.getVertex(0) ? -1 : 1);
3142  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
3143  basis->orientEdge(orientationFlag, iEdge, eTableCopy[q],
3144  eTable[q], eTableNegativeFlag[q]);
3145  }
3146  }
3147  }
3148 
3149  if(fSize != 0) {
3150  for(int iFace = 0;
3151  iFace < basis->getNumTriFace() + basis->getNumQuadFace();
3152  ++iFace) {
3153  MFace face = element->getFaceSolin(iFace);
3154  std::vector<int> faceOrientationFlag(3);
3155  face.getOrientationFlagForFace(faceOrientationFlag);
3156  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
3157  basis->orientFace(faceOrientationFlag[0], faceOrientationFlag[1],
3158  faceOrientationFlag[2], iFace,
3159  quadFaceFunctionsAllOrientations[q],
3160  triFaceFunctionsAllOrientations[q],
3161  fTableCopy[q]);
3162  }
3163  }
3164  }
3165 
3166  const std::size_t offsetOrientation =
3167  iOrientationIndex * numberOfGaussPoints * numFunctionsPerElement * 3;
3168  for(unsigned int q = 0; q < numberOfGaussPoints; ++q) {
3169  const std::size_t offsetGP = q * numFunctionsPerElement * 3;
3170 
3171  for(unsigned int i = 0; i < vSize; ++i) {
3172  basisFunctions[offsetOrientation + offsetGP + 3 * i] =
3173  vTable[q][i][0];
3174  basisFunctions[offsetOrientation + offsetGP + 3 * i + 1] =
3175  vTable[q][i][1];
3176  basisFunctions[offsetOrientation + offsetGP + 3 * i + 2] =
3177  vTable[q][i][2];
3178  }
3179  unsigned int offset = 3 * vSize;
3180  for(unsigned int i = 0; i < eSize; ++i) {
3181  basisFunctions[offsetOrientation + offsetGP + offset + 3 * i] =
3182  eTableCopy[q][i][0];
3183  basisFunctions[offsetOrientation + offsetGP + offset + 3 * i + 1] =
3184  eTableCopy[q][i][1];
3185  basisFunctions[offsetOrientation + offsetGP + offset + 3 * i + 2] =
3186  eTableCopy[q][i][2];
3187  }
3188  offset += 3 * eSize;
3189  for(unsigned int i = 0; i < fSize; ++i) {
3190  basisFunctions[offsetOrientation + offsetGP + offset + 3 * i] =
3191  fTableCopy[q][i][0];
3192  basisFunctions[offsetOrientation + offsetGP + offset + 3 * i + 1] =
3193  fTableCopy[q][i][1];
3194  basisFunctions[offsetOrientation + offsetGP + offset + 3 * i + 2] =
3195  fTableCopy[q][i][2];
3196  }
3197  offset += 3 * fSize;
3198  for(unsigned int i = 0; i < bSize; ++i) {
3199  basisFunctions[offsetOrientation + offsetGP + offset + 3 * i] =
3200  bTable[q][i][0];
3201  basisFunctions[offsetOrientation + offsetGP + offset + 3 * i + 1] =
3202  bTable[q][i][1];
3203  basisFunctions[offsetOrientation + offsetGP + offset + 3 * i + 2] =
3204  bTable[q][i][2];
3205  }
3206  }
3207 
3208  MVertexPtrLessThan comp;
3209  std::next_permutation(vertices.begin(), vertices.end(), comp);
3210  for(unsigned int i = 0; i < numVertices; ++i) {
3211  element->setVertex(i, vertices[i]);
3212  }
3213  }
3214  break;
3215  }
3216  }
3217 
3218  for(unsigned int i = 0; i < numVertices; ++i) { delete vertices[i]; }
3219  delete element;
3220  delete basis;
3221  }
3222 
3223  return;
3224 }
3225 
3226 GMSH_API void gmsh::model::mesh::getBasisFunctionsOrientation(
3227  const int elementType, const std::string &functionSpaceType,
3228  std::vector<int> &basisFunctionsOrientation, const int tag,
3229  const std::size_t task, const std::size_t numTasks)
3230 {
3231  if(!_checkInit()) return;
3232 
3233  int basisOrder = 0;
3234  std::string fsName = "";
3235  int numComponents = 0;
3236  if(!_getFunctionSpaceInfo(functionSpaceType, fsName, basisOrder,
3237  numComponents)) {
3238  Msg::Error("Unknown function space type '%s'", functionSpaceType.c_str());
3239  return;
3240  }
3241 
3242  const int dim = ElementType::getDimension(elementType);
3243  std::map<int, std::vector<GEntity *> > typeEnt;
3244  _getEntitiesForElementTypes(dim, tag, typeEnt);
3245  const std::vector<GEntity *> &entities(typeEnt[elementType]);
3246  const int familyType = ElementType::getParentType(elementType);
3247  std::size_t numElements = 0;
3248  for(std::size_t i = 0; i < entities.size(); i++) {
3249  const GEntity *ge = entities[i];
3250  numElements += ge->getNumMeshElementsByType(familyType);
3251  }
3252 
3253  if(basisFunctionsOrientation.empty() ||
3254  numElements != basisFunctionsOrientation.size()) {
3255  if(numTasks > 1) {
3256  Msg::Warning(
3257  "basisFunctionsOrientation should be preallocated if numTasks > 1");
3258  }
3259  preallocateBasisFunctionsOrientation(
3260  elementType, basisFunctionsOrientation, tag);
3261  }
3262 
3263  if(fsName == "Lagrange" || fsName == "GradLagrange") { // Lagrange type
3264  const std::size_t begin = task * numElements / numTasks;
3265  const std::size_t end = (task + 1) * numElements / numTasks;
3266  for(std::size_t iElement = begin; iElement < end; ++iElement) {
3267  basisFunctionsOrientation[iElement] = 0;
3268  }
3269  }
3270  else { // Hierarchical type
3271  const unsigned int numVertices =
3272  ElementType::getNumVertices(ElementType::getType(familyType, 1, false));
3273  std::vector<MVertex *> vertices(numVertices);
3274  std::vector<unsigned int> verticesOrder(numVertices);
3275  const std::size_t factorial[8] = {1, 1, 2, 6, 24, 120, 720, 5040};
3276 
3277  std::size_t entityOffset = 0;
3278 
3279  for(std::size_t iEntity = 0; iEntity < entities.size(); ++iEntity) {
3280  const GEntity *ge = entities[iEntity];
3281  std::size_t localNumElements = ge->getNumMeshElementsByType(familyType);
3282 
3283  const std::size_t begin = task * localNumElements / numTasks;
3284  const std::size_t end = (task + 1) * localNumElements / numTasks;
3285 
3286  for(std::size_t iElement = begin; iElement < end; ++iElement) {
3287  MElement *e = ge->getMeshElementByType(familyType, iElement);
3288  for(std::size_t i = 0; i < numVertices; ++i) {
3289  vertices[i] = e->getVertex(i);
3290  }
3291 
3292  for(std::size_t i = 0; i < numVertices; ++i) {
3293  std::size_t max = 0;
3294  std::size_t maxPos = 0;
3295  for(std::size_t j = 0; j < numVertices; ++j) {
3296  if(vertices[j] != nullptr) {
3297  if(max < vertices[j]->getNum()) {
3298  max = vertices[j]->getNum();
3299  maxPos = j;
3300  }
3301  }
3302  }
3303  vertices[maxPos] = nullptr;
3304  verticesOrder[maxPos] = numVertices - i - 1;
3305  }
3306 
3307  std::size_t elementOrientation = 0;
3308  for(std::size_t i = 0; i < numVertices; ++i) {
3309  elementOrientation +=
3310  verticesOrder[i] * factorial[numVertices - i - 1];
3311  for(std::size_t j = i + 1; j < numVertices; ++j) {
3312  if(verticesOrder[j] > verticesOrder[i]) --verticesOrder[j];
3313  }
3314  }
3315 
3316  basisFunctionsOrientation[entityOffset + iElement] =
3317  (int)elementOrientation;
3318  }
3319 
3320  entityOffset += localNumElements;
3321  }
3322  }
3323 
3324  return;
3325 }
3326 
3327 GMSH_API void gmsh::model::mesh::getBasisFunctionsOrientationForElement(
3328  const std::size_t elementTag, const std::string &functionSpaceType,
3329  int &basisFunctionsOrientation)
3330 {
3331  if(!_checkInit()) return;
3332 
3333  int basisOrder = 0;
3334  std::string fsName = "";
3335  int numComponents = 0;
3336  if(!_getFunctionSpaceInfo(functionSpaceType, fsName, basisOrder,
3337  numComponents)) {
3338  Msg::Error("Unknown function space type '%s'", functionSpaceType.c_str());
3339  return;
3340  }
3341 
3342  MElement *e = GModel::current()->getMeshElementByTag(elementTag);
3343  int elementType = e->getTypeForMSH();
3344  int familyType = ElementType::getParentType(elementType);
3345 
3346  if(fsName == "Lagrange" || fsName == "GradLagrange") { // Lagrange type
3347  basisFunctionsOrientation = 0;
3348  }
3349  else { // Hierarchical type
3350  const unsigned int numVertices =
3351  ElementType::getNumVertices(ElementType::getType(familyType, 1, false));
3352  std::vector<MVertex *> vertices(numVertices);
3353  std::vector<unsigned int> verticesOrder(numVertices);
3354  const std::size_t factorial[8] = {1, 1, 2, 6, 24, 120, 720, 5040};
3355 
3356  for(std::size_t i = 0; i < numVertices; ++i) {
3357  vertices[i] = e->getVertex(i);
3358  }
3359 
3360  for(std::size_t i = 0; i < numVertices; ++i) {
3361  std::size_t max = 0;
3362  std::size_t maxPos = 0;
3363  for(std::size_t j = 0; j < numVertices; ++j) {
3364  if(vertices[j] != nullptr) {
3365  if(max < vertices[j]->getNum()) {
3366  max = vertices[j]->getNum();
3367  maxPos = j;
3368  }
3369  }
3370  }
3371  vertices[maxPos] = nullptr;
3372  verticesOrder[maxPos] = numVertices - i - 1;
3373  }
3374 
3375  basisFunctionsOrientation = 0;
3376  for(std::size_t i = 0; i < numVertices; ++i) {
3377  basisFunctionsOrientation +=
3378  verticesOrder[i] * factorial[numVertices - i - 1];
3379  for(std::size_t j = i + 1; j < numVertices; ++j) {
3380  if(verticesOrder[j] > verticesOrder[i]) --verticesOrder[j];
3381  }
3382  }
3383  }
3384 
3385  return;
3386 }
3387 
3388 GMSH_API int
3389 gmsh::model::mesh::getNumberOfOrientations(const int elementType,
3390  const std::string &functionSpaceType)
3391 {
3392  if(!_checkInit()) return -1;
3393 
3394  int basisOrder = 0;
3395  std::string fsName = "";
3396  int numComponents = 0;
3397  if(!_getFunctionSpaceInfo(functionSpaceType, fsName, basisOrder,
3398  numComponents)) {
3399  Msg::Error("Unknown function space type '%s'", functionSpaceType.c_str());
3400  return 0;
3401  }
3402 
3403  if(fsName == "Lagrange" || fsName == "GradLagrange") { // Lagrange type
3404  return 1;
3405  }
3406  else { // Hierarchical type
3407  const int familyType = ElementType::getParentType(elementType);
3408  const unsigned int numVertices =
3409  ElementType::getNumVertices(ElementType::getType(familyType, 1, false));
3410  const std::size_t factorial[8] = {1, 1, 2, 6, 24, 120, 720, 5040};
3411  return factorial[numVertices];
3412  }
3413 
3414  return 0;
3415 }
3416 
3417 GMSH_API void
3418 gmsh::model::mesh::preallocateBasisFunctionsOrientation(
3419  const int elementType, std::vector<int> &basisFunctionsOrientation,
3420  const int tag)
3421 {
3422  if(!_checkInit()) return;
3423 
3424  const int dim = ElementType::getDimension(elementType);
3425  std::map<int, std::vector<GEntity *> > typeEnt;
3426  _getEntitiesForElementTypes(dim, tag, typeEnt);
3427  const std::vector<GEntity *> &entities(typeEnt[elementType]);
3428 
3429  const int familyType = ElementType::getParentType(elementType);
3430 
3431  std::size_t numElements = 0;
3432  for(std::size_t i = 0; i < entities.size(); i++) {
3433  const GEntity *ge = entities[i];
3434  numElements += ge->getNumMeshElementsByType(familyType);
3435  }
3436  if(!numElements) return;
3437  basisFunctionsOrientation.resize(numElements);
3438 }
3439 
3440 GMSH_API void
3441 gmsh::model::mesh::getEdges(const std::vector<std::size_t> &nodeTags,
3442  std::vector<std::size_t> &edgeTags,
3443  std::vector<int> &edgeOrientations)
3444 {
3445  edgeTags.clear();
3446  edgeOrientations.clear();
3447  std::size_t numEdges = nodeTags.size() / 2;
3448  if(!numEdges) return;
3449  edgeTags.resize(numEdges);
3450  edgeOrientations.resize(numEdges);
3451  for(std::size_t i = 0; i < numEdges; i++) {
3452  std::size_t n0 = nodeTags[2 * i];
3453  std::size_t n1 = nodeTags[2 * i + 1];
3456  if(v0 && v1) {
3457  MEdge edge;
3458  edgeTags[i] = GModel::current()->getMEdge(v0, v1, edge);
3459  if(edge.getMinVertex() == v0 && edge.getMaxVertex() == v1)
3460  edgeOrientations[i] = 1;
3461  else if(edge.getMaxVertex() == v0 && edge.getMinVertex() == v1)
3462  edgeOrientations[i] = -1;
3463  else
3464  edgeOrientations[i] = 0;
3465  }
3466  else {
3467  Msg::Error("Unknown mesh node %d or %d", n0, n1);
3468  }
3469  }
3470 }
3471 
3472 GMSH_API void gmsh::model::mesh::getFaces(
3473  const int faceType, const std::vector<std::size_t> &nodeTags,
3474  std::vector<std::size_t> &faceTags, std::vector<int> &orientations)
3475 {
3476  faceTags.clear();
3477  orientations.clear();
3478  if(faceType != 3 && faceType != 4) {
3479  Msg::Error("Unknown face type (should be 3 or 4)");
3480  return;
3481  }
3482  std::size_t numFaces = nodeTags.size() / faceType;
3483  if(!numFaces) return;
3484  faceTags.resize(numFaces);
3485  orientations.resize(numFaces, 0); // TODO
3486  for(std::size_t i = 0; i < numFaces; i++) {
3487  std::size_t n0 = nodeTags[faceType * i];
3488  std::size_t n1 = nodeTags[faceType * i + 1];
3489  std::size_t n2 = nodeTags[faceType * i + 2];
3490  std::size_t n3 = (faceType == 4) ? nodeTags[faceType * i + 3] : 0;
3494  MVertex *v3 =
3495  (faceType == 4) ? GModel::current()->getMeshVertexByTag(n3) : nullptr;
3496  if(v0 && v1 && v2) {
3497  MFace face;
3498  faceTags[i] = GModel::current()->getMFace(v0, v1, v2, v3, face);
3499  }
3500  else {
3501  Msg::Error("Unknown mesh node %d, %d or %d", n0, n1, n2);
3502  }
3503  }
3504 }
3505 
3506 GMSH_API void gmsh::model::mesh::createEdges(const vectorpair &dimTags)
3507 {
3508  if(!_checkInit()) return;
3509  std::vector<GEntity *> entities;
3510  _getEntities(dimTags, entities);
3511  for(std::size_t i = 0; i < entities.size(); i++) {
3512  GEntity *ge = entities[i];
3513  for(std::size_t j = 0; j < ge->getNumMeshElements(); j++) {
3514  MElement *e = ge->getMeshElement(j);
3515  for(int k = 0; k < e->getNumEdges(); k++) {
3516  MEdge edge = e->getEdge(k);
3517  GModel::current()->addMEdge(edge);
3518  }
3519  }
3520  }
3521 }
3522 
3523 GMSH_API void gmsh::model::mesh::createFaces(const vectorpair &dimTags)
3524 {
3525  if(!_checkInit()) return;
3526  std::vector<GEntity *> entities;
3527  _getEntities(dimTags, entities);
3528  for(std::size_t i = 0; i < entities.size(); i++) {
3529  GEntity *ge = entities[i];
3530  for(std::size_t j = 0; j < ge->getNumMeshElements(); j++) {
3531  MElement *e = ge->getMeshElement(j);
3532  for(int k = 0; k < e->getNumFaces(); k++) {
3533  MFace face = e->getFace(k);
3534  GModel::current()->addMFace(face);
3535  }
3536  }
3537  }
3538 }
3539 
3540 GMSH_API void gmsh::model::mesh::getAllEdges(std::vector<std::size_t> &edgeTags,
3541  std::vector<std::size_t> &edgeNodes)
3542 {
3543  if(!_checkInit()) return;
3544  edgeTags.clear();
3545  edgeNodes.clear();
3546  GModel *m = GModel::current();
3547  for(auto it = m->firstMEdge(); it != m->lastMEdge(); ++it) {
3548  edgeTags.push_back(it->second);
3549  edgeNodes.push_back(it->first.getVertex(0)->getNum());
3550  edgeNodes.push_back(it->first.getVertex(1)->getNum());
3551  }
3552 }
3553 
3554 GMSH_API void gmsh::model::mesh::getAllFaces(const int faceType,
3555  std::vector<std::size_t> &faceTags,
3556  std::vector<std::size_t> &faceNodes)
3557 {
3558  if(!_checkInit()) return;
3559  if(faceType != 3 && faceType != 4) {
3560  Msg::Error("Unknown face type (should be 3 or 4)");
3561  return;
3562  }
3563  faceTags.clear();
3564  faceNodes.clear();
3565  GModel *m = GModel::current();
3566  for(auto it = m->firstMFace(); it != m->lastMFace(); ++it) {
3567  if(faceType == (int)it->first.getNumVertices()) {
3568  faceTags.push_back(it->second);
3569  for(int j = 0; j < faceType; j++)
3570  faceNodes.push_back(it->first.getVertex(j)->getNum());
3571  }
3572  }
3573 }
3574 
3575 GMSH_API void gmsh::model::mesh::addEdges(const std::vector<std::size_t> &edgeTags,
3576  const std::vector<std::size_t> &edgeNodes)
3577 {
3578  if(!_checkInit()) return;
3579  if(edgeTags.size() * 2 != edgeNodes.size()) {
3580  Msg::Error("Wrong number of edge nodes");
3581  return;
3582  }
3583  GModel *m = GModel::current();
3584  for(std::size_t i = 0; i < edgeTags.size(); i++) {
3585  MVertex *v[2];
3586  for(int j = 0; j < 2; j++) {
3587  v[j] = m->getMeshVertexByTag(edgeNodes[2 * i + j]);
3588  if(!v[j]) {
3589  Msg::Error("Unknown mesh node %lu", edgeNodes[2 * i + j]);
3590  return;
3591  }
3592  }
3593  MEdge e(v[0], v[1]);
3594  m->addMEdge(e, edgeTags[i]);
3595  }
3596 }
3597 
3598 GMSH_API void gmsh::model::mesh::addFaces(const int faceType,
3599  const std::vector<std::size_t> &faceTags,
3600  const std::vector<std::size_t> &faceNodes)
3601 {
3602  if(!_checkInit()) return;
3603  if(faceType != 3 && faceType != 4) {
3604  Msg::Error("Unknown face type (should be 3 or 4)");
3605  return;
3606  }
3607  if(faceTags.size() * faceType != faceNodes.size()) {
3608  Msg::Error("Wrong number of face nodes");
3609  return;
3610  }
3611  GModel *m = GModel::current();
3612  for(std::size_t i = 0; i < faceTags.size(); i++) {
3613  MVertex *v[4] = {nullptr, nullptr, nullptr, nullptr};
3614  for(int j = 0; j < faceType; j++) {
3615  v[j] = m->getMeshVertexByTag(faceNodes[faceType * i + j]);
3616  if(!v[j]) {
3617  Msg::Error("Unknown mesh node %lu", faceNodes[faceType * i + j]);
3618  return;
3619  }
3620  }
3621  MFace f(v[0], v[1], v[2], v[3]);
3622  m->addMFace(f, faceTags[i]);
3623  }
3624 }
3625 
3626 GMSH_API void gmsh::model::mesh::getKeys(
3627  const int elementType, const std::string &functionSpaceType,
3628  std::vector<int> &typeKeys, std::vector<std::size_t> &entityKeys,
3629  std::vector<double> &coord, const int tag, const bool returnCoord)
3630 {
3631  if(!_checkInit()) return;
3632  coord.clear();
3633  typeKeys.clear();
3634  entityKeys.clear();
3635  int order = 0;
3636  int numComponents = 0;
3637  std::string fsName = "";
3638  if(!_getFunctionSpaceInfo(functionSpaceType, fsName, order, numComponents)) {
3639  Msg::Error("Unknown function space type '%s'", functionSpaceType.c_str());
3640  return;
3641  }
3642  int dim = ElementType::getDimension(elementType);
3643  std::map<int, std::vector<GEntity *> > typeEnt;
3644  _getEntitiesForElementTypes(dim, tag, typeEnt);
3645  const std::vector<GEntity *> &entities(typeEnt[elementType]);
3646  int familyType = ElementType::getParentType(elementType);
3647 
3648  HierarchicalBasis *basis(nullptr);
3649  if(fsName == "H1Legendre" || fsName == "GradH1Legendre") {
3650  switch(familyType) {
3651  case TYPE_HEX: {
3652  basis = new HierarchicalBasisH1Brick(order);
3653  } break;
3654  case TYPE_PRI: {
3655  basis = new HierarchicalBasisH1Pri(order);
3656  } break;
3657  case TYPE_TET: {
3658  basis = new HierarchicalBasisH1Tetra(order);
3659  } break;
3660  case TYPE_QUA: {
3661  basis = new HierarchicalBasisH1Quad(order);
3662  } break;
3663  case TYPE_TRI: {
3664  basis = new HierarchicalBasisH1Tria(order);
3665  } break;
3666  case TYPE_LIN: {
3667  basis = new HierarchicalBasisH1Line(order);
3668  } break;
3669  case TYPE_PNT: {
3670  basis = new HierarchicalBasisH1Point();
3671  } break;
3672  default:
3673  Msg::Error("Unknown familyType %i for basis function type %s", familyType,
3674  fsName.c_str());
3675  return;
3676  }
3677  }
3678  else if(fsName == "HcurlLegendre" || fsName == "CurlHcurlLegendre") {
3679  switch(familyType) {
3680  case TYPE_QUA: {
3681  basis = new HierarchicalBasisHcurlQuad(order);
3682  } break;
3683  case TYPE_HEX: {
3684  basis = new HierarchicalBasisHcurlBrick(order);
3685  } break;
3686  case TYPE_TRI: {
3687  basis = new HierarchicalBasisHcurlTria(order);
3688  } break;
3689  case TYPE_TET: {
3690  basis = new HierarchicalBasisHcurlTetra(order);
3691  } break;
3692  case TYPE_PRI: {
3693  basis = new HierarchicalBasisHcurlPri(order);
3694  } break;
3695  case TYPE_LIN: {
3696  basis = new HierarchicalBasisHcurlLine(order);
3697  } break;
3698  default:
3699  Msg::Error("Unknown familyType %i for basis function type %s", familyType,
3700  fsName.c_str());
3701  return;
3702  }
3703  }
3704  else if(fsName == "IsoParametric" || fsName == "Lagrange" ||
3705  fsName == "GradIsoParametric" || fsName == "GradLagrange") {
3706  const nodalBasis *nodalB(nullptr);
3707  if(order == -1) { // isoparametric
3708  nodalB = BasisFactory::getNodalBasis(elementType);
3709  }
3710  else {
3711  int familyType = ElementType::getParentType(elementType);
3712  int newType = ElementType::getType(familyType, order, false);
3713  nodalB = BasisFactory::getNodalBasis(newType);
3714  }
3715 
3716  for(std::size_t i = 0; i < entities.size(); ++i) {
3717  GEntity *ge = entities[i];
3718  std::size_t numElementsInEntitie =
3719  ge->getNumMeshElementsByType(familyType);
3720  if(returnCoord) {
3721  coord.reserve(coord.size() + numElementsInEntitie *
3722  nodalB->getNumShapeFunctions() * 3);
3723  }
3724  typeKeys.reserve(typeKeys.size() +
3725  numElementsInEntitie * nodalB->getNumShapeFunctions());
3726  entityKeys.reserve(entityKeys.size() +
3727  numElementsInEntitie * nodalB->getNumShapeFunctions());
3728 
3729  for(std::size_t j = 0; j < numElementsInEntitie; ++j) {
3730  MElement *e = ge->getMeshElementByType(familyType, j);
3731  for(size_t k = 0; k < e->getNumVertices(); ++k) {
3732  typeKeys.push_back(0);
3733  entityKeys.push_back(e->getVertex(k)->getNum());
3734  if(returnCoord) {
3735  coord.push_back(e->getVertex(k)->x());
3736  coord.push_back(e->getVertex(k)->y());
3737  coord.push_back(e->getVertex(k)->z());
3738  }
3739  }
3740  }
3741  }
3742  return;
3743  }
3744  else {
3745  Msg::Error("Unknown function space named '%s'", fsName.c_str());
3746  return;
3747  }
3748 
3749  int vSize = basis->getnVertexFunction();
3750  int bSize = basis->getnBubbleFunction();
3751  int eSize = basis->getnEdgeFunction();
3752  int quadFSize = basis->getnQuadFaceFunction();
3753  int triFSize = basis->getnTriFaceFunction();
3754  int fSize = quadFSize + triFSize;
3755  int numDofsPerElement = vSize + bSize + eSize + fSize;
3756  int numberQuadFaces = basis->getNumQuadFace();
3757  int numberTriFaces = basis->getNumTriFace();
3758  int numTriFaceFunction = 0;
3759  if(basis->getNumTriFace() != 0) {
3760  numTriFaceFunction =
3761  triFSize /
3762  basis->getNumTriFace(); // number of Tri face functions for one face
3763  }
3764  int numQuadFaceFunction = 0;
3765  if(basis->getNumQuadFace() != 0) {
3766  numQuadFaceFunction =
3767  quadFSize /
3768  basis->getNumQuadFace(); // number of Tri face functions for one face
3769  }
3770  int numEdgeFunction = 0;
3771  if(basis->getNumEdge() != 0) {
3772  numEdgeFunction =
3773  eSize / basis->getNumEdge(); // number of edge functions for one edge
3774  }
3775  int const1 = numEdgeFunction + 1;
3776  int const2 = const1 + numQuadFaceFunction;
3777  int const3 = const1 + numTriFaceFunction;
3778  int const4 = bSize + std::max(const3, const2);
3779  delete basis;
3780 
3781  for(std::size_t i = 0; i < entities.size(); i++) {
3782  GEntity *ge = entities[i];
3783  std::size_t numElementsInEntitie = ge->getNumMeshElementsByType(familyType);
3784  if(returnCoord) {
3785  coord.reserve(coord.size() +
3786  numElementsInEntitie * numDofsPerElement * 3);
3787  }
3788  typeKeys.reserve(typeKeys.size() +
3789  numElementsInEntitie * numDofsPerElement);
3790  entityKeys.reserve(entityKeys.size() +
3791  numElementsInEntitie * numDofsPerElement);
3792 
3793  for(std::size_t j = 0; j < numElementsInEntitie; j++) {
3794  MElement *e = ge->getMeshElementByType(familyType, j);
3795  // vertices
3796  for(int k = 0; k < vSize; k++) {
3797  typeKeys.push_back(0);
3798  entityKeys.push_back(e->getVertex(k)->getNum());
3799  if(returnCoord) {
3800  coord.push_back(e->getVertex(k)->x());
3801  coord.push_back(e->getVertex(k)->y());
3802  coord.push_back(e->getVertex(k)->z());
3803  }
3804  }
3805  // edges
3806  if(eSize > 0) {
3807  for(int jj = 0; jj < e->getNumEdges(); jj++) {
3808  MEdge edge = e->getEdge(jj);
3809  double coordEdge[3];
3810  if(returnCoord) {
3811  MVertex *v1 = edge.getVertex(0);
3812  MVertex *v2 = edge.getVertex(1);
3813 
3814  coordEdge[0] = 0.5 * (v1->x() + v2->x());
3815  coordEdge[1] = 0.5 * (v1->y() + v2->y());
3816  coordEdge[2] = 0.5 * (v1->z() + v2->z());
3817  }
3818  std::size_t edgeGlobalIndice = GModel::current()->addMEdge(edge);
3819  for(int k = 1; k < const1; k++) {
3820  typeKeys.push_back(k);
3821  entityKeys.push_back(edgeGlobalIndice);
3822  if(returnCoord) {
3823  coord.push_back(coordEdge[0]);
3824  coord.push_back(coordEdge[1]);
3825  coord.push_back(coordEdge[2]);
3826  }
3827  }
3828  }
3829  }
3830  // faces
3831  if(fSize > 0) {
3832  for(int jj = 0; jj < numberQuadFaces + numberTriFaces; jj++) {
3833  // Number the faces
3834  MFace face = e->getFaceSolin(jj);
3835  double coordFace[3] = {0., 0., 0.};
3836  if(returnCoord) {
3837  for(std::size_t indexV = 0; indexV < face.getNumVertices();
3838  ++indexV) {
3839  coordFace[0] += face.getVertex(indexV)->x();
3840  coordFace[1] += face.getVertex(indexV)->y();
3841  coordFace[2] += face.getVertex(indexV)->z();
3842  }
3843  coordFace[0] /= face.getNumVertices();
3844  coordFace[1] /= face.getNumVertices();
3845  coordFace[2] /= face.getNumVertices();
3846  }
3847  std::size_t faceGlobalIndice = GModel::current()->addMFace(face);
3848  int it2 = const2;
3849  if(jj >= numberQuadFaces) { it2 = const3; }
3850  for(int k = const1; k < it2; k++) {
3851  typeKeys.push_back(k);
3852  entityKeys.push_back(faceGlobalIndice);
3853  if(returnCoord) {
3854  coord.push_back(coordFace[0]);
3855  coord.push_back(coordFace[1]);
3856  coord.push_back(coordFace[2]);
3857  }
3858  }
3859  }
3860  }
3861  // volumes
3862  if(bSize > 0) {
3863  double bubbleCenterCoord[3] = {0., 0., 0.};
3864  if(returnCoord) {
3865  for(unsigned int indexV = 0; indexV < e->getNumVertices(); ++indexV) {
3866  bubbleCenterCoord[0] += e->getVertex(indexV)->x();
3867  bubbleCenterCoord[1] += e->getVertex(indexV)->y();
3868  bubbleCenterCoord[2] += e->getVertex(indexV)->z();
3869  }
3870  bubbleCenterCoord[0] /= e->getNumVertices();
3871  bubbleCenterCoord[1] /= e->getNumVertices();
3872  bubbleCenterCoord[2] /= e->getNumVertices();
3873  }
3874  for(int k = std::max(const3, const2); k < const4; k++) {
3875  typeKeys.push_back(k);
3876  entityKeys.push_back(e->getNum());
3877  if(returnCoord) {
3878  coord.push_back(bubbleCenterCoord[0]);
3879  coord.push_back(bubbleCenterCoord[1]);
3880  coord.push_back(bubbleCenterCoord[2]);
3881  }
3882  }
3883  }
3884  }
3885  }
3886 }
3887 
3888 GMSH_API void gmsh::model::mesh::getKeysForElement(
3889  const std::size_t elementTag, const std::string &functionSpaceType,
3890  std::vector<int> &typeKeys, std::vector<std::size_t> &entityKeys,
3891  std::vector<double> &coord, const bool returnCoord)
3892 {
3893  if(!_checkInit()) return;
3894  coord.clear();
3895  typeKeys.clear();
3896  entityKeys.clear();
3897  int order = 0;
3898  int numComponents = 0;
3899  std::string fsName = "";
3900  if(!_getFunctionSpaceInfo(functionSpaceType, fsName, order, numComponents)) {
3901  Msg::Error("Unknown function space type '%s'", functionSpaceType.c_str());
3902  return;
3903  }
3904  MElement *e = GModel::current()->getMeshElementByTag(elementTag);
3905  int elementType = e->getTypeForMSH();
3906  int familyType = ElementType::getParentType(elementType);
3907 
3908  HierarchicalBasis *basis(nullptr);
3909  if(fsName == "H1Legendre" || fsName == "GradH1Legendre") {
3910  switch(familyType) {
3911  case TYPE_HEX: {
3912  basis = new HierarchicalBasisH1Brick(order);
3913  } break;
3914  case TYPE_PRI: {
3915  basis = new HierarchicalBasisH1Pri(order);
3916  } break;
3917  case TYPE_TET: {
3918  basis = new HierarchicalBasisH1Tetra(order);
3919  } break;
3920  case TYPE_QUA: {
3921  basis = new HierarchicalBasisH1Quad(order);
3922  } break;
3923  case TYPE_TRI: {
3924  basis = new HierarchicalBasisH1Tria(order);
3925  } break;
3926  case TYPE_LIN: {
3927  basis = new HierarchicalBasisH1Line(order);
3928  } break;
3929  case TYPE_PNT: {
3930  basis = new HierarchicalBasisH1Point();
3931  } break;
3932  default:
3933  Msg::Error("Unknown familyType %i for basis function type %s", familyType,
3934  fsName.c_str());
3935  return;
3936  }
3937  }
3938  else if(fsName == "HcurlLegendre" || fsName == "CurlHcurlLegendre") {
3939  switch(familyType) {
3940  case TYPE_QUA: {
3941  basis = new HierarchicalBasisHcurlQuad(order);
3942  } break;
3943  case TYPE_HEX: {
3944  basis = new HierarchicalBasisHcurlBrick(order);
3945  } break;
3946  case TYPE_TRI: {
3947  basis = new HierarchicalBasisHcurlTria(order);
3948  } break;
3949  case TYPE_TET: {
3950  basis = new HierarchicalBasisHcurlTetra(order);
3951  } break;
3952  case TYPE_PRI: {
3953  basis = new HierarchicalBasisHcurlPri(order);
3954  } break;
3955  case TYPE_LIN: {
3956  basis = new HierarchicalBasisHcurlLine(order);
3957  } break;
3958  default:
3959  Msg::Error("Unknown familyType %i for basis function type %s", familyType,
3960  fsName.c_str());
3961  return;
3962  }
3963  }
3964  else if(fsName == "IsoParametric" || fsName == "Lagrange" ||
3965  fsName == "GradIsoParametric" || fsName == "GradLagrange") {
3966  typeKeys.reserve(e->getNumVertices());
3967  entityKeys.reserve(e->getNumVertices());
3968  if(returnCoord) { coord.reserve(3 * e->getNumVertices()); }
3969  for(size_t k = 0; k < e->getNumVertices(); ++k) {
3970  typeKeys.push_back(0);
3971  entityKeys.push_back(e->getVertex(k)->getNum());
3972  if(returnCoord) {
3973  coord.push_back(e->getVertex(k)->x());
3974  coord.push_back(e->getVertex(k)->y());
3975  coord.push_back(e->getVertex(k)->z());
3976  }
3977  }
3978  return;
3979  }
3980  else {
3981  Msg::Error("Unknown function space named '%s'", fsName.c_str());
3982  return;
3983  }
3984 
3985  int vSize = basis->getnVertexFunction();
3986  int bSize = basis->getnBubbleFunction();
3987  int eSize = basis->getnEdgeFunction();
3988  int quadFSize = basis->getnQuadFaceFunction();
3989  int triFSize = basis->getnTriFaceFunction();
3990  int fSize = quadFSize + triFSize;
3991  int numberQuadFaces = basis->getNumQuadFace();
3992  int numberTriFaces = basis->getNumTriFace();
3993  int numTriFaceFunction = 0;
3994  if(basis->getNumTriFace() != 0) {
3995  numTriFaceFunction =
3996  triFSize /
3997  basis->getNumTriFace(); // number of Tri face functions for one face
3998  }
3999  int numQuadFaceFunction = 0;
4000  if(basis->getNumQuadFace() != 0) {
4001  numQuadFaceFunction =
4002  quadFSize /
4003  basis->getNumQuadFace(); // number of Tri face functions for one face
4004  }
4005  int numEdgeFunction = 0;
4006  if(basis->getNumEdge() != 0) {
4007  numEdgeFunction =
4008  eSize / basis->getNumEdge(); // number of edge functions for one edge
4009  }
4010  int const1 = numEdgeFunction + 1;
4011  int const2 = const1 + numQuadFaceFunction;
4012  int const3 = const1 + numTriFaceFunction;
4013  int const4 = bSize + std::max(const3, const2);
4014  int numDofsPerElement = vSize + bSize + eSize + fSize;
4015  delete basis;
4016 
4017  typeKeys.reserve(numDofsPerElement);
4018  entityKeys.reserve(numDofsPerElement);
4019  if(returnCoord) { coord.reserve(3 * numDofsPerElement); }
4020 
4021  // vertices
4022  for(int k = 0; k < vSize; k++) {
4023  typeKeys.push_back(0);
4024  entityKeys.push_back(e->getVertex(k)->getNum());
4025  if(returnCoord) {
4026  coord.push_back(e->getVertex(k)->x());
4027  coord.push_back(e->getVertex(k)->y());
4028  coord.push_back(e->getVertex(k)->z());
4029  }
4030  }
4031  // edges
4032  if(eSize > 0) {
4033  for(int jj = 0; jj < e->getNumEdges(); jj++) {
4034  MEdge edge = e->getEdge(jj);
4035  double coordEdge[3];
4036  if(returnCoord) {
4037  MVertex *v1 = edge.getVertex(0);
4038  MVertex *v2 = edge.getVertex(1);
4039 
4040  coordEdge[0] = 0.5 * (v1->x() + v2->x());
4041  coordEdge[1] = 0.5 * (v1->y() + v2->y());
4042  coordEdge[2] = 0.5 * (v1->z() + v2->z());
4043  }
4044  std::size_t edgeGlobalIndice = GModel::current()->addMEdge(edge);
4045  for(int k = 1; k < const1; k++) {
4046  typeKeys.push_back(k);
4047  entityKeys.push_back(edgeGlobalIndice);
4048  if(returnCoord) {
4049  coord.push_back(coordEdge[0]);
4050  coord.push_back(coordEdge[1]);
4051  coord.push_back(coordEdge[2]);
4052  }
4053  }
4054  }
4055  }
4056  // faces
4057  if(fSize > 0) {
4058  for(int jj = 0; jj < numberQuadFaces + numberTriFaces; jj++) {
4059  // Number the faces
4060  MFace face = e->getFaceSolin(jj);
4061  double coordFace[3] = {0., 0., 0.};
4062  if(returnCoord) {
4063  for(std::size_t indexV = 0; indexV < face.getNumVertices(); ++indexV) {
4064  coordFace[0] += face.getVertex(indexV)->x();
4065  coordFace[1] += face.getVertex(indexV)->y();
4066  coordFace[2] += face.getVertex(indexV)->z();
4067  }
4068  coordFace[0] /= face.getNumVertices();
4069  coordFace[1] /= face.getNumVertices();
4070  coordFace[2] /= face.getNumVertices();
4071  }
4072  std::size_t faceGlobalIndice = GModel::current()->addMFace(face);
4073  int it2 = const2;
4074  if(jj >= numberQuadFaces) { it2 = const3; }
4075  for(int k = const1; k < it2; k++) {
4076  typeKeys.push_back(k);
4077  entityKeys.push_back(faceGlobalIndice);
4078  if(returnCoord) {
4079  coord.push_back(coordFace[0]);
4080  coord.push_back(coordFace[1]);
4081  coord.push_back(coordFace[2]);
4082  }
4083  }
4084  }
4085  }
4086  // volumes
4087  if(bSize > 0) {
4088  double bubbleCenterCoord[3] = {0., 0., 0.};
4089  if(returnCoord) {
4090  for(unsigned int indexV = 0; indexV < e->getNumVertices(); ++indexV) {
4091  bubbleCenterCoord[0] += e->getVertex(indexV)->x();
4092  bubbleCenterCoord[1] += e->getVertex(indexV)->y();
4093  bubbleCenterCoord[2] += e->getVertex(indexV)->z();
4094  }
4095  bubbleCenterCoord[0] /= e->getNumVertices();
4096  bubbleCenterCoord[1] /= e->getNumVertices();
4097  bubbleCenterCoord[2] /= e->getNumVertices();
4098  }
4099  for(int k = std::max(const3, const2); k < const4; k++) {
4100  typeKeys.push_back(k);
4101  entityKeys.push_back(e->getNum());
4102  if(returnCoord) {
4103  coord.push_back(bubbleCenterCoord[0]);
4104  coord.push_back(bubbleCenterCoord[1]);
4105  coord.push_back(bubbleCenterCoord[2]);
4106  }
4107  }
4108  }
4109 }
4110 
4111 GMSH_API int gmsh::model::mesh::getNumberOfKeys(
4112  const int elementType, const std::string &functionSpaceType)
4113 {
4114  int numberOfKeys = 0;
4115  int basisOrder = 0;
4116  std::string fsName = "";
4117  int numComponents = 0;
4118  if(!_getFunctionSpaceInfo(functionSpaceType, fsName, basisOrder,
4119  numComponents)) {
4120  Msg::Error("Unknown function space type '%s'", functionSpaceType.c_str());
4121  return 0;
4122  }
4123  int familyType = ElementType::getParentType(elementType);
4124  if(fsName == "H1Legendre" || fsName == "GradH1Legendre") {
4125  HierarchicalBasis *basis(nullptr);
4126  switch(familyType) {
4127  case TYPE_HEX: {
4128  basis = new HierarchicalBasisH1Brick(basisOrder);
4129  } break;
4130  case TYPE_PRI: {
4131  basis = new HierarchicalBasisH1Pri(basisOrder);
4132  } break;
4133  case TYPE_TET: {
4134  basis = new HierarchicalBasisH1Tetra(basisOrder);
4135  } break;
4136  case TYPE_QUA: {
4137  basis = new HierarchicalBasisH1Quad(basisOrder);
4138  } break;
4139  case TYPE_TRI: {
4140  basis = new HierarchicalBasisH1Tria(basisOrder);
4141  } break;
4142  case TYPE_LIN: {
4143  basis = new HierarchicalBasisH1Line(basisOrder);
4144  } break;
4145  case TYPE_PNT: {
4146  basis = new HierarchicalBasisH1Point();
4147  } break;
4148  default:
4149  Msg::Error("Unknown familyType %i for basis function type %s", familyType,
4150  fsName.c_str());
4151  return 0;
4152  }
4153  int vSize = basis->getnVertexFunction();
4154  int bSize = basis->getnBubbleFunction();
4155  int eSize = basis->getnEdgeFunction();
4156  int quadFSize = basis->getnQuadFaceFunction();
4157  int triFSize = basis->getnTriFaceFunction();
4158  numberOfKeys = vSize + bSize + eSize + quadFSize + triFSize;
4159  delete basis;
4160  }
4161  else if(fsName == "HcurlLegendre" || fsName == "CurlHcurlLegendre") {
4162  HierarchicalBasis *basis(nullptr);
4163  switch(familyType) {
4164  case TYPE_QUA: {
4165  basis = new HierarchicalBasisHcurlQuad(basisOrder);
4166  } break;
4167  case TYPE_HEX: {
4168  basis = new HierarchicalBasisHcurlBrick(basisOrder);
4169  } break;
4170  case TYPE_TRI: {
4171  basis = new HierarchicalBasisHcurlTria(basisOrder);
4172  } break;
4173  case TYPE_TET: {
4174  basis = new HierarchicalBasisHcurlTetra(basisOrder);
4175  } break;
4176  case TYPE_PRI: {
4177  basis = new HierarchicalBasisHcurlPri(basisOrder);
4178  } break;
4179  case TYPE_LIN: {
4180  basis = new HierarchicalBasisHcurlLine(basisOrder);
4181  } break;
4182  default:
4183  Msg::Error("Unknown familyType %i for basis function type %s", familyType,
4184  fsName.c_str());
4185  return 0;
4186  }
4187  int vSize = basis->getnVertexFunction();
4188  int bSize = basis->getnBubbleFunction();
4189  int eSize = basis->getnEdgeFunction();
4190  int quadFSize = basis->getnQuadFaceFunction();
4191  int triFSize = basis->getnTriFaceFunction();
4192  numberOfKeys = vSize + bSize + eSize + quadFSize + triFSize;
4193  delete basis;
4194  }
4195  else if(fsName == "IsoParametric" || fsName == "Lagrange" ||
4196  fsName == "GradIsoParametric" || fsName == "GradLagrange") {
4197  const nodalBasis *basis(nullptr);
4198  if(basisOrder == -1) { // isoparametric
4199  basis = BasisFactory::getNodalBasis(elementType);
4200  }
4201  else {
4202  int familyType = ElementType::getParentType(elementType);
4203  int newType = ElementType::getType(familyType, basisOrder, false);
4204  basis = BasisFactory::getNodalBasis(newType);
4205  }
4206  numberOfKeys = basis->getNumShapeFunctions();
4207  }
4208  else {
4209  Msg::Error("Unknown function space named '%s'", fsName.c_str());
4210  return 0;
4211  }
4212 
4213  return numberOfKeys;
4214 }
4215 
4216 GMSH_API void gmsh::model::mesh::getKeysInformation(
4217  const std::vector<int> &typeKeys, const std::vector<std::size_t> &entityKeys,
4218  const int elementType, const std::string &functionSpaceType,
4219  gmsh::vectorpair &infoKeys)
4220 {
4221  infoKeys.clear();
4222  int basisOrder = 0;
4223  std::string fsName = "";
4224  int numComponents = 0;
4225  if(!_getFunctionSpaceInfo(functionSpaceType, fsName, basisOrder,
4226  numComponents)) {
4227  Msg::Error("Unknown function space type '%s'", functionSpaceType.c_str());
4228  return;
4229  }
4230 
4231  if(typeKeys.size() != entityKeys.size()) {
4232  Msg::Error("The size of 'typeKeys' is different of the size of "
4233  "'entityKeys' ('%i', '%i')",
4234  typeKeys.size(), entityKeys.size());
4235  return;
4236  }
4237 
4238  HierarchicalBasis *basis(nullptr);
4239  int familyType = ElementType::getParentType(elementType);
4240  if(fsName == "H1Legendre" || fsName == "GradH1Legendre") {
4241  switch(familyType) {
4242  case TYPE_HEX: {
4243  basis = new HierarchicalBasisH1Brick(basisOrder);
4244  } break;
4245  case TYPE_PRI: {
4246  basis = new HierarchicalBasisH1Pri(basisOrder);
4247  } break;
4248  case TYPE_TET: {
4249  basis = new HierarchicalBasisH1Tetra(basisOrder);
4250  } break;
4251  case TYPE_QUA: {
4252  basis = new HierarchicalBasisH1Quad(basisOrder);
4253  } break;
4254  case TYPE_TRI: {
4255  basis = new HierarchicalBasisH1Tria(basisOrder);
4256  } break;
4257  case TYPE_LIN: {
4258  basis = new HierarchicalBasisH1Line(basisOrder);
4259  } break;
4260  case TYPE_PNT: {
4261  basis = new HierarchicalBasisH1Point();
4262  } break;
4263  default:
4264  Msg::Error("Unknown familyType %i for basis function type %s", familyType,
4265  fsName.c_str());
4266  return;
4267  }
4268  }
4269  else if(fsName == "HcurlLegendre" || fsName == "CurlHcurlLegendre") {
4270  switch(familyType) {
4271  case TYPE_QUA: {
4272  basis = new HierarchicalBasisHcurlQuad(basisOrder);
4273  } break;
4274  case TYPE_HEX: {
4275  basis = new HierarchicalBasisHcurlBrick(basisOrder);
4276  } break;
4277  case TYPE_TRI: {
4278  basis = new HierarchicalBasisHcurlTria(basisOrder);
4279  } break;
4280  case TYPE_TET: {
4281  basis = new HierarchicalBasisHcurlTetra(basisOrder);
4282  } break;
4283  case TYPE_PRI: {
4284  basis = new HierarchicalBasisHcurlPri(basisOrder);
4285  } break;
4286  case TYPE_LIN: {
4287  basis = new HierarchicalBasisHcurlLine(basisOrder);
4288  } break;
4289  default:
4290  Msg::Error("Unknown familyType %i for basis function type %s", familyType,
4291  fsName.c_str());
4292  return;
4293  }
4294  }
4295  else if(fsName == "IsoParametric" || fsName == "Lagrange" ||
4296  fsName == "GradIsoParametric" || fsName == "GradLagrange") {
4297  const nodalBasis *basis(nullptr);
4298  if(basisOrder == -1) { // isoparametric
4299  basis = BasisFactory::getNodalBasis(elementType);
4300  }
4301  else {
4302  int familyType = ElementType::getParentType(elementType);
4303  int newType = ElementType::getType(familyType, basisOrder, false);
4304  basis = BasisFactory::getNodalBasis(newType);
4305  }
4306  std::size_t numberOfKeys = basis->getNumShapeFunctions();
4307  std::size_t numberOfBubble = basis->getNumBubbleShapeFunctions();
4308  int dim = ElementType::getDimension(elementType);
4309 
4310  if(numberOfBubble > numberOfKeys) {
4311  Msg::Error("Number of bubble functions greater than number of keys");
4312  return;
4313  }
4314 
4315  infoKeys.reserve(typeKeys.size());
4316  for(size_t i = 0; i < typeKeys.size() / numberOfKeys; ++i) {
4317  for(size_t j = 0; j < numberOfKeys - numberOfBubble; ++j) {
4318  infoKeys.push_back(std::make_pair(0, basisOrder));
4319  }
4320  for(size_t j = 0; j < numberOfBubble; ++j) {
4321  infoKeys.push_back(std::make_pair(dim, basisOrder));
4322  }
4323  }
4324  return;
4325  }
4326  else {
4327  Msg::Error("Unknown function space named '%s'", fsName.c_str());
4328  return;
4329  }
4330 
4331  int vSize = basis->getnVertexFunction();
4332  int bSize = basis->getnBubbleFunction();
4333  int eSize = basis->getnEdgeFunction();
4334  int quadFSize = basis->getnQuadFaceFunction();
4335  int triFSize = basis->getnTriFaceFunction();
4336  int numDofsPerElement = vSize + bSize + eSize + quadFSize + triFSize;
4337  std::vector<int> functionTypeInfo(numDofsPerElement);
4338  std::vector<int> orderInfo(numDofsPerElement);
4339  basis->getKeysInfo(functionTypeInfo, orderInfo);
4340  delete basis;
4341  std::size_t keySize = typeKeys.size();
4342  if(!keySize) return;
4343  infoKeys.resize(keySize);
4344  std::size_t it = keySize / numDofsPerElement;
4345  for(std::size_t i = 0; i < it; i++) {
4346  size_t const1 = i * numDofsPerElement;
4347  for(int j = 0; j < numDofsPerElement; j++) {
4348  infoKeys[const1 + j] =
4349  std::make_pair(functionTypeInfo[j], orderInfo[j]);
4350  }
4351  }
4352 }
4353 
4354 GMSH_API void gmsh::model::mesh::getBarycenters(
4355  const int elementType, const int tag, const bool fast, const bool primary,
4356  std::vector<double> &barycenters, const std::size_t task,
4357  const std::size_t numTasks)
4358 {
4359  if(!_checkInit()) return;
4360  int dim = ElementType::getDimension(elementType);
4361  std::map<int, std::vector<GEntity *> > typeEnt;
4362  _getEntitiesForElementTypes(dim, tag, typeEnt);
4363  const std::vector<GEntity *> &entities(typeEnt[elementType]);
4364  int familyType = ElementType::getParentType(elementType);
4365  std::size_t numElements = 0;
4366  for(std::size_t i = 0; i < entities.size(); i++) {
4367  GEntity *ge = entities[i];
4368  numElements += ge->getNumMeshElementsByType(familyType);
4369  }
4370  if(!numTasks) {
4371  Msg::Error("Number of tasks should be > 0");
4372  return;
4373  }
4374  if(!numElements) return;
4375 
4376  if(3 * numElements != barycenters.size()) {
4377  if(numTasks > 1)
4378  Msg::Warning("Barycenters should be preallocated if numTasks > 1");
4379  barycenters.resize(3 * numElements);
4380  }
4381 
4382  const size_t begin = (task * numElements) / numTasks;
4383  const size_t end = ((task + 1) * numElements) / numTasks;
4384  size_t o = 0;
4385  size_t idx = 3 * begin;
4386  if(fast) {
4387  for(std::size_t i = 0; i < entities.size(); i++) {
4388  GEntity *ge = entities[i];
4389  for(std::size_t j = 0; j < ge->getNumMeshElementsByType(familyType);
4390  j++) {
4391  if(o >= begin && o < end) {
4392  MElement *e = ge->getMeshElementByType(familyType, j);
4393  SPoint3 p = e->fastBarycenter(primary);
4394  barycenters[idx++] = p[0];
4395  barycenters[idx++] = p[1];
4396  barycenters[idx++] = p[2];
4397  }
4398  o++;
4399  }
4400  }
4401  }
4402  else {
4403  for(std::size_t i = 0; i < entities.size(); i++) {
4404  GEntity *ge = entities[i];
4405  for(std::size_t j = 0; j < ge->getNumMeshElementsByType(familyType);
4406  j++) {
4407  if(o >= begin && o < end) {
4408  MElement *e = ge->getMeshElementByType(familyType, j);
4409  SPoint3 p = e->barycenter(primary);
4410  barycenters[idx++] = p[0];
4411  barycenters[idx++] = p[1];
4412  barycenters[idx++] = p[2];
4413  }
4414  o++;
4415  }
4416  }
4417  }
4418 }
4419 
4420 static bool _getIntegrationInfo(const std::string &intType,
4421  std::string &intName, int &intOrder)
4422 {
4423  if(intType.substr(0, 14) == "CompositeGauss") {
4424  intName = "CompositeGauss";
4425  intOrder = atoi(intType.substr(14).c_str());
4426  return true;
4427  }
4428  else if(intType.substr(0, 5) == "Gauss") {
4429  intName = "Gauss";
4430  intOrder = atoi(intType.substr(5).c_str());
4431  return true;
4432  }
4433  return false;
4434 }
4435 
4436 GMSH_API void gmsh::model::mesh::getIntegrationPoints(
4437  const int elementType, const std::string &integrationType,
4438  std::vector<double> &localCoord, std::vector<double> &weights)
4439 {
4440  if(!_checkInit()) return;
4441  localCoord.clear();
4442  weights.clear();
4443  std::string intName = "";
4444  int intOrder = 0;
4445  if(!_getIntegrationInfo(integrationType, intName, intOrder)) {
4446  Msg::Error("Unknown quadrature type '%s'", integrationType.c_str());
4447  return;
4448  }
4449  // get quadrature info
4450  int familyType = ElementType::getParentType(elementType);
4451  fullMatrix<double> pts;
4452  fullVector<double> wgs;
4453  gaussIntegration::get(familyType, intOrder, pts, wgs,
4454  intName == "Gauss" ? false : true);
4455  if(pts.size1() != wgs.size() || pts.size2() != 3) {
4456  Msg::Error("Wrong integration point format");
4457  return;
4458  }
4459  localCoord.resize(3 * pts.size1());
4460  weights.resize(pts.size1());
4461  for(int i = 0; i < pts.size1(); i++) {
4462  localCoord[3 * i] = pts(i, 0);
4463  localCoord[3 * i + 1] = pts(i, 1);
4464  localCoord[3 * i + 2] = pts(i, 2);
4465  weights[i] = wgs(i);
4466  }
4467 }
4468 
4469 GMSH_API void gmsh::model::mesh::preallocateBarycenters(
4470  const int elementType, std::vector<double> &barycenters, const int tag)
4471 {
4472  if(!_checkInit()) return;
4473  int dim = ElementType::getDimension(elementType);
4474  std::map<int, std::vector<GEntity *> > typeEnt;
4475  _getEntitiesForElementTypes(dim, tag, typeEnt);
4476  const std::vector<GEntity *> &entities(typeEnt[elementType]);
4477  int familyType = ElementType::getParentType(elementType);
4478  std::size_t numElements = 0;
4479  for(std::size_t i = 0; i < entities.size(); i++)
4480  numElements += entities[i]->getNumMeshElementsByType(familyType);
4481  barycenters.clear();
4482  if(!numElements) return;
4483  barycenters.resize(3 * numElements, 0);
4484 }
4485 
4486 GMSH_API void gmsh::model::mesh::getElementEdgeNodes(
4487  const int elementType, std::vector<std::size_t> &nodeTags, const int tag,
4488  const bool primary, const std::size_t task, const std::size_t numTasks)
4489 {
4490  if(!_checkInit()) return;
4491  int dim = ElementType::getDimension(elementType);
4492  std::map<int, std::vector<GEntity *> > typeEnt;
4493  _getEntitiesForElementTypes(dim, tag, typeEnt);
4494  const std::vector<GEntity *> &entities(typeEnt[elementType]);
4495  int familyType = ElementType::getParentType(elementType);
4496  std::size_t numElements = 0;
4497  int numEdgesPerEle = 0, numNodesPerEdge = 0;
4498  for(std::size_t i = 0; i < entities.size(); i++) {
4499  GEntity *ge = entities[i];
4500  int n = ge->getNumMeshElementsByType(familyType);
4501  if(n && !numNodesPerEdge) {
4502  MElement *e = ge->getMeshElementByType(familyType, 0);
4503  numEdgesPerEle = e->getNumEdges();
4504  if(primary) { numNodesPerEdge = 2; }
4505  else {
4506  std::vector<MVertex *> v;
4507  // we could use e->getHighOrderEdge() here if we decide to remove
4508  // getEdgeVertices
4509  e->getEdgeVertices(0, v);
4510  numNodesPerEdge = v.size();
4511  }
4512  }
4513  numElements += n;
4514  }
4515  if(!numTasks) {
4516  Msg::Error("Number of tasks should be > 0");
4517  return;
4518  }
4519  if(!numElements || !numEdgesPerEle || !numNodesPerEdge) return;
4520  if(numEdgesPerEle * numNodesPerEdge * numElements != nodeTags.size()) {
4521  if(numTasks > 1)
4522  Msg::Warning("Nodes should be preallocated if numTasks > 1");
4523  nodeTags.resize(numEdgesPerEle * numNodesPerEdge * numElements);
4524  }
4525  const size_t begin = (task * numElements) / numTasks;
4526  const size_t end = ((task + 1) * numElements) / numTasks;
4527  size_t o = 0;
4528  size_t idx = numEdgesPerEle * numNodesPerEdge * begin;
4529  for(std::size_t i = 0; i < entities.size(); i++) {
4530  GEntity *ge = entities[i];
4531  for(std::size_t j = 0; j < ge->getNumMeshElementsByType(familyType); j++) {
4532  if(o >= begin && o < end) {
4533  MElement *e = ge->getMeshElementByType(familyType, j);
4534  for(int k = 0; k < numEdgesPerEle; k++) {
4535  std::vector<MVertex *> v;
4536  // we could use e->getHighOrderEdge() here if we decide to remove
4537  // getEdgeVertices
4538  e->getEdgeVertices(k, v);
4539  std::size_t N = primary ? 2 : v.size();
4540  for(std::size_t l = 0; l < N; l++) {
4541  nodeTags[idx++] = v[l]->getNum();
4542  }
4543  }
4544  }
4545  o++;
4546  }
4547  }
4548 }
4549 
4550 GMSH_API void gmsh::model::mesh::getElementFaceNodes(
4551  const int elementType, const int faceType, std::vector<std::size_t> &nodeTags,
4552  const int tag, const bool primary, const std::size_t task,
4553  const std::size_t numTasks)
4554 {
4555  if(!_checkInit()) return;
4556  int dim = ElementType::getDimension(elementType);
4557  std::map<int, std::vector<GEntity *> > typeEnt;
4558  _getEntitiesForElementTypes(dim, tag, typeEnt);
4559  const std::vector<GEntity *> &entities(typeEnt[elementType]);
4560  int familyType = ElementType::getParentType(elementType);
4561  std::size_t numElements = 0;
4562  int numFacesPerEle = 0, numNodesPerFace = 0;
4563  for(std::size_t i = 0; i < entities.size(); i++) {
4564  GEntity *ge = entities[i];
4565  int n = ge->getNumMeshElementsByType(familyType);
4566  if(n && !numNodesPerFace) {
4567  MElement *e = ge->getMeshElementByType(familyType, 0);
4568  int nf = e->getNumFaces();
4569  numFacesPerEle = 0;
4570  for(int k = 0; k < nf; k++) {
4571  MFace f = e->getFace(k);
4572  if(faceType == (int)f.getNumVertices()) {
4573  numFacesPerEle++;
4574  if(!numNodesPerFace) {
4575  if(primary) { numNodesPerFace = faceType; }
4576  else {
4577  std::vector<MVertex *> v;
4578  // we could use e->getHighOrderFace() here if we decide to remove
4579  // getFaceVertices
4580  e->getFaceVertices(k, v);
4581  numNodesPerFace = v.size();
4582  }
4583  }
4584  }
4585  }
4586  }
4587  numElements += n;
4588  }
4589 
4590  if(!numTasks) {
4591  Msg::Error("Number of tasks should be > 0");
4592  return;
4593  }
4594  if(!numElements || !numFacesPerEle || !numNodesPerFace) return;
4595  if(numFacesPerEle * numNodesPerFace * numElements > nodeTags.size()) {
4596  if(numTasks > 1)
4597  Msg::Warning("Nodes should be preallocated if numTasks > 1");
4598  nodeTags.resize(numFacesPerEle * numNodesPerFace * numElements);
4599  }
4600  const size_t begin = (task * numElements) / numTasks;
4601  const size_t end = ((task + 1) * numElements) / numTasks;
4602  size_t o = 0;
4603  size_t idx = numFacesPerEle * numNodesPerFace * begin;
4604  for(std::size_t i = 0; i < entities.size(); i++) {
4605  GEntity *ge = entities[i];
4606  for(std::size_t j = 0; j < ge->getNumMeshElementsByType(familyType); j++) {
4607  if(o >= begin && o < end) {
4608  MElement *e = ge->getMeshElementByType(familyType, j);
4609  int nf = e->getNumFaces();
4610  for(int k = 0; k < nf; k++) {
4611  MFace f = e->getFace(k);
4612  if(faceType != (int)f.getNumVertices()) continue;
4613  std::vector<MVertex *> v;
4614  // we could use e->getHighOrderFace() here if we decide to remove
4615  // getFaceVertices
4616  e->getFaceVertices(k, v);
4617  std::size_t N = primary ? faceType : v.size();
4618  for(std::size_t l = 0; l < N; l++) {
4619  nodeTags[idx++] = v[l]->getNum();
4620  }
4621  }
4622  }
4623  o++;
4624  }
4625  }
4626 }
4627 
4628 GMSH_API void
4629 gmsh::model::mesh::getGhostElements(const int dim, const int tag,
4630  std::vector<std::size_t> &elementTags,
4631  std::vector<int> &partitions)
4632 {
4633  if(!_checkInit()) return;
4634  elementTags.clear();
4635  partitions.clear();
4636  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
4637  if(!ge) {
4638  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
4639  return;
4640  }
4641  std::map<MElement *, int> ghostCells;
4642  if(ge->geomType() == GEntity::GhostCurve)
4643  ghostCells = static_cast<ghostEdge *>(ge)->getGhostCells();
4644  else if(ge->geomType() == GEntity::GhostSurface)
4645  ghostCells = static_cast<ghostFace *>(ge)->getGhostCells();
4646  else if(ge->geomType() == GEntity::GhostVolume)
4647  ghostCells = static_cast<ghostRegion *>(ge)->getGhostCells();
4648 
4649  for(auto it = ghostCells.begin(); it != ghostCells.end(); it++) {
4650  elementTags.push_back(it->first->getNum());
4651  partitions.push_back(it->second);
4652  }
4653 }
4654 
4655 GMSH_API void gmsh::model::mesh::setSize(const vectorpair &dimTags,
4656  const double size)
4657 {
4658  if(!_checkInit()) return;
4659  for(std::size_t i = 0; i < dimTags.size(); i++) {
4660  int dim = dimTags[i].first, tag = dimTags[i].second;
4661  if(dim == 0) {
4662  GVertex *gv = GModel::current()->getVertexByTag(tag);
4663  if(gv) gv->setPrescribedMeshSizeAtVertex(size);
4664  }
4665  }
4666 }
4667 
4668 GMSH_API void gmsh::model::mesh::getSizes(const vectorpair &dimTags,
4669  std::vector<double> &sizes)
4670 {
4671  if(!_checkInit()) return;
4672  sizes.clear();
4673  if(dimTags.empty()) return;
4674  sizes.resize(dimTags.size(), 0.);
4675  for(std::size_t i = 0; i < dimTags.size(); i++) {
4676  int dim = dimTags[i].first, tag = dimTags[i].second;
4677  if(dim == 0) {
4678  GVertex *gv = GModel::current()->getVertexByTag(tag);
4679  if(gv) {
4680  double s = gv->prescribedMeshSizeAtVertex();
4681  if(s != MAX_LC) sizes[i] = s;
4682  }
4683  }
4684  }
4685 }
4686 
4687 GMSH_API void gmsh::model::mesh::setSizeAtParametricPoints(
4688  const int dim, const int tag, const std::vector<double> &parametricCoord,
4689  const std::vector<double> &sizes)
4690 {
4691  if(!_checkInit()) return;
4692  if(dim == 1) {
4693  GEdge *ge = GModel::current()->getEdgeByTag(tag);
4694  if(ge) ge->setMeshSizeParametric(parametricCoord, sizes);
4695  }
4696 }
4697 
4698 GMSH_API void gmsh::model::mesh::setSizeCallback(
4699  std::function<double(int, int, double, double, double, double)> callback)
4700 {
4701  if(!_checkInit()) return;
4702  GModel::current()->lcCallback = callback;
4703 }
4704 
4705 GMSH_API void gmsh::model::mesh::removeSizeCallback()
4706 {
4707  if(!_checkInit()) return;
4708  GModel::current()->lcCallback = nullptr;
4709 }
4710 
4711 GMSH_API void
4712 gmsh::model::mesh::setTransfiniteCurve(const int tag, const int numNodes,
4713  const std::string &meshType,
4714  const double coef)
4715 {
4716  if(!_checkInit()) return;
4717  // for compatibility with geo files, try both tag and -tag
4718  for(int sig = -1; sig <= 1; sig += 2) {
4719  int t = sig * tag;
4720  GEdge *ge = GModel::current()->getEdgeByTag(t);
4721  if(ge) {
4723  ge->meshAttributes.nbPointsTransfinite = numNodes;
4725  (meshType == "Progression" || meshType == "Power") ? 1 :
4726  (meshType == "Bump") ? 2 :
4727  (meshType == "Beta") ? 3 :
4728  1;
4729  ge->meshAttributes.coeffTransfinite = std::abs(coef);
4730  // in .geo file we use a negative tag to do this trick; it's a bad idea
4731  if(coef < 0) ge->meshAttributes.typeTransfinite *= -1;
4732  }
4733  else {
4734  if(t > 0) {
4735  Msg::Error("%s does not exist", _getEntityName(1, t).c_str());
4736  return;
4737  }
4738  }
4739  }
4740 }
4741 
4742 GMSH_API void
4743 gmsh::model::mesh::setTransfiniteSurface(const int tag,
4744  const std::string &arrangement,
4745  const std::vector<int> &cornerTags)
4746 {
4747  if(!_checkInit()) return;
4748  GFace *gf = GModel::current()->getFaceByTag(tag);
4749  if(!gf) {
4750  Msg::Error("%s does not exist", _getEntityName(2, tag).c_str());
4751  return;
4752  }
4755  (arrangement == "Right") ? 1 :
4756  (arrangement == "Left") ? -1 :
4757  (arrangement == "AlternateRight") ? 2 :
4758  (arrangement == "AlternateLeft") ? -2 :
4759  (arrangement == "Alternate") ? 2 :
4760  -1;
4761  if(cornerTags.empty() || cornerTags.size() == 3 || cornerTags.size() == 4) {
4762  for(std::size_t j = 0; j < cornerTags.size(); j++) {
4763  GVertex *gv = GModel::current()->getVertexByTag(cornerTags[j]);
4764  if(gv) gf->meshAttributes.corners.push_back(gv);
4765  }
4766  }
4767 }
4768 
4769 GMSH_API void
4770 gmsh::model::mesh::setTransfiniteVolume(const int tag,
4771  const std::vector<int> &cornerTags)
4772 {
4773  if(!_checkInit()) return;
4774  GRegion *gr = GModel::current()->getRegionByTag(tag);
4775  if(!gr) {
4776  Msg::Error("%s does not exist", _getEntityName(3, tag).c_str());
4777  return;
4778  }
4780  if(cornerTags.empty() || cornerTags.size() == 6 || cornerTags.size() == 8) {
4781  for(std::size_t i = 0; i < cornerTags.size(); i++) {
4782  GVertex *gv = GModel::current()->getVertexByTag(cornerTags[i]);
4783  if(gv) gr->meshAttributes.corners.push_back(gv);
4784  }
4785  }
4786 }
4787 
4789 {
4790  std::set<GVertex *> vertices;
4791  std::set<GEdge *> edges;
4792  for(std::size_t _i = 0; _i < gr->faces().size(); ++_i) {
4793  GFace *gf = gr->faces()[_i];
4794  for(std::size_t j = 0; j < gf->edges().size(); ++j) {
4795  GEdge *ge = gf->edges()[j];
4796  edges.insert(ge);
4797  vertices.insert(ge->getBeginVertex());
4798  vertices.insert(ge->getEndVertex());
4799  }
4800  }
4801  int X = int(vertices.size()) - int(edges.size()) + int(gr->faces().size());
4802  return X;
4803 }
4804 
4805 GMSH_API void gmsh::model::mesh::setTransfiniteAutomatic(
4806  const vectorpair &dimTags, const double cornerAngle, const bool recombine)
4807 {
4808 #if defined(HAVE_MESH)
4809  if(!_checkInit()) return;
4810  Msg::Debug("setTransfiniteAutomatic() with cornerAngle=%.3f, recombine=%i",
4811  cornerAngle, int(recombine));
4812 
4813  // Collect all quad 4-sided faces (from given faces and volumes)
4814  std::set<GFace *> faces;
4815  if(dimTags.size() == 0) { // Empty dimTag => all faces
4816  std::vector<GEntity *> entities;
4817  GModel::current()->getEntities(entities, 2);
4818  for(std::size_t i = 0; i < entities.size(); i++) {
4819  GFace *gf = static_cast<GFace *>(entities[i]);
4820  if(gf->edges().size() == 4) { faces.insert(gf); }
4821  }
4822  }
4823  else {
4824  for(std::size_t i = 0; i < dimTags.size(); ++i) {
4825  if(dimTags[i].first == 2) {
4826  int tag = dimTags[i].second;
4827  GFace *gf = GModel::current()->getFaceByTag(tag);
4828  if(!gf) {
4829  Msg::Error("%s does not exist", _getEntityName(2, tag).c_str());
4830  return;
4831  }
4832  if(gf->edges().size() == 4) { faces.insert(gf); }
4833  }
4834  else if(dimTags[i].first == 3) {
4835  int tag = dimTags[i].second;
4836  GRegion *gr = GModel::current()->getRegionByTag(tag);
4837  if(!gr) {
4838  Msg::Error("%s does not exist", _getEntityName(3, tag).c_str());
4839  return;
4840  }
4841  for(GFace *gf : gr->faces()) {
4842  if(gf->edges().size() == 4) { faces.insert(gf); }
4843  }
4844  }
4845  }
4846  }
4847 
4848  // Build the chords, compute the averaged number of points on each chord,
4849  // assign the transfinite attributes
4850  bool okf = MeshSetTransfiniteFacesAutomatic(faces, cornerAngle, recombine);
4851  if(!okf) {
4852  Msg::Error("failed to automatically set transfinite faces");
4853  return;
4854  }
4855 
4856  // Collect the 6-sided volumes with Euler characteristic equal to 2 (ie ball)
4857  std::set<GRegion *> regions;
4858  if(dimTags.size() == 0) { // Empty dimTag => all faces
4859  std::vector<GEntity *> entities;
4860  GModel::current()->getEntities(entities, 3);
4861  for(std::size_t i = 0; i < entities.size(); i++) {
4862  GRegion *gr = static_cast<GRegion *>(entities[i]);
4863  if(gr->faces().size() == 6 && _eulerCharacteristic(gr) == 2) {
4864  regions.insert(gr);
4865  }
4866  }
4867  }
4868  else {
4869  for(std::size_t i = 0; i < dimTags.size(); ++i) {
4870  if(dimTags[i].first == 3) {
4871  int tag = dimTags[i].second;
4872  GRegion *gr = GModel::current()->getRegionByTag(tag);
4873  if(!gr) {
4874  Msg::Error("%s does not exist", _getEntityName(3, tag).c_str());
4875  return;
4876  }
4877  if(gr->faces().size() == 6 && _eulerCharacteristic(gr) == 2) {
4878  regions.insert(gr);
4879  }
4880  }
4881  }
4882  }
4883 
4884  std::size_t nr = 0;
4885  for(GRegion *gr : regions) {
4886  bool transfinite = true;
4887  for(GFace *gf : gr->faces()) {
4889  transfinite = false;
4890  break;
4891  }
4892  if(transfinite) {
4894  nr += 1;
4895  }
4896  }
4897  }
4898  if(nr > 0)
4899  Msg::Debug("transfinite automatic: transfinite set on %li volumes", nr);
4900 #else
4901  Msg::Error("setTransfiniteAutomatic requires the mesh module");
4902 #endif
4903 }
4904 
4905 GMSH_API void gmsh::model::mesh::setRecombine(const int dim, const int tag,
4906  const double angle)
4907 {
4908  if(!_checkInit()) return;
4909  if(dim == 2) {
4910  GFace *gf = GModel::current()->getFaceByTag(tag);
4911  if(!gf) {
4912  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
4913  return;
4914  }
4915  gf->meshAttributes.recombine = 1;
4917  }
4918 }
4919 
4920 GMSH_API void gmsh::model::mesh::setSmoothing(const int dim, const int tag,
4921  const int val)
4922 {
4923  if(!_checkInit()) return;
4924  if(dim == 2) {
4925  GFace *gf = GModel::current()->getFaceByTag(tag);
4926  if(!gf) {
4927  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
4928  return;
4929  }
4931  }
4932 }
4933 
4934 GMSH_API void gmsh::model::mesh::setReverse(const int dim, const int tag,
4935  const bool val)
4936 {
4937  if(!_checkInit()) return;
4938  if(dim == 1) {
4939  GEdge *ge = GModel::current()->getEdgeByTag(tag);
4940  if(!ge) {
4941  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
4942  return;
4943  }
4944  ge->meshAttributes.reverseMesh = val;
4945  }
4946  else if(dim == 2) {
4947  GFace *gf = GModel::current()->getFaceByTag(tag);
4948  if(!gf) {
4949  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
4950  return;
4951  }
4952  gf->meshAttributes.reverseMesh = val;
4953  }
4954 }
4955 
4956 GMSH_API void gmsh::model::mesh::setAlgorithm(const int dim, const int tag,
4957  const int val)
4958 {
4959  if(!_checkInit()) return;
4960  if(dim == 2) {
4961  GFace *gf = GModel::current()->getFaceByTag(tag);
4962  if(!gf) {
4963  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
4964  return;
4965  }
4966  gf->meshAttributes.algorithm = val;
4967  }
4968 }
4969 
4970 GMSH_API void gmsh::model::mesh::setSizeFromBoundary(const int dim,
4971  const int tag,
4972  const int val)
4973 {
4974  if(!_checkInit()) return;
4975  if(dim == 2) {
4976  GFace *gf = GModel::current()->getFaceByTag(tag);
4977  if(!gf) {
4978  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
4979  return;
4980  }
4982  }
4983 }
4984 
4985 GMSH_API void gmsh::model::mesh::setCompound(const int dim,
4986  const std::vector<int> &tags)
4987 {
4988  if(!_checkInit()) return;
4989  std::vector<GEntity *> ents;
4990  for(std::size_t i = 0; i < tags.size(); i++) {
4991  GEntity *ent = GModel::current()->getEntityByTag(dim, tags[i]);
4992  if(ent) { ents.push_back(ent); }
4993  else {
4994  Msg::Error("%s does not exist", _getEntityName(dim, tags[i]).c_str());
4995  }
4996  }
4997  for(std::size_t i = 0; i < ents.size(); i++) { ents[i]->compound = ents; }
4998 }
4999 
5000 GMSH_API void gmsh::model::mesh::setOutwardOrientation(const int tag)
5001 {
5002  if(!_checkInit()) return;
5003  GRegion *gr = GModel::current()->getRegionByTag(tag);
5004  if(!gr) {
5005  Msg::Error("%s does not exist", _getEntityName(3, tag).c_str());
5006  return;
5007  }
5009 }
5010 
5011 GMSH_API void gmsh::model::mesh::removeConstraints(const vectorpair &dimTags)
5012 {
5013  if(!_checkInit()) return;
5014  std::vector<GEntity *> entities;
5015  _getEntities(dimTags, entities);
5016  for(std::size_t i = 0; i < entities.size(); i++)
5017  entities[i]->resetMeshAttributes();
5018 }
5019 
5020 GMSH_API void gmsh::model::mesh::embed(const int dim,
5021  const std::vector<int> &tags,
5022  const int inDim, const int inTag)
5023 {
5024  if(!_checkInit()) return;
5025  if(inDim == 2) {
5026  GFace *gf = GModel::current()->getFaceByTag(inTag);
5027  if(!gf) {
5028  Msg::Error("%s does not exist", _getEntityName(2, inTag).c_str());
5029  return;
5030  }
5031  for(std::size_t i = 0; i < tags.size(); i++) {
5032  if(dim == 0) {
5034  if(!gv) {
5035  Msg::Error("%s does not exist", _getEntityName(0, tags[i]).c_str());
5036  return;
5037  }
5038  gf->addEmbeddedVertex(gv);
5039  }
5040  else if(dim == 1) {
5041  GEdge *ge = GModel::current()->getEdgeByTag(tags[i]);
5042  if(!ge) {
5043  Msg::Error("%s does not exist", _getEntityName(1, tags[i]).c_str());
5044  return;
5045  }
5046  gf->addEmbeddedEdge(ge);
5047  }
5048  }
5049  }
5050  else if(inDim == 3) {
5051  GRegion *gr = GModel::current()->getRegionByTag(inTag);
5052  if(!gr) {
5053  Msg::Error("%s does not exist", _getEntityName(3, inTag).c_str());
5054  return;
5055  }
5056  for(std::size_t i = 0; i < tags.size(); i++) {
5057  if(dim == 0) {
5059  if(!gv) {
5060  Msg::Error("%s does not exist", _getEntityName(0, tags[i]).c_str());
5061  return;
5062  }
5063  gr->addEmbeddedVertex(gv);
5064  }
5065  else if(dim == 1) {
5066  GEdge *ge = GModel::current()->getEdgeByTag(tags[i]);
5067  if(!ge) {
5068  Msg::Error("%s does not exist", _getEntityName(1, tags[i]).c_str());
5069  return;
5070  }
5071  gr->addEmbeddedEdge(ge);
5072  }
5073  else if(dim == 2) {
5074  GFace *gf = GModel::current()->getFaceByTag(tags[i]);
5075  if(!gf) {
5076  Msg::Error("%s does not exist", _getEntityName(2, tags[i]).c_str());
5077  return;
5078  }
5079  gr->addEmbeddedFace(gf);
5080  }
5081  }
5082  }
5083 }
5084 
5085 GMSH_API void gmsh::model::mesh::removeEmbedded(const vectorpair &dimTags,
5086  const int rdim)
5087 {
5088  if(!_checkInit()) return;
5089  for(std::size_t i = 0; i < dimTags.size(); i++) {
5090  int dim = dimTags[i].first, tag = dimTags[i].second;
5091  if(dim == 2) {
5092  GFace *gf = GModel::current()->getFaceByTag(tag);
5093  if(!gf) {
5094  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
5095  return;
5096  }
5097  if(rdim < 0 || rdim == 1) gf->embeddedEdges().clear();
5098  if(rdim < 0 || rdim == 0) gf->embeddedVertices().clear();
5099  }
5100  else if(dimTags[i].first == 3) {
5101  GRegion *gr = GModel::current()->getRegionByTag(tag);
5102  if(!gr) {
5103  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
5104  return;
5105  }
5106  if(rdim < 0 || rdim == 2) gr->embeddedFaces().clear();
5107  if(rdim < 0 || rdim == 1) gr->embeddedEdges().clear();
5108  if(rdim < 0 || rdim == 0) gr->embeddedVertices().clear();
5109  }
5110  }
5111 }
5112 
5113 GMSH_API void gmsh::model::mesh::getEmbedded(const int dim, const int tag,
5114  vectorpair &dimTags)
5115 {
5116  if(!_checkInit()) return;
5117  dimTags.clear();
5118  if(dim == 2) {
5119  GFace *gf = GModel::current()->getFaceByTag(tag);
5120  if(!gf) {
5121  Msg::Error("%s does not exist", _getEntityName(2, tag).c_str());
5122  return;
5123  }
5124  for(auto v : gf->embeddedVertices())
5125  dimTags.push_back(std::make_pair(v->dim(), v->tag()));
5126  for(auto e : gf->embeddedEdges())
5127  dimTags.push_back(std::make_pair(e->dim(), e->tag()));
5128  }
5129  else if(dim == 3) {
5130  GRegion *gr = GModel::current()->getRegionByTag(tag);
5131  if(!gr) {
5132  Msg::Error("%s does not exist", _getEntityName(3, tag).c_str());
5133  return;
5134  }
5135  for(auto v : gr->embeddedVertices())
5136  dimTags.push_back(std::make_pair(v->dim(), v->tag()));
5137  for(auto e : gr->embeddedEdges())
5138  dimTags.push_back(std::make_pair(e->dim(), e->tag()));
5139  for(auto f : gr->embeddedFaces())
5140  dimTags.push_back(std::make_pair(f->dim(), f->tag()));
5141  }
5142 }
5143 
5144 GMSH_API void
5145 gmsh::model::mesh::reorderElements(const int elementType, const int tag,
5146  const std::vector<std::size_t> &ordering)
5147 {
5148  if(!_checkInit()) return;
5149  int dim = ElementType::getDimension(elementType);
5150  std::map<int, std::vector<GEntity *> > typeEnt;
5151  _getEntitiesForElementTypes(dim, tag, typeEnt);
5152  const std::vector<GEntity *> &entities(typeEnt[elementType]);
5153  if(entities.empty()) {
5154  Msg::Error("No elements to reorder");
5155  return;
5156  }
5157  for(std::size_t i = 0; i < entities.size(); i++) {
5158  if(!entities[i]->reorder(elementType, ordering)) {
5159  Msg::Error("Could not reorder elements");
5160  return;
5161  }
5162  }
5163 }
5164 
5165 GMSH_API void gmsh::model::mesh::renumberNodes()
5166 {
5167  if(!_checkInit()) return;
5169 }
5170 
5171 GMSH_API void gmsh::model::mesh::renumberElements()
5172 {
5173  if(!_checkInit()) return;
5175 }
5176 
5177 GMSH_API void
5178 gmsh::model::mesh::setPeriodic(const int dim, const std::vector<int> &tags,
5179  const std::vector<int> &tagsMaster,
5180  const std::vector<double> &affineTransform)
5181 {
5182  if(!_checkInit()) return;
5183  if(tags.size() != tagsMaster.size()) {
5184  Msg::Error("Incompatible number of tags and master tags for periodic mesh");
5185  return;
5186  }
5187  if(affineTransform.size() != 16) {
5188  Msg::Error("Wrong number of elements in affine transformation (%d != 16)",
5189  (int)affineTransform.size());
5190  return;
5191  }
5192  for(std::size_t i = 0; i < tags.size(); i++) {
5193  if(dim == 1) {
5194  GEdge *target = GModel::current()->getEdgeByTag(tags[i]);
5195  if(!target) {
5196  Msg::Error("%s does not exist", _getEntityName(dim, tags[i]).c_str());
5197  return;
5198  }
5199  GEdge *source = GModel::current()->getEdgeByTag(tagsMaster[i]);
5200  if(!source) {
5201  Msg::Error("%s does not exist",
5202  _getEntityName(dim, tagsMaster[i]).c_str());
5203  return;
5204  }
5205  target->setMeshMaster(source, affineTransform);
5206  }
5207  else if(dim == 2) {
5208  GFace *target = GModel::current()->getFaceByTag(tags[i]);
5209  if(!target) {
5210  Msg::Error("%s does not exist", _getEntityName(dim, tags[i]).c_str());
5211  return;
5212  }
5213  GFace *source = GModel::current()->getFaceByTag(tagsMaster[i]);
5214  if(!source) {
5215  Msg::Error("%s does not exist",
5216  _getEntityName(dim, tagsMaster[i]).c_str());
5217  return;
5218  }
5219  target->setMeshMaster(source, affineTransform);
5220  }
5221  }
5222 }
5223 
5224 GMSH_API void
5225 gmsh::model::mesh::getPeriodic(const int dim, const std::vector<int> &tags,
5226  std::vector<int> &tagsMaster)
5227 {
5228  if(!_checkInit()) return;
5229  tagsMaster.clear();
5230  tagsMaster.reserve(tags.size());
5231  for(auto i : tags) {
5232  GEntity *ge = GModel::current()->getEntityByTag(dim, i);
5233  if(!ge) {
5234  Msg::Error("%s does not exist", _getEntityName(dim, i).c_str());
5235  return;
5236  }
5237  tagsMaster.push_back(ge->getMeshMaster()->tag());
5238  }
5239 }
5240 
5241 GMSH_API void gmsh::model::mesh::getPeriodicNodes(
5242  const int dim, const int tag, int &tagMaster,
5243  std::vector<std::size_t> &nodeTags, std::vector<std::size_t> &nodeTagsMaster,
5244  std::vector<double> &affineTransform, const bool includeHighOrderNodes)
5245 {
5246  if(!_checkInit()) return;
5247  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
5248  if(!ge) {
5249  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
5250  return;
5251  }
5252  if(ge->getMeshMaster() != ge) {
5253  tagMaster = ge->getMeshMaster()->tag();
5254  for(auto it = ge->correspondingVertices.begin();
5255  it != ge->correspondingVertices.end(); ++it) {
5256  nodeTags.push_back(it->first->getNum());
5257  nodeTagsMaster.push_back(it->second->getNum());
5258  }
5259  if(includeHighOrderNodes) {
5260  for(auto it = ge->correspondingHighOrderVertices.begin();
5261  it != ge->correspondingHighOrderVertices.end(); ++it) {
5262  nodeTags.push_back(it->first->getNum());
5263  nodeTagsMaster.push_back(it->second->getNum());
5264  }
5265  }
5266  affineTransform = ge->affineTransform;
5267  }
5268  else {
5269  tagMaster = tag;
5270  nodeTags.clear();
5271  nodeTagsMaster.clear();
5272  affineTransform.clear();
5273  }
5274 }
5275 
5276 GMSH_API void gmsh::model::mesh::getPeriodicKeys(
5277  const int elementType, const std::string &functionSpaceType,
5278  const int tag, int &tagMaster,
5279  std::vector<int> &typeKeys, std::vector<int> &typeKeysMaster,
5280  std::vector<std::size_t> &entityKeys, std::vector<std::size_t> &entityKeysMaster,
5281  std::vector<double> &coord, std::vector<double> &coordMaster,
5282  const bool returnCoord)
5283 {
5284  if(!_checkInit()) return;
5285  int dim = ElementType::getDimension(elementType);
5286  GEntity *ge = GModel::current()->getEntityByTag(dim, tag);
5287  if(!ge) {
5288  Msg::Error("%s does not exist", _getEntityName(dim, tag).c_str());
5289  return;
5290  }
5291  if(ge->getMeshMaster() == ge) { // not periodic
5292  tagMaster = tag;
5293  typeKeys.clear();
5294  typeKeysMaster.clear();
5295  entityKeys.clear();
5296  entityKeysMaster.clear();
5297  return;
5298  }
5299 
5300  tagMaster = ge->getMeshMaster()->tag();
5301  getKeys(elementType, functionSpaceType,
5302  typeKeys, entityKeys, coord, tag, returnCoord);
5303  typeKeysMaster = typeKeys;
5304  entityKeysMaster = entityKeys;
5305  coordMaster = coord;
5306 
5307  int nthreads = CTX::instance()->numThreads;
5308  if(!nthreads) nthreads = Msg::GetMaxThreads();
5309 
5310  if(functionSpaceType == "IsoParametric" ||
5311  functionSpaceType == "Lagrange") {
5312 #pragma omp parallel for num_threads(nthreads)
5313  for(std::size_t i = 0; i < entityKeys.size(); i++) {
5314  MVertex v(0., 0., 0., nullptr, entityKeys[i]);
5315  auto mv = ge->correspondingVertices.find(&v);
5316  if(mv != ge->correspondingVertices.end()) {
5317  entityKeysMaster[i] = mv->second->getNum();
5318  if(returnCoord) {
5319  coord[3 * i] = mv->second->x();
5320  coord[3 * i + 1] = mv->second->y();
5321  coord[3 * i + 2] = mv->second->z();
5322  }
5323  }
5324  else {
5325  auto mv2 = ge->correspondingHighOrderVertices.find(&v);
5326  if(mv2 != ge->correspondingHighOrderVertices.end()) {
5327  entityKeysMaster[i] = mv2->second->getNum();
5328  if(returnCoord) {
5329  coord[3 * i] = mv2->second->x();
5330  coord[3 * i + 1] = mv2->second->y();
5331  coord[3 * i + 2] = mv2->second->z();
5332  }
5333  }
5334  else{
5335  Msg::Warning("Unknown master node corresponding to node %d",
5336  entityKeys[i]);
5337  }
5338  }
5339  }
5340  }
5341  else{
5342  Msg::Error("Periodic key generation currently only available for "
5343  "\"IsoParametric\" and \"Lagrange\" function spaces");
5344  }
5345 }
5346 
5347 GMSH_API void gmsh::model::mesh::getDuplicateNodes(std::vector<std::size_t> &nodeTags,
5348  const vectorpair &dimTags)
5349 {
5350  if(!_checkInit()) return;
5351  GModel *m = GModel::current();
5352  SBoundingBox3d bbox = m->bounds();
5353  double lc = bbox.empty() ? 1. : bbox.diag();
5354  double eps = lc * CTX::instance()->geom.tolerance;
5355  std::vector<GEntity *> entities;
5356  _getEntities(dimTags, entities);
5357  std::vector<MVertex *> vertices;
5358  for(std::size_t i = 0; i < entities.size(); i++) {
5359  vertices.insert(vertices.end(), entities[i]->mesh_vertices.begin(),
5360  entities[i]->mesh_vertices.end());
5361  }
5362  MVertexRTree pos(eps);
5363  std::set<MVertex *, MVertexPtrLessThan> duplicates;
5364  pos.insert(vertices, true, &duplicates);
5365  for(auto n : duplicates) nodeTags.push_back(n->getNum());
5366 }
5367 
5368 GMSH_API void gmsh::model::mesh::removeDuplicateNodes(const vectorpair &dimTags)
5369 {
5370  if(!_checkInit()) return;
5371  std::vector<GEntity *> entities;
5372  _getEntities(dimTags, entities);
5374  CTX::instance()->geom.tolerance, entities);
5376 }
5377 
5378 GMSH_API void gmsh::model::mesh::removeDuplicateElements(const vectorpair &dimTags)
5379 {
5380  if(!_checkInit()) return;
5381  std::vector<GEntity *> entities;
5382  _getEntities(dimTags, entities);
5385 }
5386 
5388  const std::vector<size_t> &elementTags, const int value)
5389 {
5390  if(!_checkInit()) return;
5391  for(auto t : elementTags) {
5393  if(e) e->setVisibility(value);
5394  }
5395 }
5396 
5397 GMSH_API void gmsh::model::mesh::importStl()
5398 {
5399  if(!_checkInit()) return;
5400  GModel *m = GModel::current();
5401  m->deleteMesh();
5402  for(auto it = m->firstFace(); it != m->lastFace(); it++) {
5403  (*it)->buildSTLTriangulation();
5404  (*it)->storeSTLAsMesh();
5405  }
5406  for(auto it = m->firstEdge(); it != m->lastEdge(); it++) {
5407  (*it)->storeSTLAsMesh();
5408  }
5409 }
5410 
5411 GMSH_API void gmsh::model::mesh::classifySurfaces(
5412  const double angle, const bool boundary, const bool forReparametrization,
5413  const double curveAngle, const bool exportDiscrete)
5414 {
5415  if(!_checkInit()) return;
5416  GModel::current()->classifySurfaces(angle, boundary, forReparametrization,
5417  curveAngle);
5418  if(exportDiscrete) {
5419  // Warning: this clears GEO_Internals!
5421  }
5422 }
5423 
5424 GMSH_API void gmsh::model::mesh::createGeometry(const vectorpair &dimTags)
5425 {
5426  if(!_checkInit()) return;
5428 }
5429 
5430 GMSH_API void gmsh::model::mesh::createTopology(const bool makeSimplyConnected,
5431  const bool exportDiscrete)
5432 {
5433  if(!_checkInit()) return;
5434 
5435  if(makeSimplyConnected) {
5438  }
5440  if(exportDiscrete) {
5441  // Warning: this clears GEO_Internals!
5443  }
5444 }
5445 
5446 GMSH_API void
5447 gmsh::model::mesh::addHomologyRequest(const std::string &type,
5448  const std::vector<int> &domainTags,
5449  const std::vector<int> &subdomainTags,
5450  const std::vector<int> &dims)
5451 {
5452  if(!_checkInit()) return;
5453  GModel::current()->addHomologyRequest(type, domainTags, subdomainTags,
5454  dims);
5455 }
5456 
5457 GMSH_API void
5458 gmsh::model::mesh::clearHomologyRequests()
5459 {
5460  if(!_checkInit()) return;
5462 }
5463 
5464 GMSH_API void
5465 gmsh::model::mesh::computeHomology(vectorpair &dimTags)
5466 {
5467  if(!_checkInit()) return;
5468  GModel::current()->computeHomology(dimTags);
5469 }
5470 
5471 GMSH_API void gmsh::model::mesh::triangulate(const std::vector<double> &coord,
5472  std::vector<std::size_t> &tri)
5473 {
5474  if(!_checkInit()) return;
5475  tri.clear();
5476  if(coord.size() % 2) {
5477  Msg::Error("Number of 2D coordinates should be even");
5478  return;
5479  }
5480 #if defined(HAVE_MESH)
5481  SBoundingBox3d bbox;
5482  for(std::size_t i = 0; i < coord.size(); i += 2)
5483  bbox += SPoint3(coord[i], coord[i + 1], 0.);
5484  double lc = 10. * norm(SVector3(bbox.max(), bbox.min()));
5485  std::vector<MVertex *> verts(coord.size() / 2);
5486  std::size_t j = 0;
5487  for(std::size_t i = 0; i < coord.size(); i += 2) {
5488  double XX = 1.e-12 * lc * (double)rand() / (double)RAND_MAX;
5489  double YY = 1.e-12 * lc * (double)rand() / (double)RAND_MAX;
5490  MVertex *v = new MVertex(coord[i] + XX, coord[i + 1] + YY, 0.);
5491  v->setIndex(j);
5492  verts[j++] = v;
5493  }
5494  std::vector<MTriangle *> tris;
5495  delaunayMeshIn2D(verts, tris);
5496  if(tris.empty()) return;
5497  tri.resize(3 * tris.size());
5498  for(std::size_t i = 0; i < tris.size(); i++) {
5499  MTriangle *t = tris[i];
5500  for(std::size_t j = 0; j < 3; j++)
5501  tri[3 * i + j] = t->getVertex(j)->getIndex() + 1; // start at 1
5502  }
5503  for(std::size_t i = 0; i < verts.size(); i++) delete verts[i];
5504  for(std::size_t i = 0; i < tris.size(); i++) delete tris[i];
5505 #else
5506  Msg::Error("triangulate requires the mesh module");
5507 #endif
5508 }
5509 
5510 GMSH_API void
5511 gmsh::model::mesh::tetrahedralize(const std::vector<double> &coord,
5512  std::vector<std::size_t> &tetra)
5513 {
5514  if(!_checkInit()) return;
5515  tetra.clear();
5516  if(coord.size() % 3) {
5517  Msg::Error("Number of coordinates should be a multiple of 3");
5518  return;
5519  }
5520 #if defined(HAVE_MESH)
5521  std::vector<MVertex *> verts(coord.size() / 3);
5522  std::size_t j = 0;
5523  for(std::size_t i = 0; i < coord.size(); i += 3) {
5524  MVertex *v = new MVertex(coord[i], coord[i + 1], coord[i + 2]);
5525  v->setIndex(j);
5526  verts[j++] = v;
5527  }
5528  std::vector<MTetrahedron *> tets;
5529  if(CTX::instance()->mesh.algo3d == ALGO_3D_HXT)
5530  delaunayMeshIn3DHxt(verts, tets);
5531  else
5532  delaunayMeshIn3D(verts, tets, true);
5533  if(tets.empty()) return;
5534  tetra.resize(4 * tets.size());
5535  for(std::size_t i = 0; i < tets.size(); i++) {
5536  MTetrahedron *t = tets[i];
5537  for(std::size_t j = 0; j < 4; j++)
5538  tetra[4 * i + j] = t->getVertex(j)->getIndex() + 1; // start at 1
5539  }
5540  for(std::size_t i = 0; i < verts.size(); i++) delete verts[i];
5541  for(std::size_t i = 0; i < tets.size(); i++) delete tets[i];
5542 #else
5543  Msg::Error("tetrahedralize requires the mesh module");
5544 #endif
5545 }
5546 
5547 // gmsh::model::mesh::field
5548 
5549 GMSH_API int gmsh::model::mesh::field::add(const std::string &fieldType,
5550  const int tag)
5551 {
5552  if(!_checkInit()) return -1;
5553  int outTag = tag;
5554 #if defined(HAVE_MESH)
5555  if(outTag < 0) { outTag = GModel::current()->getFields()->newId(); }
5556  if(!GModel::current()->getFields()->newField(outTag, fieldType)) {
5557  Msg::Error("Cannot add Field %i of type '%s'", outTag, fieldType.c_str());
5558  return -1;
5559  }
5560 #if defined(HAVE_FLTK)
5561  if(FlGui::available()) FlGui::instance()->updateFields();
5562 #endif
5563 #else
5564  Msg::Error("Fields require the mesh module");
5565 #endif
5566  return outTag;
5567 }
5568 
5569 GMSH_API void gmsh::model::mesh::field::remove(const int tag)
5570 {
5571  if(!_checkInit()) return;
5572 #if defined(HAVE_MESH)
5574 #if defined(HAVE_FLTK)
5575  if(FlGui::available()) FlGui::instance()->updateFields();
5576 #endif
5577 #else
5578  Msg::Error("Fields require the mesh module");
5579 #endif
5580 }
5581 
5582 GMSH_API void gmsh::model::mesh::field::list(std::vector<int> &tags)
5583 {
5584  if(!_checkInit()) return;
5585  tags.clear();
5586 #if defined(HAVE_MESH)
5587  FieldManager &fields = *GModel::current()->getFields();
5588  for(auto it = fields.begin(); it != fields.end(); it++) {
5589  tags.push_back(it->first);
5590  }
5591 #else
5592  Msg::Error("Fields require the mesh module");
5593 #endif
5594 }
5595 
5596 GMSH_API void gmsh::model::mesh::field::getType(const int tag,
5597  std::string &fieldType)
5598 {
5599  if(!_checkInit()) return;
5600 #if defined(HAVE_MESH)
5601  Field *field = GModel::current()->getFields()->get(tag);
5602  if(!field) {
5603  Msg::Error("Unknown field %i", tag);
5604  return;
5605  }
5606  fieldType = field->getName();
5607 #else
5608  Msg::Error("Fields require the mesh module");
5609 #endif
5610 }
5611 
5612 #if defined(HAVE_MESH)
5613 static FieldOption *_getFieldOption(const int tag, const std::string &option)
5614 {
5615  Field *field = GModel::current()->getFields()->get(tag);
5616  if(!field) {
5617  Msg::Error("Unknown field %i", tag);
5618  return nullptr;
5619  }
5620  FieldOption *o = field->options[option];
5621  if(!o) {
5622  Msg::Error("Unknown option '%s' in field %i of type '%s'", option.c_str(),
5623  tag, field->getName());
5624  return nullptr;
5625  }
5626  return o;
5627 }
5628 #endif
5629 
5630 GMSH_API void gmsh::model::mesh::field::setNumber(const int tag,
5631  const std::string &option,
5632  const double value)
5633 {
5634  if(!_checkInit()) return;
5635 #if defined(HAVE_MESH)
5636  FieldOption *o = _getFieldOption(tag, option);
5637  if(!o) return;
5638  if(o->getType() != FIELD_OPTION_DOUBLE &&
5639  o->getType() != FIELD_OPTION_INT &&
5640  o->getType() != FIELD_OPTION_BOOL) {
5641  Msg::Warning("Field option '%s' is not a number", option.c_str());
5642  }
5643  o->numericalValue(value);
5644 #else
5645  Msg::Error("Fields require the mesh module");
5646 #endif
5647 }
5648 
5649 GMSH_API void gmsh::model::mesh::field::getNumber(const int tag,
5650  const std::string &option,
5651  double &value)
5652 {
5653  if(!_checkInit()) return;
5654 #if defined(HAVE_MESH)
5655  FieldOption *o = _getFieldOption(tag, option);
5656  if(!o) { return; }
5657  if(o->getType() != FIELD_OPTION_DOUBLE &&
5658  o->getType() != FIELD_OPTION_INT &&
5659  o->getType() != FIELD_OPTION_BOOL) {
5660  Msg::Warning("Field option '%s' is not a number", option.c_str());
5661  }
5662  value = o->numericalValue();
5663 #else
5664  Msg::Error("Fields require the mesh module");
5665 #endif
5666 }
5667 
5668 GMSH_API void gmsh::model::mesh::field::setString(const int tag,
5669  const std::string &option,
5670  const std::string &value)
5671 {
5672  if(!_checkInit()) return;
5673 #if defined(HAVE_MESH)
5674  FieldOption *o = _getFieldOption(tag, option);
5675  if(!o) return;
5676  if(o->getType() != FIELD_OPTION_STRING &&
5677  o->getType() != FIELD_OPTION_PATH) {
5678  Msg::Warning("Field option '%s' is not a string", option.c_str());
5679  }
5680  o->string(value);
5681 #else
5682  Msg::Error("Fields require the mesh module");
5683 #endif
5684 }
5685 
5686 GMSH_API void gmsh::model::mesh::field::getString(const int tag,
5687  const std::string &option,
5688  std::string &value)
5689 {
5690  if(!_checkInit()) return;
5691 #if defined(HAVE_MESH)
5692  FieldOption *o = _getFieldOption(tag, option);
5693  if(!o) { return; }
5694  if(o->getType() != FIELD_OPTION_STRING &&
5695  o->getType() != FIELD_OPTION_PATH) {
5696  Msg::Warning("Field option '%s' is not a string", option.c_str());
5697  }
5698  value = o->string();
5699 #else
5700  Msg::Error("Fields require the mesh module");
5701 #endif
5702 }
5703 
5704 GMSH_API void
5705 gmsh::model::mesh::field::setNumbers(const int tag, const std::string &option,
5706  const std::vector<double> &values)
5707 {
5708  if(!_checkInit()) return;
5709 #if defined(HAVE_MESH)
5710  FieldOption *o = _getFieldOption(tag, option);
5711  if(!o) return;
5712  if(o->getType() == FIELD_OPTION_LIST) {
5713  std::list<int> vl;
5714  for(std::size_t i = 0; i < values.size(); i++) vl.push_back((int)values[i]);
5715  o->list(vl);
5716  }
5717  else {
5718  if(o->getType() != FIELD_OPTION_LIST_DOUBLE) {
5719  Msg::Warning("Field option '%s' is not a list", option.c_str());
5720  }
5721  std::list<double> vl;
5722  for(std::size_t i = 0; i < values.size(); i++) vl.push_back(values[i]);
5723  o->listdouble(vl);
5724  }
5725 #else
5726  Msg::Error("Fields require the mesh module");
5727 #endif
5728 }
5729 
5730 GMSH_API void
5731 gmsh::model::mesh::field::getNumbers(const int tag, const std::string &option,
5732  std::vector<double> &values)
5733 {
5734  if(!_checkInit()) return;
5735  values.clear();
5736 #if defined(HAVE_MESH)
5737  FieldOption *o = _getFieldOption(tag, option);
5738  if(!o) { return; }
5739  if(o->getType() == FIELD_OPTION_LIST) {
5740  std::list<int> vl = o->list();
5741  for(auto i : vl) values.push_back(i);
5742  }
5743  else {
5744  if(o->getType() != FIELD_OPTION_LIST_DOUBLE) {
5745  Msg::Warning("Field option '%s' is not a list", option.c_str());
5746  }
5747  std::list<double> vl = o->listdouble();
5748  for(auto d : vl) values.push_back(d);
5749  }
5750 #else
5751  Msg::Error("Fields require the mesh module");
5752 #endif
5753 }
5754 
5755 GMSH_API void gmsh::model::mesh::field::setAsBackgroundMesh(const int tag)
5756 {
5757  if(!_checkInit()) return;
5758 #if defined(HAVE_MESH)
5760 #else
5761  Msg::Error("Fields require the mesh module");
5762 #endif
5763 }
5764 
5765 GMSH_API void gmsh::model::mesh::field::setAsBoundaryLayer(const int tag)
5766 {
5767  if(!_checkInit()) return;
5768 #if defined(HAVE_MESH)
5770 #else
5771  Msg::Error("Fields require the mesh module");
5772 #endif
5773 }
5774 
5775 // gmsh::model::geo
5776 
5777 GMSH_API int gmsh::model::geo::addPoint(const double x, const double y,
5778  const double z, const double meshSize,
5779  const int tag)
5780 {
5781  if(!_checkInit()) return -1;
5782  int outTag = tag;
5783  double xx = CTX::instance()->geom.scalingFactor * x;
5784  double yy = CTX::instance()->geom.scalingFactor * y;
5785  double zz = CTX::instance()->geom.scalingFactor * z;
5786  double lc = CTX::instance()->geom.scalingFactor * meshSize;
5787  GModel::current()->getGEOInternals()->addVertex(outTag, xx, yy, zz, lc);
5788  return outTag;
5789 }
5790 
5791 GMSH_API int gmsh::model::geo::addLine(const int startTag, const int endTag,
5792  const int tag)
5793 {
5794  if(!_checkInit()) return -1;
5795  int outTag = tag;
5796  GModel::current()->getGEOInternals()->addLine(outTag, startTag, endTag);
5797  return outTag;
5798 }
5799 
5800 GMSH_API int gmsh::model::geo::addCircleArc(const int startTag,
5801  const int centerTag,
5802  const int endTag, const int tag,
5803  const double nx, const double ny,
5804  const double nz)
5805 {
5806  if(!_checkInit()) return -1;
5807  int outTag = tag;
5809  outTag, startTag, centerTag, endTag, nx, ny, nz);
5810  return outTag;
5811 }
5812 
5813 GMSH_API int gmsh::model::geo::addEllipseArc(
5814  const int startTag, const int centerTag, const int majorTag, const int endTag,
5815  const int tag, const double nx, const double ny, const double nz)
5816 {
5817  if(!_checkInit()) return -1;
5818  int outTag = tag;
5820  outTag, startTag, centerTag, majorTag, endTag, nx, ny, nz);
5821  return outTag;
5822 }
5823 
5824 GMSH_API int gmsh::model::geo::addSpline(const std::vector<int> &pointTags,
5825  const int tag)
5826 {
5827  if(!_checkInit()) return -1;
5828  int outTag = tag;
5829  GModel::current()->getGEOInternals()->addSpline(outTag, pointTags);
5830  return outTag;
5831 }
5832 
5833 GMSH_API int gmsh::model::geo::addBSpline(const std::vector<int> &pointTags,
5834  const int tag)
5835 {
5836  if(!_checkInit()) return -1;
5837  int outTag = tag;
5838  GModel::current()->getGEOInternals()->addBSpline(outTag, pointTags);
5839  return outTag;
5840 }
5841 
5842 GMSH_API int gmsh::model::geo::addBezier(const std::vector<int> &pointTags,
5843  const int tag)
5844 {
5845  if(!_checkInit()) return -1;
5846  int outTag = tag;
5847  GModel::current()->getGEOInternals()->addBezier(outTag, pointTags);
5848  return outTag;
5849 }
5850 
5851 GMSH_API int gmsh::model::geo::addPolyline(const std::vector<int> &pointTags,
5852  const int tag)
5853 {
5854  if(!_checkInit()) return -1;
5855  int outTag = tag;
5856  GModel::current()->getGEOInternals()->addLine(outTag, pointTags);
5857  return outTag;
5858 }
5859 
5860 GMSH_API int
5861 gmsh::model::geo::addCompoundSpline(const std::vector<int> &curveTags,
5862  const int numIntervals, const int tag)
5863 {
5864  if(!_checkInit()) return -1;
5865  int outTag = tag;
5866  GModel::current()->getGEOInternals()->addCompoundSpline(outTag, curveTags,
5867  numIntervals);
5868  return outTag;
5869 }
5870 
5871 GMSH_API int
5872 gmsh::model::geo::addCompoundBSpline(const std::vector<int> &curveTags,
5873  const int numIntervals, const int tag)
5874 {
5875  if(!_checkInit()) return -1;
5876  int outTag = tag;
5877  GModel::current()->getGEOInternals()->addCompoundBSpline(outTag, curveTags,
5878  numIntervals);
5879  return outTag;
5880 }
5881 
5882 GMSH_API int gmsh::model::geo::addCurveLoop(const std::vector<int> &curveTags,
5883  const int tag, const bool reorient)
5884 {
5885  if(!_checkInit()) return -1;
5886  int outTag = tag;
5887  GModel::current()->getGEOInternals()->addCurveLoop(outTag, curveTags,
5888  reorient);
5889  return outTag;
5890 }
5891 
5892 GMSH_API void gmsh::model::geo::addCurveLoops(const std::vector<int> &curveTags,
5893  std::vector<int> &tags)
5894 {
5895  if(!_checkInit()) return;
5897 }
5898 
5899 GMSH_API int gmsh::model::geo::addPlaneSurface(const std::vector<int> &wireTags,
5900  const int tag)
5901 {
5902  if(!_checkInit()) return -1;
5903  int outTag = tag;
5904  GModel::current()->getGEOInternals()->addPlaneSurface(outTag, wireTags);
5905  return outTag;
5906 }
5907 
5908 GMSH_API int
5909 gmsh::model::geo::addSurfaceFilling(const std::vector<int> &wireTags,
5910  const int tag, const int sphereCenterTag)
5911 {
5912  if(!_checkInit()) return -1;
5913  int outTag = tag;
5914  GModel::current()->getGEOInternals()->addSurfaceFilling(outTag, wireTags,
5915  sphereCenterTag);
5916  return outTag;
5917 }
5918 
5919 GMSH_API int
5920 gmsh::model::geo::addSurfaceLoop(const std::vector<int> &surfaceTags,
5921  const int tag)
5922 {
5923  if(!_checkInit()) return -1;
5924  int outTag = tag;
5925  GModel::current()->getGEOInternals()->addSurfaceLoop(outTag, surfaceTags);
5926  return outTag;
5927 }
5928 
5929 GMSH_API int gmsh::model::geo::addVolume(const std::vector<int> &shellTags,
5930  const int tag)
5931 {
5932  if(!_checkInit()) return -1;
5933  int outTag = tag;
5934  GModel::current()->getGEOInternals()->addVolume(outTag, shellTags);
5935  return outTag;
5936 }
5937 
5938 GMSH_API int gmsh::model::geo::addGeometry(const std::string &geometry,
5939  const std::vector<double> &numbers,
5940  const std::vector<std::string> &strings,
5941  const int tag)
5942 {
5943  int t = tag;
5944  if(t < 0) t = gmshSurface::maxTag() + 1;
5945 
5946  if(geometry == "ParametricSurface") {
5947  if(strings.size() == 3)
5948  gmshParametricSurface::NewParametricSurface(t, strings[0].c_str(),
5949  strings[1].c_str(),
5950  strings[2].c_str());
5951  else
5952  Msg::Error("Parametric surface definition requires 3 strings "
5953  "(3 expressions to compute the coordinates)");
5954  }
5955  else if(geometry == "Sphere") {
5956  if(numbers.size() == 4)
5957  gmshSphere::NewSphere(t, numbers[0], numbers[1], numbers[2], numbers[3]);
5958  else
5959  Msg::Error("Sphere definition requires 4 numbers (3 coordinates "
5960  "of the center and the radius)");
5961  }
5962  else if(geometry == "PolarSphere") {
5963  if(numbers.size() == 4)
5964  gmshPolarSphere::NewPolarSphere(t, numbers[0], numbers[1],
5965  numbers[2], numbers[3]);
5966  else
5967  Msg::Error("Polar sphere definition requires 4 numbers (3 coordinates "
5968  "of the center and the radius)");
5969  }
5970  else {
5971  Msg::Error("Unknown geometry '%s'", geometry.c_str());
5972  return 0;
5973  }
5974  return t;
5975 }
5976 
5977 GMSH_API int gmsh::model::geo::addPointOnGeometry(const int geometryTag,
5978  const double x,
5979  const double y,
5980  const double z,
5981  const double meshSize,
5982  const int tag)
5983 {
5984  if(!_checkInit()) return -1;
5985  int outTag = tag;
5986  double xx = CTX::instance()->geom.scalingFactor * x;
5987  double yy = CTX::instance()->geom.scalingFactor * y;
5988  //double zz = CTX::instance()->geom.scalingFactor * z;
5989  double lc = CTX::instance()->geom.scalingFactor * meshSize;
5990  gmshSurface *s = gmshSurface::getSurface(geometryTag);
5991  if(s) {
5992  GModel::current()->getGEOInternals()->addVertex(outTag, xx, yy, s, lc);
5993  return outTag;
5994  }
5995  else {
5996  return 0;
5997  }
5998 }
5999 
6000 static ExtrudeParams *_getExtrudeParams(const std::vector<int> &numElements,
6001  const std::vector<double> &heights,
6002  const bool recombine)
6003 {
6004  ExtrudeParams *e = nullptr;
6005  if(numElements.size()) {
6006  e = new ExtrudeParams();
6007  e->mesh.ExtrudeMesh = true;
6008  e->mesh.NbElmLayer = numElements;
6009  e->mesh.hLayer = heights;
6010  if(e->mesh.hLayer.empty()) {
6011  e->mesh.NbLayer = numElements.size();
6012  for(int i = 0; i < e->mesh.NbLayer; i++) {
6013  e->mesh.hLayer.push_back((i + 1.) / e->mesh.NbLayer);
6014  }
6015  }
6016  else {
6017  e->mesh.NbLayer = heights.size();
6018  }
6019  e->mesh.Recombine = recombine;
6020  }
6021  return e;
6022 }
6023 
6024 GMSH_API void gmsh::model::geo::extrude(const vectorpair &dimTags,
6025  const double dx, const double dy,
6026  const double dz, vectorpair &outDimTags,
6027  const std::vector<int> &numElements,
6028  const std::vector<double> &heights,
6029  const bool recombine)
6030 {
6031  if(!_checkInit()) return;
6032  outDimTags.clear();
6033  ExtrudeParams *e = _getExtrudeParams(numElements, heights, recombine);
6035  dimTags, dx, dy, dz, outDimTags, e);
6036  if(e) delete e;
6037 }
6038 
6039 GMSH_API void gmsh::model::geo::revolve(
6040  const vectorpair &dimTags, const double x, const double y, const double z,
6041  const double ax, const double ay, const double az, const double angle,
6042  vectorpair &outDimTags, const std::vector<int> &numElements,
6043  const std::vector<double> &heights, const bool recombine)
6044 {
6045  if(!_checkInit()) return;
6046  outDimTags.clear();
6047  ExtrudeParams *e = _getExtrudeParams(numElements, heights, recombine);
6049  dimTags, x, y, z, ax, ay, az, angle, outDimTags, e);
6050  if(e) delete e;
6051 }
6052 
6053 GMSH_API void gmsh::model::geo::twist(
6054  const vectorpair &dimTags, const double x, const double y, const double z,
6055  const double dx, const double dy, const double dz, const double ax,
6056  const double ay, const double az, const double angle, vectorpair &outDimTags,
6057  const std::vector<int> &numElements, const std::vector<double> &heights,
6058  const bool recombine)
6059 {
6060  _checkInit();
6061  outDimTags.clear();
6062  ExtrudeParams *e = _getExtrudeParams(numElements, heights, recombine);
6064  dimTags, x, y, z, dx, dy, dz, ax, ay, az, angle, outDimTags, e);
6065  if(e) delete e;
6066 }
6067 
6068 GMSH_API void gmsh::model::geo::extrudeBoundaryLayer(
6069  const vectorpair &dimTags, vectorpair &outDimTags,
6070  const std::vector<int> &numElements, const std::vector<double> &heights,
6071  const bool recombine, const bool second, const int viewIndex)
6072 {
6073  if(!_checkInit()) return;
6074  outDimTags.clear();
6075  ExtrudeParams *e = _getExtrudeParams(numElements, heights, recombine);
6076  if(!e) {
6077  Msg::Error("Element layers are required for boundary layer extrusion");
6078  return;
6079  }
6080  e->mesh.BoundaryLayerIndex = second ? 1 : 0;
6081  e->mesh.ViewIndex = viewIndex;
6082  GModel::current()->getGEOInternals()->boundaryLayer(dimTags, outDimTags, e);
6083  delete e;
6084 }
6085 
6086 GMSH_API void gmsh::model::geo::translate(const vectorpair &dimTags,
6087  const double dx, const double dy,
6088  const double dz)
6089 {
6090  if(!_checkInit()) return;
6091  GModel::current()->getGEOInternals()->translate(dimTags, dx, dy, dz);
6092 }
6093 
6094 GMSH_API void gmsh::model::geo::rotate(const vectorpair &dimTags,
6095  const double x, const double y,
6096  const double z, const double ax,
6097  const double ay, const double az,
6098  const double angle)
6099 {
6100  if(!_checkInit()) return;
6101  GModel::current()->getGEOInternals()->rotate(dimTags, x, y, z, ax, ay, az,
6102  angle);
6103 }
6104 
6105 GMSH_API void gmsh::model::geo::dilate(const vectorpair &dimTags,
6106  const double x, const double y,
6107  const double z, const double a,
6108  const double b, const double c)
6109 {
6110  if(!_checkInit()) return;
6111  GModel::current()->getGEOInternals()->dilate(dimTags, x, y, z, a, b, c);
6112 }
6113 
6114 GMSH_API void gmsh::model::geo::mirror(const vectorpair &dimTags,
6115  const double a, const double b,
6116  const double c, const double d)
6117 {
6118  if(!_checkInit()) return;
6119  GModel::current()->getGEOInternals()->symmetry(dimTags, a, b, c, d);
6120 }
6121 
6122 // will be deprecated
6123 GMSH_API void gmsh::model::geo::symmetrize(const vectorpair &dimTags,
6124  const double a, const double b,
6125  const double c, const double d)
6126 {
6127  gmsh::model::geo::mirror(dimTags, a, b, c, d);
6128 }
6129 
6130 GMSH_API void gmsh::model::geo::copy(const vectorpair &dimTags,
6131  vectorpair &outDimTags)
6132 {
6133  if(!_checkInit()) return;
6134  outDimTags.clear();
6135  GModel::current()->getGEOInternals()->copy(dimTags, outDimTags);
6136 }
6137 
6138 GMSH_API void gmsh::model::geo::remove(const vectorpair &dimTags,
6139  const bool recursive)
6140 {
6141  if(!_checkInit()) return;
6142  GModel::current()->getGEOInternals()->remove(dimTags, recursive);
6143 }
6144 
6145 GMSH_API void gmsh::model::geo::removeAllDuplicates()
6146 {
6147  if(!_checkInit()) return;
6149 }
6150 
6151 GMSH_API void gmsh::model::geo::splitCurve(const int tag,
6152  const std::vector<int> &pointTags,
6153  std::vector<int> &curveTags)
6154 {
6155  if(!_checkInit()) return;
6156  GModel::current()->getGEOInternals()->splitCurve(tag, pointTags, curveTags);
6157 }
6158 
6159 GMSH_API int gmsh::model::geo::getMaxTag(const int dim)
6160 {
6161  if(!_checkInit()) return -1;
6162  return GModel::current()->getGEOInternals()->getMaxTag(dim);
6163 }
6164 
6165 GMSH_API void gmsh::model::geo::setMaxTag(const int dim, const int maxTag)
6166 {
6167  if(!_checkInit()) return;
6168  GModel::current()->getGEOInternals()->setMaxTag(dim, maxTag);
6169 }
6170 
6171 GMSH_API int gmsh::model::geo::addPhysicalGroup(const int dim,
6172  const std::vector<int> &tags,
6173  const int tag,
6174  const std::string &name)
6175 {
6176  if(!_checkInit()) return -1;
6177  int outTag = tag;
6178  if(outTag < 0)
6179  outTag = GModel::current()->getGEOInternals()->getMaxPhysicalTag() + 1;
6181  tags);
6182  if(!name.empty()) GModel::current()->setPhysicalName(name, dim, outTag);
6183  return outTag;
6184 }
6185 
6186 GMSH_API void gmsh::model::geo::removePhysicalGroups(const vectorpair &dimTags)
6187 {
6188  if(!_checkInit()) return;
6189  if(dimTags.empty()) {
6191  }
6192  else {
6193  for(std::size_t i = 0; i < dimTags.size(); i++) {
6194  std::vector<int> tags; // empty to delete the group
6196  dimTags[i].first, dimTags[i].second, 2, tags);
6197  }
6198  }
6199 }
6200 
6201 GMSH_API void gmsh::model::geo::synchronize()
6202 {
6203  if(!_checkInit()) return;
6205 }
6206 
6207 // gmsh::model::geo::mesh
6208 
6209 GMSH_API void
6210 gmsh::model::geo::mesh::setTransfiniteCurve(const int tag, const int nPoints,
6211  const std::string &meshType,
6212  const double coef)
6213 {
6214  if(!_checkInit()) return;
6215  int type = (meshType == "Progression" || meshType == "Power") ? 1 :
6216  (meshType == "Bump") ? 2 :
6217  (meshType == "Beta") ? 3 :
6218  1;
6219  double c = std::abs(coef);
6220  // in .geo file we use a negative tag to do this trick; it's a bad idea
6221  if(coef < 0) type = -type;
6222 
6223  // for compatibility with geo files, try both tag and -tag
6224  for(int sig = -1; sig <= 1; sig += 2)
6225  GModel::current()->getGEOInternals()->setTransfiniteLine(sig * tag, nPoints,
6226  type, c);
6227 }
6228 
6229 GMSH_API void gmsh::model::geo::mesh::setTransfiniteSurface(
6230  const int tag, const std::string &arrangement,
6231  const std::vector<int> &cornerTags)
6232 {
6233  if(!_checkInit()) return;
6234  int t = (arrangement == "Right") ? 1 :
6235  (arrangement == "Left") ? -1 :
6236  (arrangement == "AlternateRight") ? 2 :
6237  (arrangement == "AlternateLeft") ? -2 :
6238  (arrangement == "Alternate") ? 2 :
6239  -1;
6241  cornerTags);
6242 }
6243 
6244 GMSH_API void
6245 gmsh::model::geo::mesh::setTransfiniteVolume(const int tag,
6246  const std::vector<int> &cornerTags)
6247 {
6248  if(!_checkInit()) return;
6249  GModel::current()->getGEOInternals()->setTransfiniteVolume(tag, cornerTags);
6250 }
6251 
6252 GMSH_API void gmsh::model::geo::mesh::setRecombine(const int dim, const int tag,
6253  const double angle)
6254 {
6255  if(!_checkInit()) return;
6257 }
6258 
6259 GMSH_API void gmsh::model::geo::mesh::setSmoothing(const int dim, const int tag,
6260  const int val)
6261 {
6262  if(!_checkInit()) return;
6263  if(dim == 2) { GModel::current()->getGEOInternals()->setSmoothing(tag, val); }
6264 }
6265 
6266 GMSH_API void gmsh::model::geo::mesh::setReverse(const int dim, const int tag,
6267  const bool val)
6268 {
6269  if(!_checkInit()) return;
6270  GModel::current()->getGEOInternals()->setReverseMesh(dim, tag, val);
6271 }
6272 
6273 GMSH_API void gmsh::model::geo::mesh::setAlgorithm(const int dim, const int tag,
6274  const int val)
6275 {
6276  if(!_checkInit()) return;
6277  GModel::current()->getGEOInternals()->setMeshAlgorithm(dim, tag, val);
6278 }
6279 
6280 GMSH_API void gmsh::model::geo::mesh::setSizeFromBoundary(const int dim,
6281  const int tag,
6282  const int val)
6283 {
6284  if(!_checkInit()) return;
6286 }
6287 
6288 GMSH_API void gmsh::model::geo::mesh::setSize(const vectorpair &dimTags,
6289  const double size)
6290 {
6291  if(!_checkInit()) return;
6292  for(std::size_t i = 0; i < dimTags.size(); i++) {
6293  int dim = dimTags[i].first, tag = dimTags[i].second;
6294  GModel::current()->getGEOInternals()->setMeshSize(dim, tag, size);
6295  }
6296 }
6297 
6298 // gmsh::model::occ
6299 
6300 static void _createOcc()
6301 {
6302  if(!GModel::current()->getOCCInternals())
6304 }
6305 
6306 GMSH_API int gmsh::model::occ::addPoint(const double x, const double y,
6307  const double z, const double meshSize,
6308  const int tag)
6309 {
6310  if(!_checkInit()) return -1;
6311  _createOcc();
6312  int outTag = tag;
6313  GModel::current()->getOCCInternals()->addVertex(outTag, x, y, z, meshSize);
6314  return outTag;
6315 }
6316 
6317 GMSH_API int gmsh::model::occ::addLine(const int startTag, const int endTag,
6318  const int tag)
6319 {
6320  if(!_checkInit()) return -1;
6321  _createOcc();
6322  int outTag = tag;
6323  GModel::current()->getOCCInternals()->addLine(outTag, startTag, endTag);
6324  return outTag;
6325 }
6326 
6327 GMSH_API int gmsh::model::occ::addCircleArc(const int startTag,
6328  const int centerTag,
6329  const int endTag, const int tag)
6330 {
6331  if(!_checkInit()) return -1;
6332  _createOcc();
6333  int outTag = tag;
6334  GModel::current()->getOCCInternals()->addCircleArc(outTag, startTag,
6335  centerTag, endTag);
6336  return outTag;
6337 }
6338 
6339 GMSH_API int gmsh::model::occ::addCircle(const double x, const double y,
6340  const double z, const double r,
6341  const int tag, const double angle1,
6342  const double angle2,
6343  const std::vector<double> &zAxis,
6344  const std::vector<double> &xAxis)
6345 {
6346  if(!_checkInit()) return -1;
6347  _createOcc();
6348  int outTag = tag;
6349  GModel::current()->getOCCInternals()->addCircle(outTag, x, y, z, r, angle1,
6350  angle2, zAxis, xAxis);
6351  return outTag;
6352 }
6353 
6354 GMSH_API int gmsh::model::occ::addEllipseArc(const int startTag,
6355  const int centerTag,
6356  const int majorTag,
6357  const int endTag, const int tag)
6358 {
6359  if(!_checkInit()) return -1;
6360  _createOcc();
6361  int outTag = tag;
6363  outTag, startTag, centerTag, majorTag, endTag);
6364  return outTag;
6365 }
6366 
6367 GMSH_API int gmsh::model::occ::addEllipse(const double x, const double y,
6368  const double z, const double r1,
6369  const double r2, const int tag,
6370  const double angle1,
6371  const double angle2,
6372  const std::vector<double> &zAxis,
6373  const std::vector<double> &xAxis)
6374 {
6375  if(!_checkInit()) return -1;
6376  _createOcc();
6377  int outTag = tag;
6378  GModel::current()->getOCCInternals()->addEllipse(outTag, x, y, z, r1, r2,
6379  angle1, angle2, zAxis,
6380  xAxis);
6381  return outTag;
6382 }
6383 
6384 GMSH_API int gmsh::model::occ::addSpline(const std::vector<int> &pointTags,
6385  const int tag,
6386  const std::vector<double> &tangents)
6387 {
6388  if(!_checkInit()) return -1;
6389  _createOcc();
6390  int outTag = tag;
6391  std::vector<SVector3> t;
6392  if(tangents.size() % 3) {
6393  Msg::Error("Number of entries in tangents should be a multiple of 3");
6394  }
6395  else if(!tangents.empty()) {
6396  for(std::size_t i = 0; i < tangents.size(); i += 3) {
6397  t.push_back(SVector3(tangents[i], tangents[i + 1], tangents[i + 2]));
6398  }
6399  }
6400  GModel::current()->getOCCInternals()->addSpline(outTag, pointTags, t);
6401  return outTag;
6402 }
6403 
6404 GMSH_API int gmsh::model::occ::addBSpline(
6405  const std::vector<int> &pointTags, const int tag, const int degree,
6406  const std::vector<double> &weights, const std::vector<double> &knots,
6407  const std::vector<int> &multiplicities)
6408 {
6409  if(!_checkInit()) return -1;
6410  _createOcc();
6411  int outTag = tag;
6413  outTag, pointTags, degree, weights, knots, multiplicities);
6414  return outTag;
6415 }
6416 
6417 GMSH_API int gmsh::model::occ::addBezier(const std::vector<int> &pointTags,
6418  const int tag)
6419 {
6420  if(!_checkInit()) return -1;
6421  _createOcc();
6422  int outTag = tag;
6423  GModel::current()->getOCCInternals()->addBezier(outTag, pointTags);
6424  return outTag;
6425 }
6426 
6427 GMSH_API int gmsh::model::occ::addWire(const std::vector<int> &curveTags,
6428  const int tag, const bool checkClosed)
6429 {
6430  if(!_checkInit()) return -1;
6431  _createOcc();
6432  int outTag = tag;
6433  GModel::current()->getOCCInternals()->addWire(outTag, curveTags, checkClosed);
6434  return outTag;
6435 }
6436 
6437 GMSH_API int gmsh::model::occ::addCurveLoop(const std::vector<int> &curveTags,
6438  const int tag)
6439 {
6440  if(!_checkInit()) return -1;
6441  _createOcc();
6442  int outTag = tag;
6443  GModel::current()->getOCCInternals()->addCurveLoop(outTag, curveTags);
6444  return outTag;
6445 }
6446 
6447 GMSH_API int gmsh::model::occ::addRectangle(const double x, const double y,
6448  const double z, const double dx,
6449  const double dy, const int tag,
6450  const double roundedRadius)
6451 {
6452  if(!_checkInit()) return -1;
6453  _createOcc();
6454  int outTag = tag;
6455  GModel::current()->getOCCInternals()->addRectangle(outTag, x, y, z, dx, dy,
6456  roundedRadius);
6457  return outTag;
6458 }
6459 
6460 GMSH_API int gmsh::model::occ::addDisk(const double xc, const double yc,
6461  const double zc, const double rx,
6462  const double ry, const int tag,
6463  const std::vector<double> &zAxis,
6464  const std::vector<double> &xAxis)
6465 {
6466  if(!_checkInit()) return -1;
6467  _createOcc();
6468  int outTag = tag;
6469  GModel::current()->getOCCInternals()->addDisk(outTag, xc, yc, zc, rx, ry,
6470  zAxis, xAxis);
6471  return outTag;
6472 }
6473 
6474 GMSH_API int gmsh::model::occ::addPlaneSurface(const std::vector<int> &wireTags,
6475  const int tag)
6476 {
6477  if(!_checkInit()) return -1;
6478  _createOcc();
6479  int outTag = tag;
6480  GModel::current()->getOCCInternals()->addPlaneSurface(outTag, wireTags);
6481  return outTag;
6482 }
6483 
6484 GMSH_API int gmsh::model::occ::addSurfaceFilling(
6485  const int wireTag, const int tag, const std::vector<int> &pointTags,
6486  const int degree, const int numPointsOnCurves, const int numIter,
6487  const bool anisotropic, const double tol2d, const double tol3d,
6488  const double tolAng, const double tolCurv, const int maxDegree,
6489  const int maxSegments)
6490 {
6491  if(!_checkInit()) return -1;
6492  _createOcc();
6493  int outTag = tag;
6494  std::vector<int> surf, surfCont;
6496  outTag, wireTag, pointTags, surf, surfCont, degree, numPointsOnCurves,
6497  numIter, anisotropic, tol2d, tol3d, tolAng, tolCurv, maxDegree,
6498  maxSegments);
6499  return outTag;
6500 }
6501 
6502 GMSH_API int gmsh::model::occ::addBSplineFilling(const int wireTag,
6503  const int tag,
6504  const std::string &type)
6505 {
6506  if(!_checkInit()) return -1;
6507  _createOcc();
6508  int outTag = tag;
6509  GModel::current()->getOCCInternals()->addBSplineFilling(outTag, wireTag,
6510  type);
6511  return outTag;
6512 }
6513 
6514 GMSH_API int gmsh::model::occ::addBezierFilling(const int wireTag,
6515  const int tag,
6516  const std::string &type)
6517 {
6518  if(!_checkInit()) return -1;
6519  _createOcc();
6520  int outTag = tag;
6521  GModel::current()->getOCCInternals()->addBezierFilling(outTag, wireTag, type);
6522  return outTag;
6523 }
6524 
6525 GMSH_API int gmsh::model::occ::addBSplineSurface(
6526  const std::vector<int> &pointTags, const int numPointsU, const int tag,
6527  const int degreeU, const int degreeV, const std::vector<double> &weights,
6528  const std::vector<double> &knotsU, const std::vector<double> &knotsV,
6529  const std::vector<int> &multiplicitiesU,
6530  const std::vector<int> &multiplicitiesV, const std::vector<int> &wireTags,
6531  const bool wire3D)
6532 {
6533  if(!_checkInit()) return -1;
6534  _createOcc();
6535  int outTag = tag;
6537  outTag, pointTags, numPointsU, degreeU, degreeV, weights, knotsU, knotsV,
6538  multiplicitiesU, multiplicitiesV, wireTags, wire3D);
6539  return outTag;
6540 }
6541 
6542 GMSH_API int gmsh::model::occ::addBezierSurface(
6543  const std::vector<int> &pointTags, const int numPointsU, const int tag,
6544  const std::vector<int> &wireTags, const bool wire3D)
6545 {
6546  if(!_checkInit()) return -1;
6547  _createOcc();
6548  int outTag = tag;
6550  outTag, pointTags, numPointsU, wireTags, wire3D);
6551  return outTag;
6552 }
6553 
6554 GMSH_API int
6555 gmsh::model::occ::addTrimmedSurface(const int surfaceTag,
6556  const std::vector<int> &wireTags,
6557  const bool wire3D, const int tag)
6558 {
6559  if(!_checkInit()) return -1;
6560  _createOcc();
6561  int outTag = tag;
6562  GModel::current()->getOCCInternals()->addTrimmedSurface(outTag, surfaceTag,
6563  wireTags, wire3D);
6564  return outTag;
6565 }
6566 
6567 GMSH_API int
6568 gmsh::model::occ::addSurfaceLoop(const std::vector<int> &surfaceTags,
6569  const int tag, const bool sewing)
6570 {
6571  if(!_checkInit()) return -1;
6572  _createOcc();
6573  int outTag = tag;
6574  GModel::current()->getOCCInternals()->addSurfaceLoop(outTag, surfaceTags,
6575  sewing);
6576  return outTag;
6577 }
6578 
6579 GMSH_API int gmsh::model::occ::addVolume(const std::vector<int> &shellTags,
6580  const int tag)
6581 {
6582  if(!_checkInit()) return -1;
6583  _createOcc();
6584  int outTag = tag;
6585  GModel::current()->getOCCInternals()->addVolume(outTag, shellTags);
6586  return outTag;
6587 }
6588 
6589 GMSH_API int gmsh::model::occ::addSphere(const double xc, const double yc,
6590  const double zc, const double radius,
6591  const int tag, const double angle1,
6592  const double angle2,
6593  const double angle3)
6594 {
6595  if(!_checkInit()) return -1;
6596  _createOcc();
6597  int outTag = tag;
6598  GModel::current()->getOCCInternals()->addSphere(outTag, xc, yc, zc, radius,
6599  angle1, angle2, angle3);
6600  return outTag;
6601 }
6602 
6603 GMSH_API int gmsh::model::occ::addBox(const double x, const double y,
6604  const double z, const double dx,
6605  const double dy, const double dz,
6606  const int tag)
6607 {
6608  if(!_checkInit()) return -1;
6609  _createOcc();
6610  int outTag = tag;
6611  GModel::current()->getOCCInternals()->addBox(outTag, x, y, z, dx, dy, dz);
6612  return outTag;
6613 }
6614 
6615 GMSH_API int gmsh::model::occ::addCylinder(const double x, const double y,
6616  const double z, const double dx,
6617  const double dy, const double dz,
6618  const double r, const int tag,
6619  const double angle)
6620 {
6621  if(!_checkInit()) return -1;
6622  _createOcc();
6623  int outTag = tag;
6624  GModel::current()->getOCCInternals()->addCylinder(outTag, x, y, z, dx, dy, dz,
6625  r, angle);
6626  return outTag;
6627 }
6628 
6629 GMSH_API int gmsh::model::occ::addCone(const double x, const double y,
6630  const double z, const double dx,
6631  const double dy, const double dz,
6632  const double r1, const double r2,
6633  const int tag, const double angle)
6634 {
6635  if(!_checkInit()) return -1;
6636  _createOcc();
6637  int outTag = tag;
6638  GModel::current()->getOCCInternals()->addCone(outTag, x, y, z, dx, dy, dz, r1,
6639  r2, angle);
6640  return outTag;
6641 }
6642 
6643 GMSH_API int gmsh::model::occ::addWedge(const double x, const double y,
6644  const double z, const double dx,
6645  const double dy, const double dz,
6646  const int tag, const double ltx,
6647  const std::vector<double> &zAxis)
6648 {
6649  if(!_checkInit()) return -1;
6650  _createOcc();
6651  int outTag = tag;
6652  GModel::current()->getOCCInternals()->addWedge(outTag, x, y, z, dx, dy, dz,
6653  ltx, zAxis);
6654  return outTag;
6655 }
6656 
6657 GMSH_API int gmsh::model::occ::addTorus(const double x, const double y,
6658  const double z, const double r1,
6659  const double r2, const int tag,
6660  const double angle,
6661  const std::vector<double> &zAxis)
6662 {
6663  if(!_checkInit()) return -1;
6664  _createOcc();
6665  int outTag = tag;
6666  GModel::current()->getOCCInternals()->addTorus(outTag, x, y, z, r1, r2,
6667  angle, zAxis);
6668  return outTag;
6669 }
6670 
6671 GMSH_API void gmsh::model::occ::addThruSections(
6672  const std::vector<int> &wireTags, vectorpair &outDimTags, const int tag,
6673  const bool makeSolid, const bool makeRuled, const int maxDegree,
6674  const std::string &continuity, const std::string &parametrization,
6675  const bool smoothing)
6676 {
6677  if(!_checkInit()) return;
6678  _createOcc();
6679  outDimTags.clear();
6681  tag, wireTags, makeSolid, makeRuled, outDimTags, maxDegree,
6682  continuity, parametrization, smoothing);
6683 }
6684 
6685 GMSH_API void gmsh::model::occ::addThickSolid(
6686  const int volumeTag, const std::vector<int> &excludeSurfaceTags,
6687  const double offset, vectorpair &outDimTags, const int tag)
6688 {
6689  if(!_checkInit()) return;
6690  _createOcc();
6691  outDimTags.clear();
6693  tag, volumeTag, excludeSurfaceTags, offset, outDimTags);
6694 }
6695 
6696 GMSH_API void gmsh::model::occ::extrude(const vectorpair &dimTags,
6697  const double dx, const double dy,
6698  const double dz, vectorpair &outDimTags,
6699  const std::vector<int> &numElements,
6700  const std::vector<double> &heights,
6701  const bool recombine)
6702 {
6703  if(!_checkInit()) return;
6704  _createOcc();
6705  outDimTags.clear();
6706  ExtrudeParams *e = _getExtrudeParams(numElements, heights, recombine);
6708  dimTags, dx, dy, dz, outDimTags, e);
6709  if(e) delete e;
6710 }
6711 
6712 GMSH_API void gmsh::model::occ::revolve(
6713  const vectorpair &dimTags, const double x, const double y, const double z,
6714  const double ax, const double ay, const double az, const double angle,
6715  vectorpair &outDimTags, const std::vector<int> &numElements,
6716  const std::vector<double> &heights, const bool recombine)
6717 {
6718  if(!_checkInit()) return;
6719  _createOcc();
6720  outDimTags.clear();
6721  ExtrudeParams *e = _getExtrudeParams(numElements, heights, recombine);
6723  dimTags, x, y, z, ax, ay, az, angle, outDimTags, e);
6724  if(e) delete e;
6725 }
6726 
6727 GMSH_API void gmsh::model::occ::addPipe(const vectorpair &dimTags,
6728  const int wireTag,
6729  vectorpair &outDimTags,
6730  const std::string &trihedron)
6731 {
6732  if(!_checkInit()) return;
6733  _createOcc();
6734  outDimTags.clear();
6735  GModel::current()->getOCCInternals()->addPipe(dimTags, wireTag, outDimTags,
6736  trihedron);
6737 }
6738 
6739 GMSH_API void gmsh::model::occ::fillet(const std::vector<int> &volumeTags,
6740  const std::vector<int> &curveTags,
6741  const std::vector<double> &radii,
6742  vectorpair &outDimTags,
6743  const bool removeVolume)
6744 {
6745  if(!_checkInit()) return;
6746  _createOcc();
6747  outDimTags.clear();
6748  GModel::current()->getOCCInternals()->fillet(volumeTags, curveTags, radii,
6749  outDimTags, removeVolume);
6750 }
6751 
6752 GMSH_API void gmsh::model::occ::chamfer(const std::vector<int> &volumeTags,
6753  const std::vector<int> &curveTags,
6754  const std::vector<int> &surfaceTags,
6755  const std::vector<double> &distances,
6756  vectorpair &outDimTags,
6757  const bool removeVolume)
6758 {
6759  if(!_checkInit()) return;
6760  _createOcc();
6761  outDimTags.clear();
6763  volumeTags, curveTags, surfaceTags, distances, outDimTags, removeVolume);
6764 }
6765 
6766 GMSH_API void gmsh::model::occ::fuse(const vectorpair &objectDimTags,
6767  const vectorpair &toolDimTags,
6768  vectorpair &outDimTags,
6769  std::vector<vectorpair> &outDimTagsMap,
6770  const int tag, const bool removeObject,
6771  const bool removeTool)
6772 {
6773  if(!_checkInit()) return;
6774  _createOcc();
6775  outDimTags.clear();
6776  outDimTagsMap.clear();
6778  tag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap, removeObject,
6779  removeTool);
6780 }
6781 
6783  const vectorpair &objectDimTags, const vectorpair &toolDimTags,
6784  vectorpair &outDimTags, std::vector<vectorpair> &outDimTagsMap, const int tag,
6785  const bool removeObject, const bool removeTool)
6786 {
6787  if(!_checkInit()) return;
6788  _createOcc();
6789  outDimTags.clear();
6790  outDimTagsMap.clear();
6792  tag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap, removeObject,
6793  removeTool);
6794 }
6795 
6796 GMSH_API void gmsh::model::occ::cut(const vectorpair &objectDimTags,
6797  const vectorpair &toolDimTags,
6798  vectorpair &outDimTags,
6799  std::vector<vectorpair> &outDimTagsMap,
6800  const int tag, const bool removeObject,
6801  const bool removeTool)
6802 {
6803  if(!_checkInit()) return;
6804  _createOcc();
6805  outDimTags.clear();
6806  outDimTagsMap.clear();
6808  tag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap, removeObject,
6809  removeTool);
6810 }
6811 
6812 GMSH_API void gmsh::model::occ::fragment(const vectorpair &objectDimTags,
6813  const vectorpair &toolDimTags,
6814  vectorpair &outDimTags,
6815  std::vector<vectorpair> &outDimTagsMap,
6816  const int tag, const bool removeObject,
6817  const bool removeTool)
6818 {
6819  if(!_checkInit()) return;
6820  _createOcc();
6821  outDimTags.clear();
6822  outDimTagsMap.clear();
6824  tag, objectDimTags, toolDimTags, outDimTags, outDimTagsMap, removeObject,
6825  removeTool);
6826 }
6827 
6828 GMSH_API void gmsh::model::occ::translate(const vectorpair &dimTags,
6829  const double dx, const double dy,
6830  const double dz)
6831 {
6832  if(!_checkInit()) return;
6833  _createOcc();
6834  GModel::current()->getOCCInternals()->translate(dimTags, dx, dy, dz);
6835 }
6836 
6837 GMSH_API void gmsh::model::occ::rotate(const vectorpair &dimTags,
6838  const double x, const double y,
6839  const double z, const double ax,
6840  const double ay, const double az,
6841  const double angle)
6842 {
6843  if(!_checkInit()) return;
6844  _createOcc();
6845  GModel::current()->getOCCInternals()->rotate(dimTags, x, y, z, ax, ay, az,
6846  angle);
6847 }
6848 
6849 GMSH_API void gmsh::model::occ::dilate(const vectorpair &dimTags,
6850  const double x, const double y,
6851  const double z, const double a,
6852  const double b, const double c)
6853 {
6854  if(!_checkInit()) return;
6855  _createOcc();
6856  GModel::current()->getOCCInternals()->dilate(dimTags, x, y, z, a, b, c);
6857 }
6858 
6859 GMSH_API void gmsh::model::occ::mirror(const vectorpair &dimTags,
6860  const double a, const double b,
6861  const double c, const double d)
6862 {
6863  if(!_checkInit()) return;
6864  _createOcc();
6865  GModel::current()->getOCCInternals()->symmetry(dimTags, a, b, c, d);
6866 }
6867 
6868 GMSH_API void gmsh::model::occ::symmetrize(const vectorpair &dimTags,
6869  const double a, const double b,
6870  const double c, const double d)
6871 {
6872  gmsh::model::occ::mirror(dimTags, a, b, c, d);
6873 }
6874 
6875 GMSH_API void
6876 gmsh::model::occ::affineTransform(const vectorpair &dimTags,
6877  const std::vector<double> &affineTransform)
6878 {
6879  if(!_checkInit()) return;
6880  _createOcc();
6881  GModel::current()->getOCCInternals()->affine(dimTags, affineTransform);
6882 }
6883 
6884 GMSH_API void gmsh::model::occ::copy(const vectorpair &dimTags,
6885  vectorpair &outDimTags)
6886 {
6887  if(!_checkInit()) return;
6888  _createOcc();
6889  outDimTags.clear();
6890  GModel::current()->getOCCInternals()->copy(dimTags, outDimTags);
6891 }
6892 
6893 GMSH_API void gmsh::model::occ::remove(const vectorpair &dimTags,
6894  const bool recursive)
6895 {
6896  if(!_checkInit()) return;
6897  _createOcc();
6898  GModel::current()->getOCCInternals()->remove(dimTags, recursive);
6899 }
6900 
6901 GMSH_API void gmsh::model::occ::removeAllDuplicates()
6902 {
6903  if(!_checkInit()) return;
6904  _createOcc();
6906 }
6907 
6908 GMSH_API void gmsh::model::occ::healShapes(
6909  vectorpair &outDimTags, const vectorpair &inDimTags, const double tolerance,
6910  const bool fixDegenerated, const bool fixSmallEdges, const bool fixSmallFaces,
6911  const bool sewFaces, const bool makeSolids)
6912 {
6913  if(!_checkInit()) return;
6914  _createOcc();
6915  outDimTags.clear();
6917  inDimTags, outDimTags, tolerance, fixDegenerated, fixSmallEdges,
6918  fixSmallFaces, sewFaces, makeSolids);
6919 }
6920 
6921 GMSH_API void gmsh::model::occ::convertToNURBS(const vectorpair &inDimTags)
6922 {
6923  if(!_checkInit()) return;
6924  _createOcc();
6926 }
6927 
6928 GMSH_API void gmsh::model::occ::importShapes(const std::string &fileName,
6929  vectorpair &outDimTags,
6930  const bool highestDimOnly,
6931  const std::string &format)
6932 {
6933  if(!_checkInit()) return;
6934  _createOcc();
6935  outDimTags.clear();
6936  GModel::current()->getOCCInternals()->importShapes(fileName, highestDimOnly,
6937  outDimTags, format);
6938 }
6939 
6940 GMSH_API void gmsh::model::occ::importShapesNativePointer(
6941  const void *shape, vectorpair &outDimTags, const bool highestDimOnly)
6942 {
6943  if(!_checkInit()) return;
6944  _createOcc();
6945  outDimTags.clear();
6946 #if defined(HAVE_OCC)
6948  static_cast<const TopoDS_Shape *>(shape), highestDimOnly, outDimTags);
6949 #else
6950  Msg::Error("Gmsh requires OpenCASCADE to import native shape");
6951 #endif
6952 }
6953 
6954 GMSH_API void gmsh::model::occ::getEntities(vectorpair &dimTags, const int dim)
6955 {
6956  if(!_checkInit()) return;
6957  _createOcc();
6958  GModel::current()->getOCCInternals()->getEntities(dimTags, dim);
6959 }
6960 
6961 GMSH_API void gmsh::model::occ::getEntitiesInBoundingBox(
6962  const double xmin, const double ymin, const double zmin, const double xmax,
6963  const double ymax, const double zmax, vectorpair &dimTags, const int dim)
6964 {
6965  if(!_checkInit()) return;
6966  _createOcc();
6967  dimTags.clear();
6969  xmin, ymin, zmin, xmax, ymax, zmax, dimTags, dim);
6970 }
6971 
6972 GMSH_API void gmsh::model::occ::getBoundingBox(const int dim, const int tag,
6973  double &xmin, double &ymin,
6974  double &zmin, double &xmax,
6975  double &ymax, double &zmax)
6976 {
6977  if(!_checkInit()) return;
6978  _createOcc();
6979  GModel::current()->getOCCInternals()->getBoundingBox(dim, tag, xmin, ymin,
6980  zmin, xmax, ymax, zmax);
6981 }
6982 
6983 GMSH_API void gmsh::model::occ::getCurveLoops(
6984  const int surfaceTag, std::vector<int> &curveLooptags,
6985  std::vector<std::vector<int> > &curveTags)
6986 {
6987  if(!_checkInit()) return;
6988  _createOcc();
6990  curveLooptags,
6991  curveTags);
6992 }
6993 
6994 GMSH_API void gmsh::model::occ::getSurfaceLoops(
6995  const int volumeTag, std::vector<int> &surfaceLoopTags,
6996  std::vector<std::vector<int> > &surfaceTags)
6997 {
6998  if(!_checkInit()) return;
6999  _createOcc();
7001  surfaceLoopTags,
7002  surfaceTags);
7003 }
7004 
7005 GMSH_API void gmsh::model::occ::getMass(const int dim, const int tag,
7006  double &mass)
7007 {
7008  if(!_checkInit()) return;
7009  _createOcc();
7010  GModel::current()->getOCCInternals()->getMass(dim, tag, mass);
7011 }
7012 
7013 GMSH_API void gmsh::model::occ::getCenterOfMass(const int dim, const int tag,
7014  double &x, double &y, double &z)
7015 {
7016  if(!_checkInit()) return;
7017  _createOcc();
7018  GModel::current()->getOCCInternals()->getCenterOfMass(dim, tag, x, y, z);
7019 }
7020 
7021 GMSH_API void gmsh::model::occ::getMatrixOfInertia(const int dim, const int tag,
7022  std::vector<double> &m)
7023 {
7024  if(!_checkInit()) return;
7025  _createOcc();
7027 }
7028 
7029 GMSH_API int gmsh::model::occ::getMaxTag(const int dim)
7030 {
7031  if(!_checkInit()) return -1;
7032  _createOcc();
7033  return GModel::current()->getOCCInternals()->getMaxTag(dim);
7034 }
7035 
7036 GMSH_API void gmsh::model::occ::setMaxTag(const int dim, const int maxTag)
7037 {
7038  if(!_checkInit()) return;
7039  _createOcc();
7040  GModel::current()->getOCCInternals()->setMaxTag(dim, maxTag);
7041 }
7042 
7043 GMSH_API void gmsh::model::occ::synchronize()
7044 {
7045  if(!_checkInit()) return;
7046  _createOcc();
7048 }
7049 
7050 // gmsh::model::occ::mesh
7051 
7052 GMSH_API void gmsh::model::occ::mesh::setSize(const vectorpair &dimTags,
7053  const double size)
7054 {
7055  if(!_checkInit()) return;
7056  _createOcc();
7057  for(std::size_t i = 0; i < dimTags.size(); i++) {
7058  int dim = dimTags[i].first, tag = dimTags[i].second;
7059  GModel::current()->getOCCInternals()->setMeshSize(dim, tag, size);
7060  }
7061 }
7062 
7063 // gmsh::view
7064 
7065 GMSH_API int gmsh::view::add(const std::string &name, const int tag)
7066 {
7067  if(!_checkInit()) return -1;
7068 #if defined(HAVE_POST)
7069  PView *view = new PView(tag);
7070  view->getData()->setName(name);
7071 #if defined(HAVE_FLTK)
7072  if(FlGui::available()) FlGui::instance()->updateViews(true, true);
7073 #endif
7074  return view->getTag();
7075 #else
7076  Msg::Error("Views require the post-processing module");
7077  return -1;
7078 #endif
7079 }
7080 
7081 GMSH_API void gmsh::view::remove(const int tag)
7082 {
7083  if(!_checkInit()) return;
7084 #if defined(HAVE_POST)
7085  PView *view = PView::getViewByTag(tag);
7086  if(!view) {
7087  Msg::Error("Unknown view with tag %d", tag);
7088  return;
7089  }
7090  delete view;
7091 #if defined(HAVE_FLTK)
7092  if(FlGui::available()) FlGui::instance()->updateViews(true, true);
7093 #endif
7094 #else
7095  Msg::Error("Views require the post-processing module");
7096 #endif
7097 }
7098 
7099 GMSH_API int gmsh::view::getIndex(const int tag)
7100 {
7101  if(!_checkInit()) return -1;
7102 #if defined(HAVE_POST)
7103  PView *view = PView::getViewByTag(tag);
7104  if(!view) {
7105  Msg::Error("Unknown view with tag %d", tag);
7106  return -1;
7107  }
7108  return view->getIndex();
7109 #else
7110  Msg::Error("Views require the post-processing module");
7111  return -1;
7112 #endif
7113 }
7114 
7115 GMSH_API void gmsh::view::getTags(std::vector<int> &tags)
7116 {
7117  if(!_checkInit()) return;
7118 #if defined(HAVE_POST)
7119  tags.clear();
7120  for(std::size_t i = 0; i < PView::list.size(); i++)
7121  tags.push_back(PView::list[i]->getTag());
7122 #else
7123  Msg::Error("Views require the post-processing module");
7124 #endif
7125 }
7126 
7127 template <class T>
7128 static void
7129 _addModelData(const int tag, const int step, const std::string &modelName,
7130  const std::string &dataType, const std::vector<std::size_t> &tags,
7131  const T &data, const double time, const int numComponents,
7132  const int partition)
7133 {
7134 #if defined(HAVE_POST)
7135  PView *view = PView::getViewByTag(tag);
7136  if(!view) {
7137  Msg::Error("Unknown view with tag %d", tag);
7138  return;
7139  }
7140  GModel *model = GModel::current();
7141  if(modelName.size()) {
7142  model = GModel::findByName(modelName);
7143  if(!model) {
7144  Msg::Error("Unknown model '%s'", modelName.c_str());
7145  return;
7146  }
7147  }
7149  if(dataType == "NodeData")
7151  else if(dataType == "ElementData")
7153  else if(dataType == "ElementNodeData")
7155  else if(dataType == "GaussPointData")
7157  else if(dataType == "Beam")
7159  else {
7160  Msg::Error("Unknown type of view to add '%s'", dataType.c_str());
7161  return;
7162  }
7163 
7164  PViewDataGModel *d = dynamic_cast<PViewDataGModel *>(view->getData());
7165  bool changeType = false;
7166  if(d && d->getType() != type) {
7167  Msg::Warning("Changing type of view to '%s'", dataType.c_str());
7168  changeType = true;
7169  }
7170  if(!d || changeType) { // change view type
7171  std::string name = view->getData()->getName();
7172  delete view->getData();
7173  d = new PViewDataGModel(type);
7174  d->setName(name);
7175  d->setFileName(name + ".msh");
7176  view->setData(d);
7177  }
7178  if(!d->addData(model, tags, data, step, time, partition, numComponents)) {
7179  Msg::Error("Could not add model data");
7180  return;
7181  }
7182  if(view->getOptions()->adaptVisualizationGrid)
7183  d->initAdaptiveData(view->getOptions()->timeStep,
7184  view->getOptions()->maxRecursionLevel,
7185  view->getOptions()->targetError);
7186  view->setChanged(true);
7187 #else
7188  Msg::Error("Views require the post-processing module");
7189 #endif
7190 }
7191 
7192 GMSH_API void gmsh::view::addModelData(
7193  const int tag, const int step, const std::string &modelName,
7194  const std::string &dataType, const std::vector<std::size_t> &tags,
7195  const std::vector<std::vector<double> > &data, const double time,
7196  const int numComponents, const int partition)
7197 {
7198  if(!_checkInit()) return;
7199  if(tags.size() != data.size()) {
7200  Msg::Error("Incompatible number of tags and data");
7201  return;
7202  }
7203  _addModelData(tag, step, modelName, dataType, tags, data, time, numComponents,
7204  partition);
7205 }
7206 
7207 GMSH_API void gmsh::view::addHomogeneousModelData(
7208  const int tag, const int step, const std::string &modelName,
7209  const std::string &dataType, const std::vector<std::size_t> &tags,
7210  const std::vector<double> &data, const double time, const int numComponents,
7211  const int partition)
7212 {
7213  if(!_checkInit()) return;
7214  _addModelData(tag, step, modelName, dataType, tags, data, time, numComponents,
7215  partition);
7216 }
7217 
7218 #if defined(HAVE_POST)
7219 static stepData<double> *_getModelData(const int tag, const int step,
7220  std::string &dataType, double &time,
7221  int &numComponents, int &numEnt,
7222  int &maxMult)
7223 {
7224  if(!_checkInit()) return nullptr;
7225  PView *view = PView::getViewByTag(tag);
7226  if(!view) {
7227  Msg::Error("Unknown view with tag %d", tag);
7228  return nullptr;
7229  }
7230  PViewDataGModel *d = dynamic_cast<PViewDataGModel *>(view->getData());
7231  if(!d) {
7232  Msg::Error("View with tag %d does not contain model data", tag);
7233  return nullptr;
7234  }
7236  dataType = "NodeData";
7237  else if(d->getType() == PViewDataGModel::ElementData)
7238  dataType = "ElementData";
7239  else if(d->getType() == PViewDataGModel::ElementNodeData)
7240  dataType = "ElementNodeData";
7241  else if(d->getType() == PViewDataGModel::GaussPointData)
7242  dataType = "GaussPointData";
7243  else if(d->getType() == PViewDataGModel::BeamData)
7244  dataType = "Beam";
7245  else
7246  dataType = "Unknown";
7247  stepData<double> *s = d->getStepData(step);
7248  if(!s) {
7249  Msg::Error("View with tag %d does not contain model data for step %d", tag,
7250  step);
7251  return nullptr;
7252  }
7253  time = s->getTime();
7254  numComponents = s->getNumComponents();
7255  numEnt = 0;
7256  maxMult = 0;
7257  for(std::size_t i = 0; i < s->getNumData(); i++) {
7258  if(s->getData(i)) {
7259  numEnt++;
7260  maxMult = std::max(maxMult, s->getMult(i));
7261  }
7262  }
7263  return s;
7264 }
7265 #endif
7266 
7267 GMSH_API void gmsh::view::getModelData(const int tag, const int step,
7268  std::string &dataType,
7269  std::vector<std::size_t> &tags,
7270  std::vector<std::vector<double> > &data,
7271  double &time, int &numComponents)
7272 {
7273  if(!_checkInit()) return;
7274  tags.clear();
7275  data.clear();
7276 #if defined(HAVE_POST)
7277  int numEnt, maxMult;
7278  stepData<double> *s =
7279  _getModelData(tag, step, dataType, time, numComponents, numEnt, maxMult);
7280  if(!s || !numComponents || !numEnt || !maxMult) return;
7281  data.resize(numEnt);
7282  tags.resize(numEnt);
7283  std::size_t j = 0;
7284  for(std::size_t i = 0; i < s->getNumData(); i++) {
7285  double *dd = s->getData(i);
7286  if(dd) {
7287  tags[j] = i;
7288  int mult = s->getMult(i);
7289  data[j].resize(numComponents * mult);
7290  for(int k = 0; k < numComponents * mult; k++) data[j][k] = dd[k];
7291  j++;
7292  }
7293  }
7294 #else
7295  Msg::Error("Views require the post-processing module");
7296 #endif
7297 }
7298 
7299 GMSH_API void gmsh::view::getHomogeneousModelData(
7300  const int tag, const int step, std::string &dataType,
7301  std::vector<std::size_t> &tags, std::vector<double> &data, double &time,
7302  int &numComponents)
7303 {
7304  if(!_checkInit()) return;
7305  tags.clear();
7306  data.clear();
7307 #if defined(HAVE_POST)
7308  int numEnt, maxMult;
7309  stepData<double> *s =
7310  _getModelData(tag, step, dataType, time, numComponents, numEnt, maxMult);
7311  if(!s || !numComponents || !numEnt || !maxMult) return;
7312  data.resize(numEnt * numComponents * maxMult, 0.);
7313  tags.resize(numEnt);
7314  std::size_t j = 0;
7315  for(std::size_t i = 0; i < s->getNumData(); i++) {
7316  double *dd = s->getData(i);
7317  if(dd) {
7318  tags[j] = i;
7319  int mult = s->getMult(i);
7320  for(int k = 0; k < numComponents * mult; k++) {
7321  data[j * numComponents * maxMult + k] = dd[k];
7322  }
7323  j++;
7324  }
7325  }
7326 #else
7327  Msg::Error("Views require the post-processing module");
7328 #endif
7329 }
7330 
7331 // for better performance, manual C implementation of gmsh::view::getModelData
7332 GMSH_API void gmshViewGetModelData(const int tag, const int step,
7333  char **dataType, size_t **tags,
7334  size_t *tags_n, double ***data,
7335  size_t **data_n, size_t *data_nn,
7336  double *time, int *numComponents, int *ierr)
7337 {
7338  if(!_checkInit()) {
7339  if(ierr) *ierr = -1;
7340  return;
7341  }
7342 #if defined(HAVE_POST)
7343  PView *view = PView::getViewByTag(tag);
7344  if(!view) {
7345  Msg::Error("Unknown view with tag %d", tag);
7346  if(ierr) *ierr = 2;
7347  return;
7348  }
7349  PViewDataGModel *d = dynamic_cast<PViewDataGModel *>(view->getData());
7350  if(!d) {
7351  Msg::Error("View with tag %d does not contain model data", tag);
7352  return;
7353  }
7355  *dataType = strdup("NodeData");
7356  else if(d->getType() == PViewDataGModel::ElementData)
7357  *dataType = strdup("ElementData");
7358  else if(d->getType() == PViewDataGModel::ElementNodeData)
7359  *dataType = strdup("ElementNodeData");
7360  else if(d->getType() == PViewDataGModel::GaussPointData)
7361  *dataType = strdup("GaussPointData");
7362  else if(d->getType() == PViewDataGModel::BeamData)
7363  *dataType = strdup("Beam");
7364  else
7365  *dataType = strdup("Unknown");
7366  stepData<double> *s = d->getStepData(step);
7367  if(!s) {
7368  Msg::Error("View with tag %d does not contain model data for step %d", tag,
7369  step);
7370  if(ierr) *ierr = 2;
7371  return;
7372  }
7373  *tags_n = 0;
7374  *data_nn = 0;
7375  *time = s->getTime();
7376  *numComponents = s->getNumComponents();
7377  int numEnt = 0;
7378  for(size_t i = 0; i < s->getNumData(); i++) {
7379  if(s->getData(i)) numEnt++;
7380  }
7381  if(!numEnt) return;
7382  *tags_n = numEnt;
7383  *tags = (size_t *)Malloc(numEnt * sizeof(size_t));
7384  *data_nn = numEnt;
7385  *data_n = (size_t *)Malloc(numEnt * sizeof(size_t *));
7386  *data = (double **)Malloc(numEnt * sizeof(double *));
7387  size_t j = 0;
7388  for(size_t i = 0; i < s->getNumData(); i++) {
7389  double *dd = s->getData(i);
7390  if(dd) {
7391  (*tags)[j] = i;
7392  int mult = s->getMult(i);
7393  (*data_n)[j] = *numComponents * mult;
7394  (*data)[j] = (double *)Malloc(*numComponents * mult * sizeof(double));
7395  for(int k = 0; k < *numComponents * mult; k++) (*data)[j][k] = dd[k];
7396  j++;
7397  }
7398  }
7399  if(ierr) *ierr = 0;
7400 #else
7401  Msg::Error("Views require the post-processing module");
7402  if(ierr) *ierr = -1;
7403 #endif
7404 }
7405 
7406 GMSH_API void gmsh::view::addListData(const int tag,
7407  const std::string &dataType,
7408  const int numElements,
7409  const std::vector<double> &data)
7410 {
7411  if(!_checkInit()) return;
7412 #if defined(HAVE_POST)
7413  PView *view = PView::getViewByTag(tag);
7414  if(!view) {
7415  Msg::Error("Unknown view with tag %d", tag);
7416  return;
7417  }
7418  PViewDataList *d = dynamic_cast<PViewDataList *>(view->getData());
7419  if(!d) { // change the view type
7420  std::string name = view->getData()->getName();
7421  delete view->getData();
7422  d = new PViewDataList();
7423  d->setName(name);
7424  d->setFileName(name + ".pos");
7425  view->setData(d);
7426  }
7427  const char *types[] = {"SP", "VP", "TP", "SL", "VL", "TL", "ST", "VT",
7428  "TT", "SQ", "VQ", "TQ", "SS", "VS", "TS", "SH",
7429  "VH", "TH", "SI", "VI", "TI", "SY", "VY", "TY"};
7430  for(int idxtype = 0; idxtype < 24; idxtype++) {
7431  if(dataType == types[idxtype]) {
7432  d->importList(idxtype, numElements, data, true);
7433  view->setChanged(true);
7434  return;
7435  }
7436  }
7437  Msg::Error("Unknown data type for list import");
7438 #else
7439  Msg::Error("Views require the post-processing module");
7440 #endif
7441 }
7442 
7443 GMSH_API void gmsh::view::getListData(const int tag,
7444  std::vector<std::string> &dataTypes,
7445  std::vector<int> &numElements,
7446  std::vector<std::vector<double> > &data)
7447 {
7448  if(!_checkInit()) return;
7449 #if defined(HAVE_POST)
7450  PView *view = PView::getViewByTag(tag);
7451  if(!view) {
7452  Msg::Error("Unknown view with tag %d", tag);
7453  return;
7454  }
7455  PViewDataList *d = dynamic_cast<PViewDataList *>(view->getData());
7456  if(!d) {
7457  Msg::Error("View with tag %d does not contain list data", tag);
7458  return;
7459  }
7460  const char *types[] = {"SP", "VP", "TP", "SL", "VL", "TL", "ST", "VT",
7461  "TT", "SQ", "VQ", "TQ", "SS", "VS", "TS", "SH",
7462  "VH", "TH", "SI", "VI", "TI", "SY", "VY", "TY"};
7463  std::vector<int> N(24);
7464  std::vector<std::vector<double> *> V(24);
7465  d->getListPointers(&N[0], &V[0]);
7466  for(int idxtype = 0; idxtype < 24; idxtype++) {
7467  if(N[idxtype]) {
7468  dataTypes.push_back(types[idxtype]);
7469  numElements.push_back(N[idxtype]);
7470  data.push_back(*V[idxtype]);
7471  }
7472  }
7473 #else
7474  Msg::Error("Views require the post-processing module");
7475 #endif
7476 }
7477 
7478 #if defined(HAVE_POST)
7479 static double getStringStyle(const std::vector<std::string> &style)
7480 {
7481  if(style.empty()) return 0.;
7482  int align = 0, font = 0, fontsize = CTX::instance()->glFontSize;
7483  if(style.size() % 2) {
7484  Msg::Error("Number of string style attributes should be even");
7485  }
7486  else {
7487  for(std::size_t i = 0; i < style.size(); i += 2) {
7488  std::string key = style[i], val = style[i + 1];
7489 #if defined(HAVE_OPENGL)
7490  if(key == "Font")
7491  font = drawContext::global()->getFontIndex(val.c_str());
7492  else if(key == "FontSize")
7493  fontsize = atoi(val.c_str());
7494  else if(key == "Align")
7495  align = drawContext::global()->getFontAlign(val.c_str());
7496 #endif
7497  }
7498  }
7499  return (double)((align << 16) | (font << 8) | (fontsize));
7500 }
7501 #endif
7502 
7503 GMSH_API void
7504 gmsh::view::addListDataString(const int tag, const std::vector<double> &coord,
7505  const std::vector<std::string> &data,
7506  const std::vector<std::string> &style)
7507 {
7508  if(!_checkInit()) return;
7509 #if defined(HAVE_POST)
7510  PView *view = PView::getViewByTag(tag);
7511  if(!view) {
7512  Msg::Error("Unknown view with tag %d", tag);
7513  return;
7514  }
7515  PViewDataList *d = dynamic_cast<PViewDataList *>(view->getData());
7516  if(!d) { // change the view type
7517  std::string name = view->getData()->getName();
7518  delete view->getData();
7519  d = new PViewDataList();
7520  d->setName(name);
7521  d->setFileName(name + ".pos");
7522  view->setData(d);
7523  }
7524  if(coord.size() == 3) {
7525  d->T3D.push_back(coord[0]);
7526  d->T3D.push_back(coord[1]);
7527  d->T3D.push_back(coord[2]);
7528  d->T3D.push_back(getStringStyle(style)), d->T3D.push_back(d->T3C.size());
7529  d->NbT3++;
7530  for(std::size_t i = 0; i < data.size(); i++) {
7531  for(std::size_t j = 0; j < data[i].size(); j++) {
7532  d->T3C.push_back(data[i][j]);
7533  }
7534  d->T3C.push_back('\0');
7535  }
7536  }
7537  else if(coord.size() == 2) {
7538  d->T2D.push_back(coord[0]);
7539  d->T2D.push_back(coord[1]);
7540  d->T2D.push_back(getStringStyle(style)), d->T2D.push_back(d->T2C.size());
7541  d->NbT2++;
7542  for(std::size_t i = 0; i < data.size(); i++) {
7543  for(std::size_t j = 0; j < data[i].size(); j++) {
7544  d->T2C.push_back(data[i][j]);
7545  }
7546  d->T2C.push_back('\0');
7547  }
7548  }
7549  d->finalize();
7550  view->setChanged(true);
7551 #else
7552  Msg::Error("Views require the post-processing module");
7553 #endif
7554 }
7555 
7556 GMSH_API void gmsh::view::getListDataStrings(const int tag, const int dim,
7557  std::vector<double> &coord,
7558  std::vector<std::string> &data,
7559  std::vector<std::string> &style)
7560 {
7561  if(!_checkInit()) return;
7562 #if defined(HAVE_POST)
7563  PView *view = PView::getViewByTag(tag);
7564  if(!view) {
7565  Msg::Error("Unknown view with tag %d", tag);
7566  return;
7567  }
7568  PViewDataList *d = dynamic_cast<PViewDataList *>(view->getData());
7569  if(!d) {
7570  Msg::Error("View with tag %d does not contain list data", tag);
7571  return;
7572  }
7573  int nstep = d->getNumTimeSteps();
7574  if(dim == 3) {
7575  int ns = d->getNumStrings3D();
7576  for(int i = 0; i < ns; i++) {
7577  for(int j = 0; j < nstep; j++) {
7578  double x, y, z, styl;
7579  std::string s;
7580  d->getString3D(i, j, s, x, y, z, styl);
7581  if(i == 0) {
7582  coord.push_back(x);
7583  coord.push_back(y);
7584  coord.push_back(z);
7585  }
7586  data.push_back(s);
7587  // TODO convert style to strings, pad with empty strings so that all
7588  // strings return the same number of styling pairs
7589  style.push_back("");
7590  }
7591  }
7592  }
7593  else if(dim == 2) {
7594  int ns = d->getNumStrings2D();
7595  for(int i = 0; i < ns; i++) {
7596  for(int j = 0; j < nstep; j++) {
7597  double x, y, styl;
7598  std::string s;
7599  d->getString2D(i, j, s, x, y, styl);
7600  if(i == 0) {
7601  coord.push_back(x);
7602  coord.push_back(y);
7603  }
7604  data.push_back(s);
7605  // TODO convert style to strings, pad with empty strings so that all
7606  // strings return the same number of styling pairs
7607  style.push_back("");
7608  }
7609  }
7610  }
7611 #else
7612  Msg::Error("Views require the post-processing module");
7613 #endif
7614 }
7615 
7616 GMSH_API void gmsh::view::setInterpolationMatrices(
7617  const int tag, const std::string &type, const int d,
7618  const std::vector<double> &coef, const std::vector<double> &exp,
7619  const int dGeo, const std::vector<double> &coefGeo,
7620  const std::vector<double> &expGeo)
7621 {
7622  if(!_checkInit()) return;
7623 #if defined(HAVE_POST)
7624  PView *view = PView::getViewByTag(tag);
7625  if(!view) {
7626  Msg::Error("Unknown view with tag %d", tag);
7627  return;
7628  }
7629  PViewData *data = view->getData();
7630  if(!data) {
7631  Msg::Error("View with tag %d does not contain any data", tag);
7632  return;
7633  }
7634 
7635  int itype = 0;
7636  if(type == "Line" || type == "line")
7637  itype = TYPE_LIN;
7638  else if(type == "Triangle" || type == "triangle")
7639  itype = TYPE_TRI;
7640  else if(type == "Quadrangle" || type == "quadrangle")
7641  itype = TYPE_QUA;
7642  else if(type == "Tetrahedron" || type == "tetrahedron")
7643  itype = TYPE_TET;
7644  else if(type == "Pyramid" || type == "pyramid")
7645  itype = TYPE_PYR;
7646  else if(type == "Prism" || type == "prism")
7647  itype = TYPE_PRI;
7648  else if(type == "Hexahedron" || type == "hexahedron")
7649  itype = TYPE_HEX;
7650  else {
7651  Msg::Error("Unknown element family type '%s'", type.c_str());
7652  return;
7653  }
7654 
7655  if(data->haveInterpolationMatrices(itype))
7656  data->deleteInterpolationMatrices(itype);
7657 
7658  if(d <= 0) return;
7659 
7660  // field interpolation coefficients and exponents
7661  if((int)coef.size() != d * d) {
7662  Msg::Error("Wrong number of coefficients (%d != %d x %d)", (int)coef.size(),
7663  d, d);
7664  return;
7665  }
7666  if((int)exp.size() != d * 3) {
7667  Msg::Error("Wrong number of exponents (%d != %d x 3)", (int)exp.size(), d);
7668  return;
7669  }
7670  fullMatrix<double> F(d, d), P(d, 3);
7671  for(int i = 0; i < d; i++) {
7672  for(int j = 0; j < d; j++) { F(i, j) = coef[d * i + j]; }
7673  for(int j = 0; j < 3; j++) { P(i, j) = exp[3 * i + j]; }
7674  }
7675 
7676  if(dGeo <= 0) {
7677  data->setInterpolationMatrices(itype, F, P);
7678  view->setChanged(true);
7679  return;
7680  }
7681 
7682  // geometry interpolation coefficients and exponents
7683  if((int)coefGeo.size() != dGeo * dGeo) {
7684  Msg::Error("Wrong number of coefficients (%d != %d x %d)",
7685  (int)coefGeo.size(), dGeo, dGeo);
7686  return;
7687  }
7688  if((int)expGeo.size() != dGeo * 3) {
7689  Msg::Error("Wrong number of exponents (%d != %d x 3)", (int)expGeo.size(),
7690  dGeo);
7691  return;
7692  }
7693  fullMatrix<double> Fg(dGeo, dGeo), Pg(dGeo, 3);
7694  for(int i = 0; i < dGeo; i++) {
7695  for(int j = 0; j < dGeo; j++) { Fg(i, j) = coefGeo[dGeo * i + j]; }
7696  for(int j = 0; j < 3; j++) { Pg(i, j) = expGeo[3 * i + j]; }
7697  }
7698  data->setInterpolationMatrices(itype, F, P, Fg, Pg);
7699  view->setChanged(true);
7700 #else
7701  Msg::Error("Views require the post-processing module");
7702 #endif
7703 }
7704 
7705 GMSH_API int gmsh::view::addAlias(const int refTag, const bool copyOptions,
7706  const int tag)
7707 {
7708  if(!_checkInit()) return -1;
7709 #if defined(HAVE_POST)
7710  PView *ref = PView::getViewByTag(refTag);
7711  if(!ref) {
7712  Msg::Error("Unknown view with tag %d", refTag);
7713  return -1;
7714  }
7715  PView *view = new PView(ref, copyOptions, tag);
7716 #if defined(HAVE_FLTK)
7717  if(FlGui::available()) FlGui::instance()->updateViews(true, true);
7718 #endif
7719  return view->getTag();
7720 #else
7721  Msg::Error("Views require the post-processing module");
7722  return -1;
7723 #endif
7724 }
7725 
7726 GMSH_API void gmsh::view::combine(const std::string &what,
7727  const std::string &how, const bool remove,
7728  const bool copyOptions)
7729 {
7730  if(!_checkInit()) return;
7731 #if defined(HAVE_POST)
7732  bool time = (what == "steps") ? true : false; // "elements"
7733  int ihow = (how == "all") ? 1 : (how == "name") ? 2 : 0; // "visible"
7734  PView::combine(time, ihow, remove, copyOptions);
7735 #if defined(HAVE_FLTK)
7736  if(FlGui::available()) FlGui::instance()->updateViews(true, true);
7737 #endif
7738 #else
7739  Msg::Error("Views require the post-processing module");
7740 #endif
7741 }
7742 
7743 GMSH_API void gmsh::view::probe(const int tag, const double x, const double y,
7744  const double z, std::vector<double> &values,
7745  double &distance, const int step,
7746  const int numComp, const bool gradient,
7747  const double distanceMax,
7748  const std::vector<double> &xElemCoord,
7749  const std::vector<double> &yElemCoord,
7750  const std::vector<double> &zElemCoord,
7751  const int dim)
7752 {
7753  if(!_checkInit()) return;
7754 #if defined(HAVE_POST)
7755  PView *view = PView::getViewByTag(tag);
7756  if(!view) {
7757  Msg::Error("Unknown view with tag %d", tag);
7758  return;
7759  }
7760  PViewData *data = view->getData();
7761  if(!data) {
7762  Msg::Error("No data in view %d", tag);
7763  return;
7764  }
7765  values.clear();
7766  std::vector<double> val(9 * data->getNumTimeSteps() * 3);
7767  int qn = 0;
7768  double *qx = nullptr, *qy = nullptr, *qz = nullptr;
7769  if(xElemCoord.size() && yElemCoord.size() && zElemCoord.size() &&
7770  xElemCoord.size() == yElemCoord.size() &&
7771  xElemCoord.size() == zElemCoord.size()) {
7772  qn = xElemCoord.size();
7773  qx = (double *)&xElemCoord[0];
7774  qy = (double *)&yElemCoord[0];
7775  qz = (double *)&zElemCoord[0];
7776  }
7777  int numSteps = (step < 0) ? data->getNumTimeSteps() : 1;
7778  int mult = gradient ? 3 : 1;
7779  int numVal = 0;
7780  distance = distanceMax;
7781  switch(numComp) {
7782  case 1:
7783  if(data->searchScalarClosest(x, y, z, distance, &val[0], step, nullptr,
7784  qn, qx, qy, qz, gradient, dim)) {
7785  numVal = numSteps * mult * 1;
7786  }
7787  break;
7788  case 3:
7789  if(data->searchVectorClosest(x, y, z, distance, &val[0], step, nullptr,
7790  qn, qx, qy, qz, gradient, dim)) {
7791  numVal = numSteps * mult * 3;
7792  }
7793  break;
7794  case 9:
7795  if(data->searchTensorClosest(x, y, z, distance, &val[0], step, nullptr,
7796  qn, qx, qy, qz, gradient, dim)) {
7797  numVal = numSteps * mult * 9;
7798  }
7799  break;
7800  default:
7801  if(data->searchScalarClosest(x, y, z, distance, &val[0], step, nullptr,
7802  qn, qx, qy, qz, gradient, dim)) {
7803  numVal = numSteps * mult * 1;
7804  }
7805  else if(data->searchVectorClosest(x, y, z, distance, &val[0], step, nullptr,
7806  qn, qx, qy, qz, gradient,
7807  dim)) {
7808  numVal = numSteps * mult * 3;
7809  }
7810  else if(data->searchTensorClosest(x, y, z, distance, &val[0], step, nullptr,
7811  qn, qx, qy, qz, gradient,
7812  dim)) {
7813  numVal = numSteps * mult * 9;
7814  }
7815  break;
7816  }
7817  for(int i = 0; i < numVal; i++) values.push_back(val[i]);
7818 #else
7819  Msg::Error("Views require the post-processing module");
7820 #endif
7821 }
7822 
7823 GMSH_API void gmsh::view::write(const int tag, const std::string &fileName,
7824  const bool append)
7825 {
7826  if(!_checkInit()) return;
7827 #if defined(HAVE_POST)
7828  PView *view = PView::getViewByTag(tag);
7829  if(!view) {
7830  Msg::Error("Unknown view with tag %d", tag);
7831  return;
7832  }
7833  view->write(fileName, 10, append);
7834 #else
7835  Msg::Error("Views require the post-processing module");
7836 #endif
7837 }
7838 
7839 GMSH_API void gmsh::view::setVisibilityPerWindow(const int tag, const int value,
7840  const int windowIndex)
7841 {
7842  if(!_checkInit()) return;
7843 #if defined(HAVE_POST)
7844  PView *view = PView::getViewByTag(tag);
7845  if(!view) {
7846  Msg::Error("Unknown view with tag %d", tag);
7847  return;
7848  }
7849 #if defined(HAVE_FLTK)
7850  FlGui::instance()->setCurrentOpenglWindow(windowIndex);
7851  drawContext *ctx = FlGui::instance()->getCurrentDrawContext();
7852  if(value)
7853  ctx->show(view);
7854  else
7855  ctx->hide(view);
7856 #endif
7857 #else
7858  Msg::Error("Views require the post-processing module");
7859 #endif
7860 }
7861 
7862 // gmsh::view::option
7863 
7864 GMSH_API void gmsh::view::option::setNumber(int tag, const std::string &name,
7865  const double value)
7866 {
7867  if(!_checkInit()) return;
7868 #if defined(HAVE_POST)
7869  PView *view = PView::getViewByTag(tag);
7870  if(view) {
7871  if(!GmshSetOption("View", name, value, view->getIndex()))
7872  Msg::Error("Could not set option '%s' in view with tag %d",
7873  name.c_str(), tag);
7874  }
7875  else {
7876  Msg::Error("Unknown view with tag %d", tag);
7877  }
7878 #else
7879  Msg::Error("Views require the post-processing module");
7880 #endif
7881 }
7882 
7883 GMSH_API void gmsh::view::option::getNumber(int tag, const std::string &name,
7884  double &value)
7885 {
7886  if(!_checkInit()) return;
7887 #if defined(HAVE_POST)
7888  PView *view = PView::getViewByTag(tag);
7889  if(view) {
7890  if(!GmshGetOption("View", name, value, view->getIndex()))
7891  Msg::Error("Could not get option '%s' in view with tag %d",
7892  name.c_str(), tag);
7893  }
7894  else {
7895  Msg::Error("Unknown view with tag %d", tag);
7896  }
7897 #else
7898  Msg::Error("Views require the post-processing module");
7899 #endif
7900 }
7901 
7902 GMSH_API void gmsh::view::option::setString(int tag, const std::string &name,
7903  const std::string &value)
7904 {
7905  if(!_checkInit()) return;
7906 #if defined(HAVE_POST)
7907  PView *view = PView::getViewByTag(tag);
7908  if(view) {
7909  if(!GmshSetOption("View", name, value, view->getIndex()))
7910  Msg::Error("Could not set option '%s' in view with tag %d",
7911  name.c_str(), tag);
7912  }
7913  else {
7914  Msg::Error("Unknown view with tag %d", tag);
7915  }
7916 #else
7917  Msg::Error("Views require the post-processing module");
7918 #endif
7919 }
7920 
7921 GMSH_API void gmsh::view::option::getString(int tag, const std::string &name,
7922  std::string &value)
7923 {
7924  if(!_checkInit()) return;
7925 #if defined(HAVE_POST)
7926  PView *view = PView::getViewByTag(tag);
7927  if(view) {
7928  if(!GmshGetOption("View", name, value, view->getIndex()))
7929  Msg::Error("Could not get option '%s' in view with tag %d",
7930  name.c_str(), tag);
7931  }
7932  else {
7933  Msg::Error("Unknown view with tag %d", tag);
7934  }
7935 #else
7936  Msg::Error("Views require the post-processing module");
7937 #endif
7938 }
7939 
7940 GMSH_API void gmsh::view::option::setColor(int tag, const std::string &name,
7941  const int r, const int g,
7942  const int b, const int a)
7943 {
7944  if(!_checkInit()) return;
7945 #if defined(HAVE_POST)
7946  PView *view = PView::getViewByTag(tag);
7947  if(view) {
7948  unsigned int value = CTX::instance()->packColor(r, g, b, a);
7949  if(!GmshSetOption("View", name, value, view->getIndex()))
7950  Msg::Error("Could not set option '%s' in view with tag %d",
7951  name.c_str(), tag);
7952  }
7953  else {
7954  Msg::Error("Unknown view with tag %d", tag);
7955  }
7956 #else
7957  Msg::Error("Views require the post-processing module");
7958 #endif
7959 }
7960 
7961 GMSH_API void gmsh::view::option::getColor(int tag, const std::string &name,
7962  int &r, int &g, int &b, int &a)
7963 {
7964  if(!_checkInit()) return;
7965 #if defined(HAVE_POST)
7966  PView *view = PView::getViewByTag(tag);
7967  if(view) {
7968  unsigned int value;
7969  if(GmshGetOption("View", name, value, view->getIndex())) {
7970  r = CTX::instance()->unpackRed(value);
7971  g = CTX::instance()->unpackGreen(value);
7972  b = CTX::instance()->unpackBlue(value);
7973  a = CTX::instance()->unpackAlpha(value);
7974  }
7975  else {
7976  Msg::Error("Could not get option '%s' in view with tag %d",
7977  name.c_str(), tag);
7978  }
7979  }
7980  else {
7981  Msg::Error("Unknown view with tag %d", tag);
7982  }
7983 #else
7984  Msg::Error("Views require the post-processing module");
7985 #endif
7986 }
7987 
7988 GMSH_API void gmsh::view::option::copy(const int refTag, const int tag)
7989 {
7990  if(!_checkInit()) return;
7991 #if defined(HAVE_POST)
7992  PView *ref = PView::getViewByTag(refTag);
7993  if(!ref) {
7994  Msg::Error("Unknown view with tag %d", refTag);
7995  return;
7996  }
7997  PView *view = PView::getViewByTag(tag);
7998  if(!view) {
7999  Msg::Error("Unknown view with tag %d", tag);
8000  return;
8001  }
8002  view->setOptions(ref->getOptions());
8003  view->setChanged(true);
8004 #if defined(HAVE_FLTK)
8005  if(FlGui::available()) FlGui::instance()->updateViews(true, true);
8006 #endif
8007 #else
8008  Msg::Error("Views require the post-processing module");
8009 #endif
8010 }
8011 
8012 // gmsh::plugin
8013 
8014 GMSH_API void gmsh::plugin::setNumber(const std::string &name,
8015  const std::string &option,
8016  const double value)
8017 {
8018  if(!_checkInit()) return;
8019 #if defined(HAVE_PLUGINS)
8020  try {
8021  PluginManager::instance()->setPluginOption(name, option, value);
8022  } catch(...) {
8023  Msg::Error("Unknown plugin or plugin option");
8024  }
8025 #else
8026  Msg::Error("Views require the post-processing and plugin modules");
8027 #endif
8028 }
8029 
8030 GMSH_API void gmsh::plugin::setString(const std::string &name,
8031  const std::string &option,
8032  const std::string &value)
8033 {
8034  if(!_checkInit()) return;
8035 #if defined(HAVE_PLUGINS)
8036  try {
8037  PluginManager::instance()->setPluginOption(name, option, value);
8038  } catch(...) {
8039  Msg::Error("Unknown plugin or plugin option");
8040  }
8041 #else
8042  Msg::Error("Views require the post-processing and plugin modules");
8043 #endif
8044 }
8045 
8046 GMSH_API int gmsh::plugin::run(const std::string &name)
8047 {
8048  if(!_checkInit()) return 0;
8049 #if defined(HAVE_PLUGINS)
8050  try {
8051  return PluginManager::instance()->action(name, "Run", nullptr);
8052  } catch(...) {
8053  Msg::Error("Unknown plugin or plugin action");
8054  return 0;
8055  }
8056 #else
8057  Msg::Error("Views require the post-processing and plugin modules");
8058  return 0;
8059 #endif
8060 }
8061 
8062 // gmsh::graphics
8063 
8064 GMSH_API void gmsh::graphics::draw()
8065 {
8066 #if defined(HAVE_OPENGL)
8067  drawContext::global()->draw(false); // not rate-limited
8068 #endif
8069 }
8070 
8071 // gmsh::fltk
8072 
8073 #if defined(HAVE_FLTK)
8074 static void _errorHandlerFltk(const char *fmt, ...)
8075 {
8076  char str[5000];
8077  va_list args;
8078  va_start(args, fmt);
8079  vsnprintf(str, sizeof(str), fmt, args);
8080  va_end(args);
8081  Msg::Error("%s (FLTK internal error)", str);
8082 }
8083 
8084 static void _createFltk()
8085 {
8086  if(!FlGui::available())
8087  FlGui::instance(_argc, _argv, false, _errorHandlerFltk);
8088 }
8089 #endif
8090 
8091 GMSH_API void gmsh::fltk::initialize()
8092 {
8093  if(!_checkInit()) return;
8094 #if defined(HAVE_FLTK)
8095  _createFltk();
8096  FlGui::setFinishedProcessingCommandLine();
8097  FlGui::check();
8098 #else
8099  Msg::Error("Fltk not available");
8100 #endif
8101 }
8102 
8103 GMSH_API void gmsh::fltk::finalize()
8104 {
8105  if(!_checkInit()) return;
8106 #if defined(HAVE_FLTK)
8107  FlGui::destroy();
8108 #else
8109  Msg::Error("Fltk not available");
8110 #endif
8111 }
8112 
8113 GMSH_API int gmsh::fltk::isAvailable()
8114 {
8115  if(!_checkInit()) return -1;
8116 #if defined(HAVE_FLTK)
8117  return FlGui::available() ? 1 : 0;
8118 #else
8119  return 0;
8120 #endif
8121 }
8122 
8123 GMSH_API void gmsh::fltk::wait(const double time)
8124 {
8125  if(!_checkInit()) return;
8126 #if defined(HAVE_FLTK)
8127  _createFltk();
8128  if(time >= 0)
8129  FlGui::wait(time, true); // force
8130  else
8131  FlGui::wait(true); // force
8132 #else
8133  Msg::Error("Fltk not available");
8134 #endif
8135 }
8136 
8137 GMSH_API void gmsh::fltk::lock()
8138 {
8139  if(!_checkInit()) return;
8140 #if defined(HAVE_FLTK)
8141  FlGui::lock();
8142 #else
8143  Msg::Error("Fltk not available");
8144 #endif
8145 }
8146 
8147 GMSH_API void gmsh::fltk::unlock()
8148 {
8149  if(!_checkInit()) return;
8150 #if defined(HAVE_FLTK)
8151  FlGui::unlock();
8152 #else
8153  Msg::Error("Fltk not available");
8154 #endif
8155 }
8156 
8157 GMSH_API void gmsh::fltk::update()
8158 {
8159  if(!_checkInit()) return;
8160 #if defined(HAVE_FLTK)
8161  _createFltk();
8162  FlGui::instance()->updateViews(true, true);
8163 #else
8164  Msg::Error("Fltk not available");
8165 #endif
8166 }
8167 
8168 GMSH_API void gmsh::fltk::awake(const std::string &action)
8169 {
8170  if(!_checkInit()) return;
8171 #if defined(HAVE_FLTK)
8172  FlGui::awake(action);
8173 #else
8174  Msg::Error("Fltk not available");
8175 #endif
8176 }
8177 
8178 GMSH_API void gmsh::fltk::run()
8179 {
8180  if(!_checkInit()) return;
8181 #if defined(HAVE_FLTK)
8182  _createFltk();
8183  FlGui::instance()->run(); // this calls draw() once
8184 #else
8185  Msg::Error("Fltk not available");
8186 #endif
8187 }
8188 
8189 #if defined(HAVE_FLTK)
8190 static int selectionCode(char val)
8191 {
8192  switch(val) {
8193  case 'q': return 0; // abort
8194  case 'l': return 1; // selected
8195  case 'r': return 2; // deselected
8196  case 'u': return 3; // undone last selection
8197  case 'e': return 4; // ended selection
8198  default: return -1; // unknown code
8199  }
8200 }
8201 #endif
8202 
8203 GMSH_API int gmsh::fltk::selectEntities(vectorpair &dimTags, const int dim)
8204 {
8205  if(!_checkInit()) return -1;
8206  dimTags.clear();
8207 #if defined(HAVE_FLTK)
8208  _createFltk();
8209  char ret = 0;
8210  switch(dim) {
8211  case 0: ret = FlGui::instance()->selectEntity(ENT_POINT); break;
8212  case 1: ret = FlGui::instance()->selectEntity(ENT_CURVE); break;
8213  case 2: ret = FlGui::instance()->selectEntity(ENT_SURFACE); break;
8214  case 3: ret = FlGui::instance()->selectEntity(ENT_VOLUME); break;
8215  default: ret = FlGui::instance()->selectEntity(ENT_ALL); break;
8216  }
8217  if(!FlGui::available()) return 0; // GUI closed during selection
8218  for(std::size_t i = 0; i < FlGui::instance()->selectedVertices.size(); i++)
8219  dimTags.push_back(
8220  std::make_pair(0, FlGui::instance()->selectedVertices[i]->tag()));
8221  for(std::size_t i = 0; i < FlGui::instance()->selectedEdges.size(); i++)
8222  dimTags.push_back(
8223  std::make_pair(1, FlGui::instance()->selectedEdges[i]->tag()));
8224  for(std::size_t i = 0; i < FlGui::instance()->selectedFaces.size(); i++)
8225  dimTags.push_back(
8226  std::make_pair(2, FlGui::instance()->selectedFaces[i]->tag()));
8227  for(std::size_t i = 0; i < FlGui::instance()->selectedRegions.size(); i++)
8228  dimTags.push_back(
8229  std::make_pair(3, FlGui::instance()->selectedRegions[i]->tag()));
8230  return selectionCode(ret);
8231 #else
8232  return 0;
8233 #endif
8234 }
8235 
8236 GMSH_API int gmsh::fltk::selectElements(std::vector<std::size_t> &elementTags)
8237 {
8238  if(!_checkInit()) return -1;
8239  elementTags.clear();
8240 #if defined(HAVE_FLTK)
8241  _createFltk();
8242  int old = CTX::instance()->pickElements;
8243  CTX::instance()->pickElements = 1;
8245  char ret = FlGui::instance()->selectEntity(ENT_ALL);
8246  CTX::instance()->pickElements = old;
8247  if(!FlGui::available()) return 0; // GUI closed during selection
8248  for(std::size_t i = 0; i < FlGui::instance()->selectedElements.size(); i++)
8249  elementTags.push_back(FlGui::instance()->selectedElements[i]->getNum());
8250  return selectionCode(ret);
8251 #else
8252  return 0;
8253 #endif
8254 }
8255 
8256 GMSH_API int gmsh::fltk::selectViews(std::vector<int> &viewTags)
8257 {
8258  if(!_checkInit()) return -1;
8259  viewTags.clear();
8260 #if defined(HAVE_FLTK)
8261  _createFltk();
8262  char ret = FlGui::instance()->selectEntity(ENT_ALL);
8263  if(!FlGui::available()) return 0; // GUI closed during selection
8264  for(std::size_t i = 0; i < FlGui::instance()->selectedViews.size(); i++)
8265  viewTags.push_back(FlGui::instance()->selectedViews[i]->getTag());
8266  return selectionCode(ret);
8267 #else
8268  return 0;
8269 #endif
8270 }
8271 
8272 GMSH_API void gmsh::fltk::splitCurrentWindow(const std::string &how,
8273  const double ratio)
8274 {
8275  if(!_checkInit()) return;
8276 #if defined(HAVE_FLTK)
8277  _createFltk();
8278  if(how == "h")
8279  FlGui::instance()->splitCurrentOpenglWindow('h', ratio);
8280  else if(how == "v")
8281  FlGui::instance()->splitCurrentOpenglWindow('v', ratio);
8282  else if(how == "u")
8283  FlGui::instance()->splitCurrentOpenglWindow('u');
8284  else {
8285  Msg::Error("Unknown window splitting method '%s'", how.c_str());
8286  }
8287 #endif
8288 }
8289 
8290 GMSH_API void gmsh::fltk::setCurrentWindow(const int windowIndex)
8291 {
8292  if(!_checkInit()) return;
8293 #if defined(HAVE_FLTK)
8294  _createFltk();
8295  FlGui::instance()->setCurrentOpenglWindow(windowIndex);
8296 #endif
8297 }
8298 
8299 GMSH_API void gmsh::fltk::setStatusMessage(const std::string &message,
8300  const bool graphics)
8301 {
8302  if(!_checkInit()) return;
8303 #if defined(HAVE_FLTK)
8304  _createFltk();
8305  FlGui::instance()->setStatus(message, graphics);
8306 #endif
8307 }
8308 
8309 GMSH_API void gmsh::fltk::showContextWindow(const int dim, const int tag)
8310 {
8311  if(!_checkInit()) return;
8312 #if defined(HAVE_FLTK)
8313  _createFltk();
8314  FlGui::instance()->showOnelabContext(dim, tag);
8315 #endif
8316 }
8317 
8318 GMSH_API void gmsh::fltk::openTreeItem(const std::string &name)
8319 {
8320  if(!_checkInit()) return;
8321 #if defined(HAVE_FLTK)
8322  _createFltk();
8323  FlGui::instance()->openTreeItem(name);
8324 #endif
8325 }
8326 
8327 GMSH_API void gmsh::fltk::closeTreeItem(const std::string &name)
8328 {
8329  if(!_checkInit()) return;
8330 #if defined(HAVE_FLTK)
8331  _createFltk();
8332  FlGui::instance()->closeTreeItem(name);
8333 #endif
8334 }
8335 
8336 // gmsh::parser
8337 
8338 GMSH_API void gmsh::parser::getNames(std::vector<std::string> &names,
8339  const std::string &search)
8340 {
8341  if(!_checkInit()) return;
8342 #if defined(HAVE_PARSER)
8343  names.clear();
8344  if(search.empty()) {
8345  for(auto &p : gmsh_yysymbols) names.push_back(p.first);
8346  for(auto &p : gmsh_yystringsymbols) names.push_back(p.first);
8347  }
8348  else{
8349  try{
8350  for(auto &p : gmsh_yysymbols) {
8351  if(std::regex_search(p.first, std::regex(search)))
8352  names.push_back(p.first);
8353  }
8354  for(auto &p : gmsh_yystringsymbols) {
8355  if(std::regex_search(p.first, std::regex(search)))
8356  names.push_back(p.first);
8357  }
8358  }
8359  catch(...) {
8360  }
8361  }
8362 #else
8363  Msg::Error("Parser not available");
8364 #endif
8365 }
8366 
8367 GMSH_API void gmsh::parser::setNumber(const std::string &name,
8368  const std::vector<double> &value)
8369 {
8370  if(!_checkInit()) return;
8371 #if defined(HAVE_PARSER)
8372  gmsh_yysymbol &s(gmsh_yysymbols[name]);
8373  s.list = (value.size() != 1);
8374  s.value = value;
8375 #else
8376  Msg::Error("Parser not available");
8377 #endif
8378 }
8379 
8380 GMSH_API void gmsh::parser::getNumber(const std::string &name,
8381  std::vector<double> &value)
8382 {
8383  if(!_checkInit()) return;
8384 #if defined(HAVE_PARSER)
8385  value = gmsh_yysymbols[name].value;
8386 #else
8387  Msg::Error("Parser not available");
8388 #endif
8389 }
8390 
8391 GMSH_API void gmsh::parser::setString(const std::string &name,
8392  const std::vector<std::string> &value)
8393 {
8394  if(!_checkInit()) return;
8395 #if defined(HAVE_PARSER)
8396  gmsh_yystringsymbols[name] = value;
8397 #else
8398  Msg::Error("Parser not available");
8399 #endif
8400 }
8401 
8402 GMSH_API void gmsh::parser::getString(const std::string &name,
8403  std::vector<std::string> &value)
8404 {
8405  if(!_checkInit()) return;
8406 #if defined(HAVE_PARSER)
8407  value = gmsh_yystringsymbols[name];
8408 #else
8409  Msg::Error("Parser not available");
8410 #endif
8411 }
8412 
8413 GMSH_API void gmsh::parser::clear(const std::string &name)
8414 {
8415  if(!_checkInit()) return;
8416 #if defined(HAVE_PARSER)
8417  if(name.empty()) {
8418  gmsh_yysymbols.clear();
8419  gmsh_yystringsymbols.clear();
8420  }
8421  else {
8422  {
8423  auto it = gmsh_yysymbols.find(name);
8424  if(it != gmsh_yysymbols.end())
8425  gmsh_yysymbols.erase(it);
8426  }
8427  {
8428  auto it = gmsh_yystringsymbols.find(name);
8429  if(it != gmsh_yystringsymbols.end())
8430  gmsh_yystringsymbols.erase(it);
8431  }
8432  }
8433 #else
8434  Msg::Error("Parser not available");
8435 #endif
8436 }
8437 
8438 GMSH_API void gmsh::parser::parse(const std::string &fileName)
8439 {
8440  if(!_checkInit()) return;
8441 #if defined(HAVE_PARSER)
8442  ParseFile(fileName, true, true);
8443 #else
8444  Msg::Error("Parser not available");
8445 #endif
8446 }
8447 
8448 // gmsh::onelab
8449 
8450 GMSH_API void gmsh::onelab::set(const std::string &data,
8451  const std::string &format)
8452 {
8453  if(!_checkInit()) return;
8454 #if defined(HAVE_ONELAB)
8455  if(format == "json") {
8456  if(!::onelab::server::instance()->fromJSON(data))
8457  Msg::Error("Could not parse json data '%s'", data.c_str());
8458  }
8459  else
8460  Msg::Error("Unknown data format");
8461 #else
8462  Msg::Error("ONELAB not available");
8463 #endif
8464 }
8465 
8466 GMSH_API void gmsh::onelab::get(std::string &data, const std::string &name,
8467  const std::string &format)
8468 {
8469  if(!_checkInit()) return;
8470 #if defined(HAVE_ONELAB)
8471  data.clear();
8472  if(name.empty()) {
8473  if(format == "json")
8474  ::onelab::server::instance()->toJSON(data, "Gmsh");
8475  else
8476  Msg::Error("Unknown data format");
8477  }
8478  else {
8479  std::vector< ::onelab::number> ps;
8480  ::onelab::server::instance()->get(ps, name);
8481  if(ps.size()) {
8482  if(format == "json")
8483  data = ps[0].toJSON();
8484  else
8485  data = ps[0].toChar();
8486  }
8487  else {
8488  std::vector< ::onelab::string> ps2;
8489  ::onelab::server::instance()->get(ps2, name);
8490  if(ps2.size()) {
8491  if(format == "json")
8492  data = ps2[0].toJSON();
8493  else
8494  data = ps2[0].toChar();
8495  }
8496  }
8497  }
8498 #else
8499  Msg::Error("ONELAB not available");
8500 #endif
8501 }
8502 
8503 GMSH_API void gmsh::onelab::getNames(std::vector<std::string> &names,
8504  const std::string &search)
8505 {
8506  if(!_checkInit()) return;
8507 #if defined(HAVE_ONELAB)
8509 #else
8510  Msg::Error("ONELAB not available");
8511 #endif
8512 }
8513 
8514 GMSH_API void gmsh::onelab::setNumber(const std::string &name,
8515  const std::vector<double> &value)
8516 {
8517  if(!_checkInit()) return;
8518 #if defined(HAVE_ONELAB)
8519  ::onelab::number p(name);
8520  std::vector< ::onelab::number> ps;
8521  ::onelab::server::instance()->get(ps, name);
8522  if(ps.size()) p = ps[0];
8523  p.setValues(value);
8524  ::onelab::server::instance()->set(p, "Gmsh");
8525 #else
8526  Msg::Error("ONELAB not available");
8527 #endif
8528 }
8529 
8530 GMSH_API void gmsh::onelab::getNumber(const std::string &name,
8531  std::vector<double> &value)
8532 {
8533  if(!_checkInit()) return;
8534 #if defined(HAVE_ONELAB)
8535  value.clear();
8536  std::vector< ::onelab::number> ps;
8537  ::onelab::server::instance()->get(ps, name);
8538  if(ps.size()) value = ps[0].getValues();
8539 #else
8540  Msg::Error("ONELAB not available");
8541 #endif
8542 }
8543 
8544 GMSH_API void gmsh::onelab::setString(const std::string &name,
8545  const std::vector<std::string> &value)
8546 {
8547  if(!_checkInit()) return;
8548 #if defined(HAVE_ONELAB)
8549  ::onelab::string p(name);
8550  std::vector< ::onelab::string> ps;
8551  ::onelab::server::instance()->get(ps, name);
8552  if(ps.size()) p = ps[0];
8553  p.setValues(value);
8554  ::onelab::server::instance()->set(p, "Gmsh");
8555 #else
8556  Msg::Error("ONELAB not available");
8557 #endif
8558 }
8559 
8560 GMSH_API void gmsh::onelab::getString(const std::string &name,
8561  std::vector<std::string> &value)
8562 {
8563  if(!_checkInit()) return;
8564 #if defined(HAVE_ONELAB)
8565  value.clear();
8566  std::vector< ::onelab::string> ps;
8567  ::onelab::server::instance()->get(ps, name);
8568  if(ps.size()) value = ps[0].getValues();
8569 #else
8570  Msg::Error("ONELAB not available");
8571 #endif
8572 }
8573 
8574 GMSH_API int gmsh::onelab::getChanged(const std::string &name)
8575 {
8576  if(!_checkInit()) return 0;
8577 #if defined(HAVE_ONELAB)
8578  return ::onelab::server::instance()->getChanged(name);
8579 #else
8580  Msg::Error("ONELAB not available");
8581  return 0;
8582 #endif
8583 }
8584 
8585 GMSH_API void gmsh::onelab::setChanged(const std::string &name, const int value)
8586 {
8587  if(!_checkInit()) return;
8588 #if defined(HAVE_ONELAB)
8589  ::onelab::server::instance()->setChanged(value, name);
8590 #else
8591  Msg::Error("ONELAB not available");
8592 #endif
8593 }
8594 
8595 GMSH_API void gmsh::onelab::clear(const std::string &name)
8596 {
8597  if(!_checkInit()) return;
8598 #if defined(HAVE_ONELAB)
8600 #else
8601  Msg::Error("ONELAB not available");
8602 #endif
8603 }
8604 
8605 GMSH_API void gmsh::onelab::run(const std::string &name,
8606  const std::string &command)
8607 {
8608  if(!_checkInit()) return;
8609 #if defined(HAVE_ONELAB)
8610  onelabUtils::runClient(name, command);
8611 #endif
8612 }
8613 
8614 // gmsh::logger
8615 
8616 GMSH_API void gmsh::logger::write(const std::string &message,
8617  const std::string &level)
8618 {
8619  if(!_checkInit()) return;
8620  if(level == "error")
8621  Msg::Error("%s", message.c_str());
8622  else if(level == "warning")
8623  Msg::Warning("%s", message.c_str());
8624  else
8625  Msg::Info("%s", message.c_str());
8626 }
8627 
8628 class apiMsg : public GmshMessage {
8629 private:
8630  std::vector<std::string> _log;
8631 
8632 public:
8633  apiMsg() {}
8634  virtual void operator()(std::string level, std::string message)
8635  {
8636 #pragma omp critical
8637  _log.push_back(level + ": " + message);
8638  }
8639  void get(std::vector<std::string> &log) const { log = _log; }
8640 };
8641 
8642 GMSH_API void gmsh::logger::start()
8643 {
8644  if(!_checkInit()) return;
8645  GmshMessage *msg = Msg::GetCallback();
8646  if(msg) { Msg::Warning("Logger already started - ignoring"); }
8647  else {
8648  msg = new apiMsg();
8649  Msg::SetCallback(msg);
8650  }
8651 }
8652 
8653 GMSH_API void gmsh::logger::get(std::vector<std::string> &log)
8654 {
8655  if(!_checkInit()) return;
8656  apiMsg *msg = dynamic_cast<apiMsg *>(Msg::GetCallback());
8657  if(msg) { msg->get(log); }
8658  else {
8659  log.clear();
8660  }
8661 }
8662 
8663 GMSH_API void gmsh::logger::stop()
8664 {
8665  if(!_checkInit()) return;
8666  GmshMessage *msg = Msg::GetCallback();
8667  if(msg) {
8668  delete msg;
8669  Msg::SetCallback(nullptr);
8670  }
8671  else {
8672  Msg::Warning("Logger not started - ignoring");
8673  }
8674 }
8675 
8676 GMSH_API double gmsh::logger::getWallTime()
8677 {
8678  if(!_checkInit()) return -1;
8679  return TimeOfDay();
8680 }
8681 
8682 GMSH_API double gmsh::logger::getCpuTime()
8683 {
8684  if(!_checkInit()) return -1;
8685  return Cpu();
8686 }
8687 
8688 GMSH_API void gmsh::logger::getLastError(std::string &error)
8689 {
8690  if(!_checkInit()) return;
8691  error = Msg::GetLastError();
8692 }
OCC_Internals::setMaxTag
void setMaxTag(int dim, int val)
Definition: GModelIO_OCC.h:484
MElement::minSIGEShapeMeasure
double minSIGEShapeMeasure()
Definition: MElement.h:267
MElement::getNum
virtual std::size_t getNum() const
Definition: MElement.h:68
onelab::server::instance
static server * instance(const std::string &address="")
Definition: onelab.h:1309
GModel::removeDuplicateMeshElements
int removeDuplicateMeshElements(const std::vector< GEntity * > &entities=std::vector< GEntity * >())
Definition: GModel.cpp:2792
onelab::string
Definition: onelab.h:678
PViewDataList::getListPointers
virtual void getListPointers(int N[24], std::vector< double > *V[24])
Definition: PViewDataListIO.cpp:827
PViewOptions::timeStep
int timeStep
Definition: PViewOptions.h:61
PViewDataList::importList
void importList(int index, int n, const std::vector< double > &v, bool finalize)
Definition: PViewDataListIO.cpp:812
GModel::setOrderN
int setOrderN(int order, int linear, int incomplete, int onlyVisible)
Definition: GModel.cpp:1454
GEdge::setMeshMaster
void setMeshMaster(GEdge *master, const std::vector< double > &)
Definition: GEdge.cpp:89
ENT_VOLUME
#define ENT_VOLUME
Definition: GmshDefines.h:234
Msg::GetCallback
static GmshMessage * GetCallback()
Definition: GmshMessage.cpp:244
GEO_Internals::removeAllDuplicates
void removeAllDuplicates()
Definition: GModelIO_GEO.cpp:1077
MElement::xyz2uvw
virtual void xyz2uvw(double xyz[3], double uvw[3]) const
Definition: MElement.cpp:1128
MTriangle.h
OCC_Internals::addVertex
bool addVertex(int &tag, double x, double y, double z, double meshSize=MAX_LC)
Definition: GModelIO_OCC.h:486
GModel::setVisibility
void setVisibility(char val)
Definition: GModel.h:341
GEntity::getMeshElementByType
virtual MElement * getMeshElementByType(const int familyType, const std::size_t index) const
Definition: GEntity.h:365
HierarchicalBasisHcurlTria.h
ghostEdge::getPartition
virtual int getPartition() const
Definition: ghostEdge.h:37
OCC_Internals::symmetry
bool symmetry(const std::vector< std::pair< int, int > > &inDimTags, double a, double b, double c, double d)
Definition: GModelIO_OCC.h:764
FieldOption::numericalValue
virtual void numericalValue(double val)
Definition: Field.h:84
TimeOfDay
double TimeOfDay()
Definition: OS.cpp:399
tags
static std::map< SPoint2, unsigned int > tags
Definition: drawGraph2d.cpp:400
PluginManager::setPluginOption
void setPluginOption(const std::string &pluginName, const std::string &option, double value)
Definition: PluginManager.cpp:152
MVertexPtrLessThan
Definition: MVertex.h:218
GEO_Internals::addBSpline
bool addBSpline(int &tag, const std::vector< int > &pointTags, const std::vector< double > &seqknots=std::vector< double >())
Definition: GModelIO_GEO.cpp:297
OCC_Internals::addCircleArc
bool addCircleArc(int &tag, int startTag, int centerTag, int endTag)
Definition: GModelIO_OCC.h:499
contextGeometryOptions::tolerance
double tolerance
Definition: Context.h:99
GEntity::affineTransform
std::vector< double > affineTransform
Definition: GEntity.h:403
SBoundingBox3d::diag
double diag() const
Definition: SBoundingBox3d.h:93
OCC_Internals::setMeshSize
void setMeshSize(int dim, int tag, double size)
Definition: GModelIO_OCC.h:802
GFace::containsParam
virtual bool containsParam(const SPoint2 &pt)
Definition: GFace.cpp:1403
OCC_Internals::booleanIntersection
bool booleanIntersection(int tag, const std::vector< std::pair< int, int > > &objectDimTags, const std::vector< std::pair< int, int > > &toolDimTags, std::vector< std::pair< int, int > > &outDimTags, std::vector< std::vector< std::pair< int, int > > > &outDimTagsMap, bool removeObject, bool removeTool)
Definition: GModelIO_OCC.h:717
GModel::firstEdge
eiter firstEdge()
Definition: GModel.h:356
CTX::packColor
unsigned int packColor(int R, int G, int B, int A)
Definition: Context.cpp:128
GFace::edges
virtual std::vector< GEdge * > const & edges() const
Definition: GFace.h:121
PView
Definition: PView.h:27
GMSH_API
#define GMSH_API
Definition: GmshGlobal.h:65
drawContextGlobal::getFontAlign
virtual int getFontAlign(const char *alignstr)
Definition: drawContext.h:102
partitionEdge
Definition: partitionEdge.h:12
Field.h
GEntity::GhostCurve
@ GhostCurve
Definition: GEntity.h:125
GFace::firstDer
virtual Pair< SVector3, SVector3 > firstDer(const SPoint2 &param) const =0
PViewDataGModel::ElementData
@ ElementData
Definition: PViewDataGModel.h:195
SplitOptionName
bool SplitOptionName(const std::string &fullName, std::string &category, std::string &name, int &index)
Definition: StringUtils.cpp:156
OCC_Internals::addTorus
bool addTorus(int &tag, double x, double y, double z, double r1, double r2, double angle, const std::vector< double > &N=std::vector< double >())
Definition: GModelIO_OCC.h:642
computeCrossField
int computeCrossField(GModel *gm, std::vector< int > &tags)
Definition: gmshCrossFields.cpp:3895
OCC_Internals::addLine
bool addLine(int &tag, int startTag, int endTag)
Definition: GModelIO_OCC.h:491
GEO_Internals::getMaxTag
int getMaxTag(int dim) const
Definition: GModelIO_GEO.cpp:99
gmsh_sign
int gmsh_sign(T const &value)
Definition: Numeric.h:28
MEdge
Definition: MEdge.h:14
HierarchicalBasisHcurlLine.h
GModel::getFileName
std::string getFileName() const
Definition: GModel.h:333
PViewDataList::NbT3
int NbT3
Definition: PViewDataList.h:48
GmshFLTK
int GmshFLTK(int argc, char **argv)
Definition: GmshGlobal.cpp:388
GEdge::reparamOnFace
virtual SPoint2 reparamOnFace(const GFace *face, double epar, int dir) const
Definition: GEdge.cpp:482
GEntity::getColor
virtual unsigned int getColor()
Definition: GEntity.h:318
GEO_Internals::boundaryLayer
bool boundaryLayer(const std::vector< std::pair< int, int > > &inDimTags, std::vector< std::pair< int, int > > &outDimTags, ExtrudeParams *e=0)
Definition: GModelIO_GEO.cpp:804
OCC_Internals::addVolume
bool addVolume(int &tag, const std::vector< int > &shellTags)
Definition: GModelIO_OCC.h:612
PluginManager::action
int action(const std::string &pluginName, const std::string &action, void *data)
Definition: PluginManager.cpp:119
pyramidalBasis.h
GEntity::correspondingHighOrderVertices
std::map< MVertex *, MVertex * > correspondingHighOrderVertices
Definition: GEntity.h:409
GFace::setBoundEdges
void setBoundEdges(const std::vector< int > &tagEdges)
Definition: GFace.cpp:113
nodalBasis::points
fullMatrix< double > points
Definition: nodalBasis.h:16
GEO_Internals::extrude
bool extrude(const std::vector< std::pair< int, int > > &inDimTags, double dx, double dy, double dz, std::vector< std::pair< int, int > > &outDimTags, ExtrudeParams *e=0)
Definition: GModelIO_GEO.cpp:774
PViewDataList::T2C
std::vector< char > T2C
Definition: PViewDataList.h:50
PViewDataGModel
Definition: PViewDataGModel.h:191
GRegion::method
char method
Definition: GRegion.h:146
meshGRegionDelaunayInsertion.h
ElementType::nameOfParentType
std::string nameOfParentType(int type, bool plural=false)
Definition: ElementType.cpp:882
GPoint::y
double y() const
Definition: GPoint.h:22
GFace::recombine
int recombine
Definition: GFace.h:344
GFace.h
GModel::getMaxElementaryNumber
int getMaxElementaryNumber(int dim)
Definition: GModel.cpp:817
GModel::createOCCInternals
void createOCCInternals()
Definition: GModelIO_OCC.cpp:5874
ghostRegion
Definition: ghostRegion.h:18
ENT_POINT
#define ENT_POINT
Definition: GmshDefines.h:231
distance
double distance(MVertex *v1, MVertex *v2)
Definition: MVertex.h:245
OCC_Internals::revolve
bool revolve(const std::vector< std::pair< int, int > > &inDimTags, double x, double y, double z, double ax, double ay, double az, double angle, std::vector< std::pair< int, int > > &outDimTags, ExtrudeParams *e=0)
Definition: GModelIO_OCC.h:670
OCC_Internals::copy
bool copy(const std::vector< std::pair< int, int > > &inDimTags, std::vector< std::pair< int, int > > &outDimTags)
Definition: GModelIO_OCC.h:774
GVertex::setPosition
virtual void setPosition(GPoint &p)
Definition: GVertex.cpp:32
PViewDataGModel::NodeData
@ NodeData
Definition: PViewDataGModel.h:194
HierarchicalBasisH1Pri
Definition: HierarchicalBasisH1Pri.h:50
_addElements
static void _addElements(int dim, int tag, const std::vector< MElement * > &src, std::vector< T * > &dst)
Definition: gmsh.cpp:1987
FieldOption::string
virtual std::string string() const
Definition: Field.h:98
OCC_Internals::addSurfaceLoop
bool addSurfaceLoop(int &tag, const std::vector< int > &surfaceTags, bool sewing)
Definition: GModelIO_OCC.h:607
ghostFace
Definition: ghostFace.h:17
fullVector< double >
GEdge::setMeshSizeParametric
void setMeshSizeParametric(const std::vector< double > u, const std::vector< double > lc)
Definition: GEdge.cpp:998
GModel::getAttributes
std::map< std::string, std::vector< std::string > > & getAttributes()
Definition: GModel.h:731
TYPE_LIN
#define TYPE_LIN
Definition: GmshDefines.h:65
MTetrahedron
Definition: MTetrahedron.h:34
PViewDataList::T3D
std::vector< double > T3D
Definition: PViewDataList.h:49
isInitialized
static bool isInitialized
Definition: GmshGlobal.cpp:63
GEntity::getMeshVertex
MVertex * getMeshVertex(std::size_t index)
Definition: GEntity.h:379
nodalBasis::df
virtual void df(double u, double v, double w, double grads[][3]) const =0
ghostFace::getGhostCells
virtual std::map< MElement *, int > & getGhostCells()
Definition: ghostFace.h:46
GEO_Internals::rotate
bool rotate(const std::vector< std::pair< int, int > > &dimTags, double x, double y, double z, double ax, double ay, double az, double angle)
Definition: GModelIO_GEO.cpp:848
CTX::unpackBlue
int unpackBlue(unsigned int X)
Definition: Context.cpp:152
GFace
Definition: GFace.h:33
MElement::getTypeForMSH
virtual int getTypeForMSH() const
Definition: MElement.h:488
onelab::server::clear
void clear(const std::string &name="", const std::string &client="")
Definition: onelab.h:1315
GmshFinalize
int GmshFinalize()
Definition: GmshGlobal.cpp:243
GModel::recombineMesh
int recombineMesh()
Definition: GModel.cpp:1421
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
MEdge::getMaxVertex
MVertex * getMaxVertex() const
Definition: MEdge.h:42
GModel::removeDuplicateMeshVertices
int removeDuplicateMeshVertices(double tolerance, const std::vector< GEntity * > &entities=std::vector< GEntity * >())
Definition: GModel.cpp:2684
GEdge::lines
std::vector< MLine * > lines
Definition: GEdge.h:42
F
#define F
Definition: DefaultOptions.h:23
GEO_Internals::setMaxTag
void setMaxTag(int dim, int val)
Definition: GModelIO_GEO.cpp:87
angle
double angle(const SVector3 &a, const SVector3 &b)
Definition: SVector3.h:157
_getEntities
static void _getEntities(const gmsh::vectorpair &dimTags, std::vector< GEntity * > &entities)
Definition: gmsh.cpp:1426
SPoint2
Definition: SPoint2.h:12
PViewData::getNumTimeSteps
virtual int getNumTimeSteps()=0
discreteRegion.h
quadsToTriangles
void quadsToTriangles(GFace *gf, double minqual)
Definition: meshGFaceOptimize.cpp:1374
stepData::getTime
double getTime()
Definition: PViewDataGModel.h:103
gmshCrossFields.h
GEO_Internals::setTransfiniteLine
void setTransfiniteLine(int tag, int nPoints, int type, double coef)
Definition: GModelIO_GEO.cpp:1136
MElementFactory
Definition: MElement.h:517
OS.h
ghostFace.h
MElement::getFaceVertices
virtual void getFaceVertices(const int num, std::vector< MVertex * > &v) const
Definition: MElement.h:225
GEO_Internals::setMeshSizeFromBoundary
void setMeshSizeFromBoundary(int dim, int tag, int val)
Definition: GModelIO_GEO.cpp:1353
_initialized
static int _initialized
Definition: gmsh.cpp:109
GModel::getMaxElementNumber
std::size_t getMaxElementNumber() const
Definition: GModel.h:223
GEO_Internals::modifyPhysicalGroup
bool modifyPhysicalGroup(int dim, int tag, int op, const std::vector< int > &tags)
Definition: GModelIO_GEO.cpp:1000
GRegion::addEmbeddedVertex
void addEmbeddedVertex(GVertex *v)
Definition: GRegion.h:57
FieldOption::listdouble
virtual const std::list< double > & listdouble() const
Definition: Field.h:91
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
GEO_Internals::setTransfiniteSurface
void setTransfiniteSurface(int tag, int arrangement, const std::vector< int > &cornerTags)
Definition: GModelIO_GEO.cpp:1163
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
GFace::algorithm
int algorithm
Definition: GFace.h:363
MESH_TRANSFINITE
#define MESH_TRANSFINITE
Definition: GmshDefines.h:259
meshGRegionHxt.h
PViewDataList
Definition: PViewDataList.h:17
discreteEdge
Definition: discreteEdge.h:12
ExtrudeParams::BoundaryLayerIndex
int BoundaryLayerIndex
Definition: ExtrudeParams.h:46
MVertex
Definition: MVertex.h:24
MElement::getDim
virtual int getDim() const =0
OCC_Internals::getMass
bool getMass(int dim, int tag, double &mass)
Definition: GModelIO_OCC.h:836
GEO_Internals::addCompoundBSpline
bool addCompoundBSpline(int &tag, const std::vector< int > &curveTags, int numPoints)
Definition: GModelIO_GEO.cpp:394
CTX::numThreads
int numThreads
Definition: Context.h:169
GModel::lcCallback
std::function< double(int, int, double, double, double, double)> lcCallback
Definition: GModel.h:713
GEntity::getParentEntity
virtual GEntity * getParentEntity()
Definition: GEntity.h:199
GModel::remove
bool remove(GRegion *r)
Definition: GModel.cpp:435
GModel::getName
std::string getName() const
Definition: GModel.h:329
GEO_Internals::setRecombine
void setRecombine(int dim, int tag, double angle)
Definition: GModelIO_GEO.cpp:1252
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
MVertex::z
double z() const
Definition: MVertex.h:62
GFace::transfiniteArrangement
int transfiniteArrangement
Definition: GFace.h:353
GFace::method
char method
Definition: GFace.h:348
GEdge::reverseMesh
bool reverseMesh
Definition: GEdge.h:259
reparamMeshVertexOnFace
bool reparamMeshVertexOnFace(MVertex const *v, const GFace *gf, SPoint2 &param, bool onSurface, bool failOnSeam, int dir)
Definition: MVertex.cpp:522
HierarchicalBasisH1Quad
Definition: HierarchicalBasisH1Quad.h:35
ghostRegion::getGhostCells
virtual std::map< MElement *, int > & getGhostCells()
Definition: ghostRegion.h:50
box
Definition: gl2gif.cpp:311
gmshSurface::getSurface
static gmshSurface * getSurface(int tag)
Definition: gmshSurface.cpp:51
OCC_Internals::addSphere
bool addSphere(int &tag, double xc, double yc, double zc, double radius, double angle1, double angle2, double angle3)
Definition: GModelIO_OCC.h:616
stepData::getData
Real * getData(int index, bool allocIfNeeded=false, int mult=1)
Definition: PViewDataGModel.h:119
SPoint3
Definition: SPoint3.h:14
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
GmshInitialize
int GmshInitialize(int argc, char **argv, bool readConfigFiles, bool exitOnCommandLineError)
Definition: GmshGlobal.cpp:65
CTX::pickElements
int pickElements
Definition: Context.h:294
HierarchicalBasisHcurlBrick.h
gmshParametricSurface::NewParametricSurface
static gmshSurface * NewParametricSurface(int iSurf, const char *, const char *, const char *)
Definition: gmshSurface.cpp:100
PViewData::searchVectorClosest
bool searchVectorClosest(double x, double y, double z, double &distance, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: PViewData.cpp:378
MVertex::getNum
std::size_t getNum() const
Definition: MVertex.h:86
GModel::getFaceByTag
GFace * getFaceByTag(int n) const
Definition: GModel.cpp:326
OCC_Internals::booleanDifference
bool booleanDifference(int tag, const std::vector< std::pair< int, int > > &objectDimTags, const std::vector< std::pair< int, int > > &toolDimTags, std::vector< std::pair< int, int > > &outDimTags, std::vector< std::vector< std::pair< int, int > > > &outDimTagsMap, bool removeObject, bool removeTool)
Definition: GModelIO_OCC.h:726
OCC_Internals::addSpline
bool addSpline(int &tag, const std::vector< int > &pointTags, const std::vector< SVector3 > &tangents=std::vector< SVector3 >())
Definition: GModelIO_OCC.h:522
TYPE_PNT
#define TYPE_PNT
Definition: GmshDefines.h:64
GFace::meshAttributes
struct GFace::@18 meshAttributes
SBoundingBox3d::min
SPoint3 min() const
Definition: SBoundingBox3d.h:90
Range::high
T high() const
Definition: Range.h:20
GFace::point
virtual GPoint point(double par1, double par2) const =0
OCC_Internals::addCurveLoop
bool addCurveLoop(int &tag, const std::vector< int > &curveTags)
Definition: GModelIO_OCC.h:543
fullVector::size
int size() const
Definition: fullMatrix.h:69
SVector3
Definition: SVector3.h:16
FieldOption::list
virtual const std::list< int > & list() const
Definition: Field.h:86
element::getEdge
virtual void getEdge(int num, int &start, int &end)=0
GModel::getMeshVertexByTag
MVertex * getMeshVertexByTag(int n)
Definition: GModel.cpp:1953
PView::getIndex
int getIndex()
Definition: PView.h:92
TYPE_TRI
#define TYPE_TRI
Definition: GmshDefines.h:66
meshGFaceOptimize.h
GFace::addEmbeddedEdge
void addEmbeddedEdge(GEdge *e)
Definition: GFace.h:108
PView.h
GModelIO_OCC.h
GEO_Internals::addSurfaceFilling
bool addSurfaceFilling(int &tag, const std::vector< int > &wireTags, int sphereCenterTag=-1)
Definition: GModelIO_GEO.cpp:630
Msg::GetGmshClient
static GmshClient * GetGmshClient()
Definition: GmshMessage.cpp:1272
GModelIO_GEO.h
partitionFace
Definition: partitionFace.h:12
contextMeshOptions::meshOnlyVisible
int meshOnlyVisible
Definition: Context.h:36
MTriangle::getVertex
virtual MVertex * getVertex(int num)
Definition: MTriangle.h:62
OCC_Internals::dilate
bool dilate(const std::vector< std::pair< int, int > > &inDimTags, double x, double y, double z, double a, double b, double c)
Definition: GModelIO_OCC.h:759
GEntity::edges
virtual std::vector< GEdge * > const & edges() const
Definition: GEntity.h:211
MVertex::onWhat
GEntity * onWhat() const
Definition: MVertex.h:82
MPoint.h
FIELD_OPTION_PATH
@ FIELD_OPTION_PATH
Definition: Field.h:33
MPrism
Definition: MPrism.h:34
partitionRegion::getPartitions
virtual const std::vector< int > & getPartitions() const
Definition: partitionRegion.h:39
OCC_Internals::addBezierFilling
bool addBezierFilling(int &tag, int wireTag, const std::string &type="")
Definition: GModelIO_OCC.h:579
GModel::getMaxVertexNumber
std::size_t getMaxVertexNumber() const
Definition: GModel.h:222
MVertex::point
SPoint3 point() const
Definition: MVertex.h:67
MElement::getEdgeVertices
virtual void getEdgeVertices(const int num, std::vector< MVertex * > &v) const
Definition: MElement.h:221
GModel::destroyMeshCaches
void destroyMeshCaches()
Definition: GModel.cpp:214
gmshSurface.h
GModel::getEdgeByTag
GEdge * getEdgeByTag(int n) const
Definition: GModel.cpp:336
FieldOption::getType
virtual FieldOptionType getType()=0
GmshBatch
int GmshBatch()
Definition: GmshGlobal.cpp:278
MLine.h
edges
static int edges[6][2]
Definition: meshGRegionLocalMeshMod.cpp:23
MAX_LC
#define MAX_LC
Definition: GEntity.h:19
Pair::left
L left() const
Definition: Pair.h:18
partitionFace::getPartitions
virtual const std::vector< int > & getPartitions() const
Definition: partitionFace.h:39
GEntity::containsPoint
virtual bool containsPoint(const SPoint3 &pt) const
Definition: GEntity.h:265
GEO_Internals::addEllipseArc
bool addEllipseArc(int &tag, int startTag, int centerTag, int majorTag, int endTag, double nx=0., double ny=0., double nz=0.)
Definition: GModelIO_GEO.cpp:209
GEO_Internals::addLine
bool addLine(int &tag, int startTag, int endTag)
Definition: GModelIO_GEO.cpp:141
PViewData.h
PViewData::haveInterpolationMatrices
bool haveInterpolationMatrices(int type=0)
Definition: PViewData.cpp:186
GModel::removePhysicalGroups
void removePhysicalGroups()
Definition: GModel.cpp:893
GEntity
Definition: GEntity.h:31
apiMsg::_log
std::vector< std::string > _log
Definition: gmsh.cpp:8630
GPoint
Definition: GPoint.h:13
GRegion::corners
std::vector< GVertex * > corners
Definition: GRegion.h:150
GEntity::getNumMeshVertices
std::size_t getNumMeshVertices()
Definition: GEntity.h:376
ghostRegion::getPartition
virtual int getPartition() const
Definition: ghostRegion.h:45
TYPE_PRI
#define TYPE_PRI
Definition: GmshDefines.h:70
GFace::closestPoint
virtual GPoint closestPoint(const SPoint3 &queryPoint, const double initialGuess[2]) const
Definition: GFace.cpp:1323
OCC_Internals::addWedge
bool addWedge(int &tag, double x, double y, double z, double dx, double dy, double dz, double ltx, const std::vector< double > &N=std::vector< double >())
Definition: GModelIO_OCC.h:636
GEntity::getMeshMaster
GEntity * getMeshMaster() const
Definition: GEntity.h:291
GEntity::PartitionVolume
@ PartitionVolume
Definition: GEntity.h:124
PViewData::setFileName
virtual void setFileName(const std::string &val)
Definition: PViewData.h:75
OCC_Internals::addPipe
bool addPipe(const std::vector< std::pair< int, int > > &inDimTags, int wireTag, std::vector< std::pair< int, int > > &outDimTags, const std::string &trihedron="")
Definition: GModelIO_OCC.h:677
GModel::getNumPartitions
std::size_t getNumPartitions() const
Definition: GModel.h:602
MElement::getNumVertices
virtual std::size_t getNumVertices() const =0
reparamMeshVertexOnEdge
bool reparamMeshVertexOnEdge(MVertex *v, const GEdge *ge, double &param)
Definition: MVertex.cpp:592
OCC_Internals::addBSplineSurface
bool addBSplineSurface(int &tag, const std::vector< int > &pointTags, const int numPointsU, const int degreeU, const int degreeV, const std::vector< double > &weights, const std::vector< double > &knotsU, const std::vector< double > &knotsV, const std::vector< int > &multiplicitiesU, const std::vector< int > &multiplicitiesV, const std::vector< int > &wireTags=std::vector< int >(), bool wire3D=true)
Definition: GModelIO_OCC.h:583
GEntity::GhostSurface
@ GhostSurface
Definition: GEntity.h:126
drawContext::global
static drawContextGlobal * global()
Definition: drawContext.cpp:85
GModel::getLastMeshEntityError
std::vector< GEntity * > getLastMeshEntityError()
Definition: GModel.h:586
getBoundingBox
void getBoundingBox(int dim, List_T *in, List_T *out)
Definition: Gmsh.tab.cpp:15533
apiMsg
Definition: gmsh.cpp:8628
PView::setData
void setData(PViewData *val)
Definition: PView.h:86
GModel::rebuildMeshVertexCache
void rebuildMeshVertexCache(bool onlyIfNecessary=false)
Definition: GModel.cpp:1879
HierarchicalBasisHcurlTetra
Definition: HierarchicalBasisHcurlTetra.h:53
GEO_Internals::addVolume
bool addVolume(int &tag, const std::vector< int > &shellTags)
Definition: GModelIO_GEO.cpp:701
PViewData::searchScalarClosest
bool searchScalarClosest(double x, double y, double z, double &distance, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: PViewData.cpp:338
PViewDataGModel::GaussPointData
@ GaussPointData
Definition: PViewDataGModel.h:197
GModel::createGeometryOfDiscreteEntities
void createGeometryOfDiscreteEntities(const std::vector< std::pair< int, int > > &dimTags=std::vector< std::pair< int, int > >())
Definition: GModel.cpp:2370
HierarchicalBasisH1Brick.h
discreteRegion
Definition: discreteRegion.h:13
OCC_Internals::convertToNURBS
bool convertToNURBS(const std::vector< std::pair< int, int > > &dimTags)
Definition: GModelIO_OCC.h:798
OCC_Internals::addRectangle
bool addRectangle(int &tag, double x, double y, double z, double dx, double dy, double roundedRadius=0.)
Definition: GModelIO_OCC.h:547
GEntity::PartitionCurve
@ PartitionCurve
Definition: GEntity.h:122
discreteVertex.h
PView::setChanged
void setChanged(bool val)
Definition: PView.cpp:241
PViewDataList::getString2D
void getString2D(int i, int step, std::string &str, double &x, double &y, double &style)
Definition: PViewDataList.cpp:569
ENT_SURFACE
#define ENT_SURFACE
Definition: GmshDefines.h:233
GModel::makeDiscreteRegionsSimplyConnected
void makeDiscreteRegionsSimplyConnected()
Definition: GModel.cpp:3101
PluginManager::instance
static PluginManager * instance()
Definition: PluginManager.cpp:169
GEntity::setColor
virtual void setColor(unsigned color, bool recursive=false)
Definition: GEntity.h:319
MLine
Definition: MLine.h:21
onelab::number
Definition: onelab.h:432
PViewData::initAdaptiveData
void initAdaptiveData(int step, int level, double tol)
Definition: PViewData.cpp:37
drawContextGlobal::draw
virtual void draw(bool rateLimited=true)
Definition: drawContext.h:97
GVertex::points
std::vector< MPoint * > points
Definition: GVertex.h:120
GModel::findByName
static GModel * findByName(const std::string &name, const std::string &fileName="")
Definition: GModel.cpp:158
HierarchicalBasisHcurlQuad
Definition: HierarchicalBasisHcurlQuad.h:36
GPoint::z
double z() const
Definition: GPoint.h:23
onelab::server::get
bool get(std::vector< T > &ps, const std::string &name="", const std::string &client="")
Definition: onelab.h:1324
GEntity::setVisibility
virtual void setVisibility(char val, bool recursive=false)
Definition: GEntity.h:308
OCC_Internals::addBSplineFilling
bool addBSplineFilling(int &tag, int wireTag, const std::string &type="")
Definition: GModelIO_OCC.h:575
GFace::meshSizeFromBoundary
int meshSizeFromBoundary
Definition: GFace.h:365
GmshSetOption
int GmshSetOption(const std::string &category, const std::string &name, std::string value, int index)
Definition: GmshGlobal.cpp:119
HierarchicalBasisH1Tria
Definition: HierarchicalBasisH1Tria.h:36
OCC_Internals::booleanFragments
bool booleanFragments(int tag, const std::vector< std::pair< int, int > > &objectDimTags, const std::vector< std::pair< int, int > > &toolDimTags, std::vector< std::pair< int, int > > &outDimTags, std::vector< std::vector< std::pair< int, int > > > &outDimTagsMap, bool removeObject, bool removeTool)
Definition: GModelIO_OCC.h:735
GModel::getEntitiesInBox
void getEntitiesInBox(std::vector< GEntity * > &entities, const SBoundingBox3d &box, int dim=-1) const
Definition: GModel.cpp:672
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
PViewDataList::getNumStrings3D
int getNumStrings3D()
Definition: PViewDataList.h:119
MElement::getVertex
virtual const MVertex * getVertex(int num) const =0
GRegion::faces
virtual std::vector< GFace * > faces() const
Definition: GRegion.h:64
SPoint3::x
double x(void) const
Definition: SPoint3.h:125
GRegion::hexahedra
std::vector< MHexahedron * > hexahedra
Definition: GRegion.h:164
fullMatrix< double >
_eulerCharacteristic
int _eulerCharacteristic(GRegion *gr)
Definition: gmsh.cpp:4788
MElement::getEdge
virtual MEdge getEdge(int num) const =0
GModel::getPhysicalGroups
void getPhysicalGroups(std::map< int, std::vector< GEntity * > > groups[4]) const
Definition: GModel.cpp:837
GModel::lastFace
fiter lastFace()
Definition: GModel.h:359
GModel::addMFace
std::size_t addMFace(MFace &face, std::size_t num=0)
Definition: GModel.cpp:1583
HierarchicalBasisH1Point.h
GEdge.h
_getAdditionalNodesOnBoundary
static void _getAdditionalNodesOnBoundary(GEntity *entity, std::vector< std::size_t > &nodeTags, std::vector< double > &coord, std::vector< double > &parametricCoord, bool parametric)
Definition: gmsh.cpp:1477
MFace
Definition: MFace.h:20
HierarchicalBasisH1Pri.h
PViewDataList::getNumTimeSteps
int getNumTimeSteps()
Definition: PViewDataList.h:79
discreteVertex
Definition: discreteVertex.h:15
GModel::getPhysicalName
std::string getPhysicalName(int dim, int num) const
Definition: GModel.cpp:961
PViewData::setInterpolationMatrices
void setInterpolationMatrices(int type, const fullMatrix< double > &coefVal, const fullMatrix< double > &expVal)
Definition: PViewData.cpp:154
GEdge::firstDer
virtual SVector3 firstDer(double par) const =0
GRegion.h
MVertex::setParameter
virtual bool setParameter(int i, double par)
Definition: MVertex.h:102
GModel::bounds
SBoundingBox3d bounds(bool aroundVisible=false)
Definition: GModel.cpp:1043
FieldManager::deleteField
void deleteField(int id)
Definition: Field.cpp:118
MVertex::setIndex
void setIndex(long int index)
Definition: MVertex.h:94
MElement::fastBarycenter
virtual SPoint3 fastBarycenter(bool primary=false) const
Definition: MElement.cpp:536
Range
Definition: Range.h:10
ExtrudeParams::mesh
struct ExtrudeParams::@14 mesh
nodalBasis::order
int order
Definition: nodalBasis.h:14
GModel::renumberMeshVertices
void renumberMeshVertices()
Definition: GModel.cpp:1623
MEdge::getVertex
MVertex * getVertex(std::size_t i) const
Definition: MEdge.h:39
GEntity::vertices
virtual std::vector< GVertex * > vertices() const
Definition: GEntity.h:218
BasisFactory::getNodalBasis
static const nodalBasis * getNodalBasis(int tag)
Definition: BasisFactory.cpp:23
GEO_Internals::addSpline
bool addSpline(int &tag, const std::vector< int > &pointTags)
Definition: GModelIO_GEO.cpp:245
PView::getViewByTag
static PView * getViewByTag(int tag, int timeStep=-1, int partition=-1)
Definition: PView.cpp:376
delaunayMeshIn3D
void delaunayMeshIn3D(std::vector< MVertex * > &v, std::vector< MTetrahedron * > &result, bool removeBox)
Definition: meshGRegionDelaunayInsertion.cpp:1559
nodalBasis::f
virtual void f(double u, double v, double w, double *sf) const =0
PView::getTag
int getTag()
Definition: PView.h:89
contextMeshOptions::algoSubdivide
int algoSubdivide
Definition: Context.h:29
GModel::setFileName
void setFileName(const std::string &fileName)
Definition: GModel.cpp:123
GModel::changeEntityTag
bool changeEntityTag(int dim, int tag, int newTag)
Definition: GModel.cpp:367
GEntity::mesh_vertices
std::vector< MVertex * > mesh_vertices
Definition: GEntity.h:56
GFace::secondDer
virtual void secondDer(const SPoint2 &param, SVector3 &dudu, SVector3 &dvdv, SVector3 &dudv) const =0
OCC_Internals::addDisk
bool addDisk(int &tag, double xc, double yc, double zc, double rx, double ry, const std::vector< double > &N=std::vector< double >(), const std::vector< double > &V=std::vector< double >())
Definition: GModelIO_OCC.h:552
gmshSurface
Definition: gmshSurface.h:22
FIELD_OPTION_BOOL
@ FIELD_OPTION_BOOL
Definition: Field.h:34
delaunayMeshIn3DHxt
void delaunayMeshIn3DHxt(std::vector< MVertex * > &v, std::vector< MTetrahedron * > &tets)
Definition: meshGRegionHxt.cpp:680
HierarchicalBasisH1Point
Definition: HierarchicalBasisH1Point.h:21
FieldManager::setBackgroundFieldId
void setBackgroundFieldId(int id)
Definition: Field.h:165
ElementType::getPrimaryType
int getPrimaryType(int type)
Definition: ElementType.cpp:877
apiMsg::apiMsg
apiMsg()
Definition: gmsh.cpp:8633
stepData::getMult
int getMult(int index)
Definition: PViewDataGModel.h:94
MHexahedron.h
FieldManager::newId
int newId()
Definition: Field.cpp:98
GModel::setElementaryName
void setElementaryName(int dim, int tag, const std::string &name)
Definition: GModel.h:500
OCC_Internals::addEllipseArc
bool addEllipseArc(int &tag, int startTag, int centerTag, int majorTag, int endTag)
Definition: GModelIO_OCC.h:510
MEdgeVertex
Definition: MVertex.h:137
gmsh_yysymbols
std::map< std::string, gmsh_yysymbol > gmsh_yysymbols
Definition: Gmsh.tab.cpp:643
OCC_Internals::extrude
bool extrude(const std::vector< std::pair< int, int > > &inDimTags, double dx, double dy, double dz, std::vector< std::pair< int, int > > &outDimTags, ExtrudeParams *e=0)
Definition: GModelIO_OCC.h:663
drawContextGlobal::getFontIndex
virtual int getFontIndex(const char *fontname)
Definition: drawContext.h:99
gmsh_yysymbol
Definition: Parser.h:18
GFace::recombineAngle
double recombineAngle
Definition: GFace.h:346
MElement::getNumFaces
virtual int getNumFaces()=0
GModel::firstMFace
hashmapMFace::const_iterator firstMFace()
Definition: GModel.h:287
GEntity::getNumMeshElements
virtual std::size_t getNumMeshElements() const
Definition: GEntity.h:348
GVertex
Definition: GVertex.h:23
GVertex::prescribedMeshSizeAtVertex
virtual double prescribedMeshSizeAtVertex() const
Definition: GVertex.h:75
GEntity::getTypeString
virtual std::string getTypeString()
Definition: GEntity.h:133
rotate
void rotate(const Quaternion &omega, XYZ axe)
Definition: Camera.cpp:398
gmshSurface::maxTag
static int maxTag()
Definition: gmshSurface.h:38
OCC_Internals::addBezierSurface
bool addBezierSurface(int &tag, const std::vector< int > &pointTags, const int numPointsU, const std::vector< int > &wireTags=std::vector< int >(), bool wire3D=true)
Definition: GModelIO_OCC.h:595
intersect
static int intersect(PolyMesh::Vertex *v0, PolyMesh::Vertex *v1, PolyMesh::Vertex *b0, PolyMesh::Vertex *b1)
Definition: meshTriangulation.cpp:416
tolerance
#define tolerance
Definition: curvature.cpp:11
PluginManager.h
SBoundingBox3d::empty
bool empty()
Definition: SBoundingBox3d.h:36
OCC_Internals::getEntitiesInBoundingBox
bool getEntitiesInBoundingBox(double xmin, double ymin, double zmin, double xmax, double ymax, double zmax, std::vector< std::pair< int, int > > &dimTags, int dim)
Definition: GModelIO_OCC.h:819
MVertex.h
ElementType::getType
int getType(int parentType, int order, bool serendip=false)
Definition: ElementType.cpp:757
GModel::refineMesh
int refineMesh(int linear, bool splitIntoQuads=false, bool splitIntoHexas=false, bool barycentric=false)
Definition: GModel.cpp:1401
PView::combine
static void combine(bool time, int how, bool remove, bool copyOptions)
Definition: PView.cpp:249
PViewDataList::T3C
std::vector< char > T3C
Definition: PViewDataList.h:50
setVisibility
void setVisibility(int dim, int visible, bool recursive)
Definition: Gmsh.tab.cpp:15557
MTetrahedron::getVertex
virtual MVertex * getVertex(int num)
Definition: MTetrahedron.h:67
OCC_Internals::getMaxTag
int getMaxTag(int dim) const
Definition: GModelIO_OCC.h:485
GFace::embeddedVertices
std::set< GVertex *, GEntityPtrLessThan > & embeddedVertices()
Definition: GFace.h:160
partitionRegion.h
MElement::getVolume
virtual double getVolume()
Definition: MElement.cpp:567
GModel::getDim
int getDim() const
Definition: GModel.cpp:989
norm
void norm(const double *vec, double *norm)
Definition: gmshLevelset.cpp:202
OCC_Internals::addSurfaceFilling
bool addSurfaceFilling(int &tag, int wireTag, const std::vector< int > &pointTags=std::vector< int >(), const std::vector< int > &surfaceTags=std::vector< int >(), const std::vector< int > &surfaceContinuity=std::vector< int >(), const int degree=2, const int numPointsOnCurves=15, const int numIter=2, const bool anisotropic=false, const double tol2d=0.00001, const double tol3d=0.0001, const double tolAng=0.01, const double tolCurv=0.1, const int maxDegree=8, const int maxSegments=9)
Definition: GModelIO_OCC.h:562
Numeric.h
FieldManager::get
Field * get(int id)
Definition: Field.cpp:74
ReplaceSubString
std::string ReplaceSubString(const std::string &olds, const std::string &news, const std::string &str)
Definition: StringUtils.cpp:140
MElement::getFace
virtual MFace getFace(int num) const =0
HierarchicalBasisHcurlPri
Definition: HierarchicalBasisHcurlPri.h:55
GModel
Definition: GModel.h:44
HierarchicalBasis
Definition: HierarchicalBasis.h:18
HierarchicalBasisH1Tetra.h
GModel::rebuildMeshElementCache
void rebuildMeshElementCache(bool onlyIfNecessary=false)
Definition: GModel.cpp:1914
GEO_Internals::symmetry
bool symmetry(const std::vector< std::pair< int, int > > &dimTags, double a, double b, double c, double d)
Definition: GModelIO_GEO.cpp:862
HierarchicalBasisH1Line.h
HierarchicalBasisHcurlQuad.h
Cpu
double Cpu()
Definition: OS.cpp:366
GModel::classifySurfaces
void classifySurfaces(double angleThreshold, bool includeBoundary, bool forReparametrization, double curveAngleThreshold)
Definition: GModel.cpp:3472
PView::getData
PViewData * getData(bool useAdaptiveIfAvailable=false)
Definition: PView.cpp:233
MElement::getNumShapeFunctions
virtual std::size_t getNumShapeFunctions() const
Definition: MElement.h:387
onelab.h
CTX::unpackGreen
int unpackGreen(unsigned int X)
Definition: Context.cpp:144
Msg::GetMaxThreads
static int GetMaxThreads()
Definition: GmshMessage.cpp:1637
gmshSphere::NewSphere
static gmshSurface * NewSphere(int _iSphere, double _x, double _y, double _z, double _r)
Definition: gmshSurface.cpp:38
_createOcc
static void _createOcc()
Definition: gmsh.cpp:6300
Msg::SetCallback
static void SetCallback(GmshMessage *callback)
Definition: GmshMessage.cpp:239
PViewOptions.h
GEdge::getBeginVertex
virtual GVertex * getBeginVertex() const
Definition: GEdge.h:63
PViewDataList.h
ExtrudeParams::NbLayer
int NbLayer
Definition: ExtrudeParams.h:39
GModel::addHomologyRequest
void addHomologyRequest(const std::string &type, const std::vector< int > &domain, const std::vector< int > &subdomain, const std::vector< int > &dim)
Definition: GModel.cpp:3480
GModel::getMeshVerticesForPhysicalGroup
void getMeshVerticesForPhysicalGroup(int dim, int num, std::vector< MVertex * > &)
Definition: GModel.cpp:1987
partitionRegion
Definition: partitionRegion.h:12
ExtrudeParams.h
GModel::createTopologyFromMesh
void createTopologyFromMesh()
Definition: GModelCreateTopologyFromMesh.cpp:663
GEO_Internals::splitCurve
bool splitCurve(int tag, const std::vector< int > &pointTags, std::vector< int > &curveTags)
Definition: GModelIO_GEO.cpp:868
MVertex::setXYZ
void setXYZ(double x, double y, double z)
Definition: MVertex.h:68
GModel::clearHomologyRequests
void clearHomologyRequests()
Definition: GModel.cpp:3491
_getEntityName
static std::string _getEntityName(int dim, int tag)
Definition: gmsh.cpp:398
MFace::getVertex
MVertex * getVertex(std::size_t i) const
Definition: MFace.h:30
meshGFaceDelaunayInsertion.h
ghostFace::getPartition
virtual int getPartition() const
Definition: ghostFace.h:41
OCC_Internals::translate
bool translate(const std::vector< std::pair< int, int > > &inDimTags, double dx, double dy, double dz)
Definition: GModelIO_OCC.h:749
GFace::parFromPoint
virtual SPoint2 parFromPoint(const SPoint3 &, bool onSurface=true, bool convTestXYZ=false) const
Definition: GFace.cpp:1254
onelab::server::getParameterNames
void getParameterNames(std::vector< std::string > &names, const std::string &search="") const
Definition: onelab.h:1358
setColor
void setColor(const std::vector< std::pair< int, int >> &dimTags, unsigned int val, bool recursive)
Definition: Gmsh.tab.cpp:15587
nodalBasis::getNumBubbleShapeFunctions
int getNumBubbleShapeFunctions() const
Definition: nodalBasis.cpp:863
GmshClearProject
int GmshClearProject()
Definition: GmshGlobal.cpp:219
MElement::reverse
virtual void reverse()
Definition: MElement.h:308
GEO_Internals::setMeshAlgorithm
void setMeshAlgorithm(int dim, int tag, int val)
Definition: GModelIO_GEO.cpp:1344
MPyramid.h
FieldManager
Definition: Field.h:145
FIELD_OPTION_DOUBLE
@ FIELD_OPTION_DOUBLE
Definition: Field.h:30
GEntity::geomType
virtual GeomType geomType() const
Definition: GEntity.h:238
GModel::firstFace
fiter firstFace()
Definition: GModel.h:355
GmshMergeFile
int GmshMergeFile(const std::string &fileName)
Definition: GmshGlobal.cpp:225
GmshDefines.h
MElement::etaShapeMeasure
virtual double etaShapeMeasure()
Definition: MElement.h:260
_checkInit
static bool _checkInit()
Definition: gmsh.cpp:113
MEdge::getMinVertex
MVertex * getMinVertex() const
Definition: MEdge.h:41
PViewDataGModel::BeamData
@ BeamData
Definition: PViewDataGModel.h:198
GEdge::meshAttributes
struct GEdge::@16 meshAttributes
SPoint3::y
double y(void) const
Definition: SPoint3.h:127
GEO_Internals::getMaxPhysicalTag
int getMaxPhysicalTag() const
Definition: GModelIO_GEO.h:132
PViewData::deleteInterpolationMatrices
void deleteInterpolationMatrices(int type=0)
Definition: PViewData.cpp:194
ExtrudeParams::Recombine
bool Recombine
Definition: ExtrudeParams.h:37
_getFunctionSpaceInfo
static bool _getFunctionSpaceInfo(const std::string &fsType, std::string &fsName, int &fsOrder, int &fsComp)
Definition: gmsh.cpp:2318
PViewDataList::getString3D
void getString3D(int i, int step, std::string &str, double &x, double &y, double &z, double &style)
Definition: PViewDataList.cpp:576
_addModelData
static void _addModelData(const int tag, const int step, const std::string &modelName, const std::string &dataType, const std::vector< std::size_t > &tags, const T &data, const double time, const int numComponents, const int partition)
Definition: gmsh.cpp:7129
MHexahedron
Definition: MHexahedron.h:28
FIELD_OPTION_LIST
@ FIELD_OPTION_LIST
Definition: Field.h:35
OCC_Internals::getSurfaceLoops
bool getSurfaceLoops(int volumeTag, std::vector< int > &surfaceLoopTags, std::vector< std::vector< int > > &surfaceTags)
Definition: GModelIO_OCC.h:831
OCC_Internals::addThickSolid
bool addThickSolid(int tag, int solidTag, const std::vector< int > &excludeFaceTags, double offset, std::vector< std::pair< int, int > > &outDimTags)
Definition: GModelIO_OCC.h:657
picojson::parse
std::string parse(value &out, Iter &pos, const Iter &last)
Definition: picojson.h:1058
drawContext
Definition: drawContext.h:120
GmshMessage
Definition: GmshMessage.h:23
onelabUtils.h
OCC_Internals::fillet
bool fillet(const std::vector< int > &volumeTags, const std::vector< int > &curveTags, const std::vector< double > &radii, std::vector< std::pair< int, int > > &outDimTags, bool removeVolume)
Definition: GModelIO_OCC.h:683
PViewDataList::finalize
bool finalize(bool computeMinMax=true, const std::string &interpolationScheme="")
Definition: PViewDataList.cpp:81
PViewData::setName
virtual void setName(const std::string &val)
Definition: PViewData.h:71
GModel::add
bool add(GRegion *r)
Definition: GModel.h:394
HierarchicalBasisHcurlBrick
Definition: HierarchicalBasisHcurlBrick.h:46
CTX::mesh
contextMeshOptions mesh
Definition: Context.h:313
Parser.h
GModel::getElementaryName
std::string getElementaryName(int dim, int tag)
Definition: GModel.cpp:1007
OCC_Internals::removeAllDuplicates
void removeAllDuplicates()
Definition: GModelIO_OCC.h:744
OCC_Internals::addEllipse
bool addEllipse(int &tag, double x, double y, double z, double r1, double r2, double angle1, double angle2, const std::vector< double > &N=std::vector< double >(), const std::vector< double > &V=std::vector< double >())
Definition: GModelIO_OCC.h:515
contextGeometryOptions::scalingFactor
double scalingFactor
Definition: Context.h:118
PViewOptions::maxRecursionLevel
int maxRecursionLevel
Definition: PViewOptions.h:78
GEO_Internals::addVertex
bool addVertex(int &tag, double x, double y, double z, double lc)
Definition: GModelIO_GEO.cpp:112
PViewOptions::targetError
double targetError
Definition: PViewOptions.h:79
GModel::getFields
FieldManager * getFields()
Definition: GModel.h:325
MElement
Definition: MElement.h:30
GModel::firstMEdge
hashmapMEdge::const_iterator firstMEdge()
Definition: GModel.h:285
GModel::getMeshElementByTag
MElement * getMeshElementByTag(int n)
Definition: GModel.h:538
PViewDataGModel.h
pyramidalBasis
Definition: pyramidalBasis.h:13
OCC_Internals::getEntities
bool getEntities(std::vector< std::pair< int, int > > &dimTags, int dim)
Definition: GModelIO_OCC.h:809
OCC_Internals::importShapes
bool importShapes(const std::string &fileName, bool highestDimOnly, std::vector< std::pair< int, int > > &outDimTags, const std::string &format="")
Definition: GModelIO_OCC.h:785
ExtrudeParams::NbElmLayer
std::vector< int > NbElmLayer
Definition: ExtrudeParams.h:40
ALGO_3D_HXT
#define ALGO_3D_HXT
Definition: GmshDefines.h:255
GEntity::GhostVolume
@ GhostVolume
Definition: GEntity.h:127
GEntity::tag
int tag() const
Definition: GEntity.h:280
MFaceVertex
Definition: MVertex.h:168
OCC_Internals::addBox
bool addBox(int &tag, double x, double y, double z, double dx, double dy, double dz)
Definition: GModelIO_OCC.h:621
GModel::list
static std::vector< GModel * > list
Definition: GModel.h:202
mult
Quaternion mult(const Quaternion &A, const Quaternion &B)
Definition: Camera.cpp:459
OCC_Internals::getBoundingBox
bool getBoundingBox(int dim, int tag, double &xmin, double &ymin, double &zmin, double &xmax, double &ymax, double &zmax)
Definition: GModelIO_OCC.h:814
PViewDataList::getNumStrings2D
int getNumStrings2D()
Definition: PViewDataList.h:118
GEdge::coeffTransfinite
double coeffTransfinite
Definition: GEdge.h:251
GModel::deleteMesh
void deleteMesh()
Definition: GModel.cpp:236
GModel::removePhysicalName
void removePhysicalName(const std::string &name)
Definition: GModel.cpp:968
partitionFace.h
discreteFace.h
getBoundary
static int getBoundary(int type, const int(**boundary)[6][4])
Definition: Skin.cpp:165
Field
Definition: Field.h:103
apiMsg::get
void get(std::vector< std::string > &log) const
Definition: gmsh.cpp:8639
_argv
static char ** _argv
Definition: gmsh.cpp:111
MVertexRTree.h
GModel::removeElementaryName
void removeElementaryName(const std::string &name)
Definition: GModel.cpp:1014
GEO_Internals::dilate
bool dilate(const std::vector< std::pair< int, int > > &dimTags, double x, double y, double z, double a, double b, double c)
Definition: GModelIO_GEO.cpp:855
partitionEdge.h
gmshViewGetModelData
GMSH_API void gmshViewGetModelData(const int tag, const int step, char **dataType, size_t **tags, size_t *tags_n, double ***data, size_t **data_n, size_t *data_nn, double *time, int *numComponents, int *ierr)
Definition: gmsh.cpp:7332
partitionEdge::getPartitions
virtual const std::vector< int > & getPartitions() const
Definition: partitionEdge.h:41
GModel::makeDiscreteFacesSimplyConnected
void makeDiscreteFacesSimplyConnected()
Definition: GModel.cpp:3160
GModel::computeHomology
void computeHomology(std::vector< std::pair< int, int > > &newPhysicals)
Definition: GModel.cpp:3496
HierarchicalBasisHcurlLine
Definition: HierarchicalBasisHcurlLine.h:31
SVector3::x
double x(void) const
Definition: SVector3.h:30
GModel::getEntities
void getEntities(std::vector< GEntity * > &entities, int dim=-1) const
Definition: GModel.cpp:651
GModel::exportDiscreteGEOInternals
int exportDiscreteGEOInternals()
Definition: GModelIO_GEO.cpp:1910
element
Definition: shapeFunctions.h:12
PViewDataGModel::getType
int getType(int step, int ent, int ele)
Definition: PViewDataGModel.cpp:700
CTX::geom
contextGeometryOptions geom
Definition: Context.h:311
GRegion
Definition: GRegion.h:28
nodalBasis::dimension
int dimension
Definition: nodalBasis.h:14
ExtrudeParams::ExtrudeMesh
bool ExtrudeMesh
Definition: ExtrudeParams.h:36
GEntity::parBounds
virtual Range< double > parBounds(int i) const
Definition: GEntity.h:259
OCC_Internals::rotate
bool rotate(const std::vector< std::pair< int, int > > &inDimTags, double x, double y, double z, double ax, double ay, double az, double angle)
Definition: GModelIO_OCC.h:754
GEO_Internals::addCurveLoops
bool addCurveLoops(const std::vector< int > &curveTags, std::vector< int > &curveLoopTags)
Definition: GModelIO_GEO.cpp:529
fullMatrix::size2
int size2() const
Definition: fullMatrix.h:275
GRegion::prisms
std::vector< MPrism * > prisms
Definition: GRegion.h:165
GmshGlobal.h
PViewData
Definition: PViewData.h:29
GmshGetOption
int GmshGetOption(const std::string &category, const std::string &name, std::string &value, int index)
Definition: GmshGlobal.cpp:161
MTriangle
Definition: MTriangle.h:26
GEdge::typeTransfinite
int typeTransfinite
Definition: GEdge.h:254
contextMeshOptions::secondOrderIncomplete
int secondOrderIncomplete
Definition: Context.h:35
delaunayMeshIn2D
void delaunayMeshIn2D(std::vector< MVertex * > &v, std::vector< MTriangle * > &result, bool removeBox, std::vector< MEdge > *edgesToRecover, bool hilbertSort)
Definition: meshGFaceDelaunayInsertion.cpp:1834
GModel::getMeshElementsByCoord
std::vector< MElement * > getMeshElementsByCoord(SPoint3 &p, int dim=-1, bool strict=true)
Definition: GModel.cpp:1865
TYPE_PYR
#define TYPE_PYR
Definition: GmshDefines.h:69
StringUtils.h
GRegion::pyramids
std::vector< MPyramid * > pyramids
Definition: GRegion.h:166
MElement::pnt
virtual void pnt(double u, double v, double w, SPoint3 &p) const
Definition: MElement.cpp:1072
contextMeshOptions::changed
int changed
Definition: Context.h:82
GEdge::curvature
virtual double curvature(double par) const
Definition: GEdge.cpp:492
Msg::GetLastError
static std::string GetLastError()
Definition: GmshMessage.cpp:362
CTX::unpackAlpha
int unpackAlpha(unsigned int X)
Definition: Context.cpp:160
FIELD_OPTION_INT
@ FIELD_OPTION_INT
Definition: Field.h:31
PViewDataList::NbT2
int NbT2
Definition: PViewDataList.h:48
_getEntitiesForElementTypes
static void _getEntitiesForElementTypes(int dim, int tag, std::map< int, std::vector< GEntity * > > &typeEnt)
Definition: gmsh.cpp:1808
GRegion::addEmbeddedFace
void addEmbeddedFace(GFace *f)
Definition: GRegion.h:59
MElement::gammaShapeMeasure
virtual double gammaShapeMeasure()
Definition: MElement.h:259
HierarchicalBasisH1Brick
Definition: HierarchicalBasisH1Brick.h:45
_argc
static int _argc
Definition: gmsh.cpp:110
MElement::minSICNShapeMeasure
double minSICNShapeMeasure()
Definition: MElement.h:261
removeEmbedded
void removeEmbedded(const std::vector< std::pair< int, int >> &dimTags, int dim)
Definition: Gmsh.tab.cpp:15393
GEntity::PartitionSurface
@ PartitionSurface
Definition: GEntity.h:123
PViewOptions::adaptVisualizationGrid
int adaptVisualizationGrid
Definition: PViewOptions.h:78
GModel::setCurrent
static int setCurrent(GModel *m)
Definition: GModel.cpp:147
MeshSetTransfiniteFacesAutomatic
bool MeshSetTransfiniteFacesAutomatic(std::set< GFace * > &candidate_faces, double cornerAngle=2.35, bool setRecombine=true, double maxDiffRel=1., bool ignoreEmbedded=false)
Automatically set transfinite constraints on curves and faces in the candidate_faces if possible....
Definition: meshGFaceTransfinite.cpp:817
TYPE_QUA
#define TYPE_QUA
Definition: GmshDefines.h:67
TYPE_POLYG
#define TYPE_POLYG
Definition: GmshDefines.h:72
GEO_Internals::translate
bool translate(const std::vector< std::pair< int, int > > &dimTags, double dx, double dy, double dz)
Definition: GModelIO_GEO.cpp:842
PViewDataGModel::ElementNodeData
@ ElementNodeData
Definition: PViewDataGModel.h:196
MVertex::getParameter
virtual bool getParameter(int i, double &par) const
Definition: MVertex.h:97
Field::getName
virtual const char * getName()=0
meshGFace.h
GEO_Internals::addCircleArc
bool addCircleArc(int &tag, int startTag, int centerTag, int endTag, double nx=0., double ny=0., double nz=0.)
Definition: GModelIO_GEO.cpp:175
polynomialBasis.h
PView::write
bool write(const std::string &fileName, int format, bool append=false)
Definition: PViewIO.cpp:378
onelab::server::toJSON
bool toJSON(std::string &json, const std::string &client="")
Definition: onelab.h:1382
SPoint2::x
double x(void) const
Definition: SPoint2.h:86
GEdge::closestPoint
virtual GPoint closestPoint(const SPoint3 &queryPoint, double &param) const
Definition: GEdge.cpp:552
discreteEdge.h
ENT_CURVE
#define ENT_CURVE
Definition: GmshDefines.h:232
MVertex::getIndex
long int getIndex() const
Definition: MVertex.h:93
Pair::right
R right() const
Definition: Pair.h:20
HierarchicalBasisH1Tria.h
ENT_ALL
#define ENT_ALL
Definition: GmshDefines.h:235
OCC_Internals::addCircle
bool addCircle(int &tag, double x, double y, double z, double r, double angle1, double angle2, const std::vector< double > &N=std::vector< double >(), const std::vector< double > &V=std::vector< double >())
Definition: GModelIO_OCC.h:503
Context.h
nodalBasis
Definition: nodalBasis.h:12
GRegion::embeddedEdges
std::vector< GEdge * > & embeddedEdges()
Definition: GRegion.h:80
GModel::getLastMeshVertexError
std::vector< MVertex * > getLastMeshVertexError()
Definition: GModel.h:592
GEntity::getMeshElement
virtual MElement * getMeshElement(std::size_t index) const
Definition: GEntity.h:363
GFace::transfiniteSmoothing
int transfiniteSmoothing
Definition: GFace.h:355
stepData::getNumComponents
int getNumComponents()
Definition: PViewDataGModel.h:93
ElementType::getDimension
int getDimension(int type)
Definition: ElementType.cpp:297
Field::options
std::map< std::string, FieldOption * > options
Definition: Field.h:112
MTetrahedron.h
getElement
static MElement * getElement(GEntity *e, int va_type, int index)
Definition: drawContext.cpp:902
PViewDataList::T2D
std::vector< double > T2D
Definition: PViewDataList.h:49
GEdge::containsParam
virtual bool containsParam(double pt) const
Definition: GEdge.cpp:453
SVector3::y
double y(void) const
Definition: SVector3.h:31
fullMatrix::size1
int size1() const
Definition: fullMatrix.h:274
ExtrudeParams::ViewIndex
int ViewIndex
Definition: ExtrudeParams.h:46
GRegion::embeddedFaces
std::vector< GFace * > & embeddedFaces()
Definition: GRegion.h:81
GEO_Internals::setReverseMesh
void setReverseMesh(int dim, int tag, bool val=1)
Definition: GModelIO_GEO.cpp:1309
GModel::unpartitionMesh
int unpartitionMesh()
Definition: GModel.cpp:2226
HierarchicalBasisH1Line
Definition: HierarchicalBasisH1Line.h:30
GVertex.h
GEntity::getNumMeshElementsByType
virtual std::size_t getNumMeshElementsByType(const int familyType) const
Definition: GEntity.h:349
GEO_Internals::revolve
bool revolve(const std::vector< std::pair< int, int > > &inDimTags, double x, double y, double z, double ax, double ay, double az, double angle, std::vector< std::pair< int, int > > &outDimTags, ExtrudeParams *e=0)
Definition: GModelIO_GEO.cpp:783
GFace::embeddedEdges
std::vector< GEdge * > & embeddedEdges()
Definition: GFace.h:156
z
const double z
Definition: GaussQuadratureQuad.cpp:56
GFace::curvatureMax
virtual double curvatureMax(const SPoint2 &param) const
Definition: GFace.cpp:1020
MQuadrangle.h
GEO_Internals::copy
bool copy(const std::vector< std::pair< int, int > > &inDimTags, std::vector< std::pair< int, int > > &outDimTags)
Definition: GModelIO_GEO.cpp:913
OCC_Internals::addBezier
bool addBezier(int &tag, const std::vector< int > &pointTags)
Definition: GModelIO_OCC.h:527
GRegion::meshAttributes
struct GRegion::@20 meshAttributes
MElement::getInfoMSH
static unsigned int getInfoMSH(const int typeMSH, const char **const name=nullptr)
Definition: MElement.cpp:2057
OCC_Internals::addCone
bool addCone(int &tag, double x, double y, double z, double dx, double dy, double dz, double r1, double r2, double angle)
Definition: GModelIO_OCC.h:631
OCC_Internals::addWire
bool addWire(int &tag, const std::vector< int > &curveTags, bool closed)
Definition: GModelIO_OCC.h:539
GEO_Internals::twist
bool twist(const std::vector< std::pair< int, int > > &inDimTags, double x, double y, double z, double dx, double dy, double dz, double ax, double ay, double az, double angle, std::vector< std::pair< int, int > > &outDimTags, ExtrudeParams *e=0)
Definition: GModelIO_GEO.cpp:793
CTX::glFontSize
int glFontSize
Definition: Context.h:267
HierarchicalBasisHcurlTetra.h
HierarchicalBasisH1Quad.h
gmsh_yystringsymbols
std::map< std::string, std::vector< std::string > > gmsh_yystringsymbols
Definition: Gmsh.tab.cpp:644
GEdge::point
virtual GPoint point(double p) const =0
makeSimplyConnected
static void makeSimplyConnected(std::map< int, std::vector< MElement * > > elements[11])
Definition: GModel.cpp:3216
Pair
Definition: Pair.h:10
apiMsg::operator()
virtual void operator()(std::string level, std::string message)
Definition: gmsh.cpp:8634
picojson::copy
void copy(const std::string &s, Iter oi)
Definition: picojson.h:510
Malloc
void * Malloc(size_t size)
Definition: MallocUtils.cpp:12
MPoint
Definition: MPoint.h:16
OCC_Internals::getCenterOfMass
bool getCenterOfMass(int dim, int tag, double &x, double &y, double &z)
Definition: GModelIO_OCC.h:837
GEO_Internals::addCompoundSpline
bool addCompoundSpline(int &tag, const std::vector< int > &curveTags, int numPoints)
Definition: GModelIO_GEO.cpp:387
GRegion::addEmbeddedEdge
void addEmbeddedEdge(GEdge *e)
Definition: GRegion.h:58
GEO_Internals::addPlaneSurface
bool addPlaneSurface(int &tag, const std::vector< int > &wireTags)
Definition: GModelIO_GEO.cpp:592
GModel::removePhysicalGroup
void removePhysicalGroup(int dim, int num)
Definition: GModel.cpp:901
GEO_Internals::remove
bool remove(int dim, int tag, bool recursive=false)
Definition: GModelIO_GEO.cpp:969
GEdge
Definition: GEdge.h:26
SVector3::z
double z(void) const
Definition: SVector3.h:32
GModel::optimizeMesh
int optimizeMesh(const std::string &how, bool force=false, int niter=1)
Definition: GModel.cpp:1437
PView::getOptions
PViewOptions * getOptions()
Definition: PView.h:81
GmshWriteFile
int GmshWriteFile(const std::string &fileName)
Definition: GmshGlobal.cpp:237
OCC_Internals::synchronize
void synchronize(GModel *model)
Definition: GModelIO_OCC.h:803
PViewDataGModel::DataType
DataType
Definition: PViewDataGModel.h:193
MElement::angleShapeMeasure
virtual double angleShapeMeasure()
Definition: MElement.h:281
GModel::pruneMeshVertexAssociations
void pruneMeshVertexAssociations()
Definition: GModel.cpp:2527
TYPE_HEX
#define TYPE_HEX
Definition: GmshDefines.h:71
GEO_Internals::setSmoothing
void setSmoothing(int tag, int val)
Definition: GModelIO_GEO.cpp:1291
MPrism.h
FieldManager::addBoundaryLayerFieldId
void addBoundaryLayerFieldId(int id)
Definition: Field.h:166
MElement::barycenter
virtual SPoint3 barycenter(bool primary=false) const
Definition: MElement.cpp:520
GEntity::getPhysicalEntities
virtual std::vector< int > getPhysicalEntities()
Definition: GEntity.h:288
TYPE_TET
#define TYPE_TET
Definition: GmshDefines.h:68
GModel::setPhysicalName
int setPhysicalName(const std::string &name, int dim, int num=0)
Definition: GModel.cpp:937
MFace::getOrientationFlagForFace
void getOrientationFlagForFace(std::vector< int > &faceOrientationFlag)
Definition: MFace.cpp:84
GEO_Internals::addSurfaceLoop
bool addSurfaceLoop(int &tag, const std::vector< int > &surfaceTags)
Definition: GModelIO_GEO.cpp:680
_getExtrudeParams
static ExtrudeParams * _getExtrudeParams(const std::vector< int > &numElements, const std::vector< double > &heights, const bool recombine)
Definition: gmsh.cpp:6000
drawContext::show
void show(GModel *m)
Definition: drawContext.h:187
HierarchicalBasisHcurlPri.h
GModel::getEntityByTag
GEntity * getEntityByTag(int dim, int n) const
Definition: GModel.cpp:356
SPoint3::z
double z(void) const
Definition: SPoint3.h:129
GModel::mesh
int mesh(int dimension)
Definition: GModel.cpp:1066
GModel::getMFace
std::size_t getMFace(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3, MFace &face)
Definition: GModel.cpp:1591
GEO_Internals::setMeshSize
void setMeshSize(int dim, int tag, double size)
Definition: GModelIO_GEO.cpp:1117
partitionVertex
Definition: partitionVertex.h:12
OCC_Internals::getCurveLoops
bool getCurveLoops(int surfaceTag, std::vector< int > &curveLoopTags, std::vector< std::vector< int > > &curveTags)
Definition: GModelIO_OCC.h:826
polynomialBasis
Definition: polynomialBasis.h:16
TYPE_TRIH
#define TYPE_TRIH
Definition: GmshDefines.h:76
GModel::renumberMeshElements
void renumberMeshElements()
Definition: GModel.cpp:1732
MElement::setVisibility
virtual void setVisibility(char val)
Definition: MElement.h:97
GFace::setMeshMaster
void setMeshMaster(GFace *master, const std::vector< double > &)
Definition: GFace.cpp:2222
OCC_Internals::addBSpline
bool addBSpline(int &tag, const std::vector< int > &pointTags, const int degree=-1, const std::vector< double > &weights=std::vector< double >(), const std::vector< double > &knots=std::vector< double >(), const std::vector< int > &multiplicities=std::vector< int >())
Definition: GModelIO_OCC.h:531
GEntity::PartitionPoint
@ PartitionPoint
Definition: GEntity.h:121
MVertexRTree
Definition: MVertexRTree.h:16
GModel::lastEdge
eiter lastEdge()
Definition: GModel.h:360
GModel::lastMFace
hashmapMFace::const_iterator lastMFace()
Definition: GModel.h:288
MElement::getJacobian
virtual double getJacobian(const fullMatrix< double > &gsf, double jac[3][3]) const
Definition: MElement.cpp:868
OCC_Internals::affine
bool affine(const std::vector< std::pair< int, int > > &inDimTags, const std::vector< double > &mat)
Definition: GModelIO_OCC.h:769
FIELD_OPTION_LIST_DOUBLE
@ FIELD_OPTION_LIST_DOUBLE
Definition: Field.h:36
stepData::getNumData
std::size_t getNumData()
Definition: PViewDataGModel.h:109
PViewData::searchTensorClosest
bool searchTensorClosest(double x, double y, double z, double &distance, double *values, int step=-1, double *size=nullptr, int qn=0, double *qx=nullptr, double *qy=nullptr, double *qz=nullptr, bool grad=false, int dim=-1)
Definition: PViewData.cpp:418
GVertex::reparamOnFace
virtual SPoint2 reparamOnFace(const GFace *gf, int) const
Definition: GVertex.cpp:49
onelabUtils::runClient
void runClient(const std::string &name="", const std::string &command="")
GModel::getMEdge
std::size_t getMEdge(MVertex *v0, MVertex *v1, MEdge &edge)
Definition: GModel.cpp:1569
GModel.h
MFace::getNumVertices
std::size_t getNumVertices() const
Definition: MFace.h:29
PViewData::getName
virtual std::string getName()
Definition: PViewData.h:70
ghostEdge.h
OCC_Internals::addPlaneSurface
bool addPlaneSurface(int &tag, const std::vector< int > &wireTags)
Definition: GModelIO_OCC.h:558
gaussIntegration::get
static void get(int elementType, int order, fullMatrix< double > &pts, fullVector< double > &weights, bool forceTensorRule=false)
Definition: GaussIntegration.cpp:65
GModel::getRegionByTag
GRegion * getRegionByTag(int n) const
Definition: GModel.cpp:316
MVertex::y
double y() const
Definition: MVertex.h:61
GFace::normal
virtual SVector3 normal(const SPoint2 &param) const
Definition: GFace.cpp:1416
GEdge::getEndVertex
virtual GVertex * getEndVertex() const
Definition: GEdge.h:64
ElementType::getNumVertices
int getNumVertices(int type)
Definition: ElementType.cpp:456
GEO_Internals::resetPhysicalGroups
void resetPhysicalGroups()
Definition: GModelIO_GEO.cpp:992
GFace::addEmbeddedVertex
void addEmbeddedVertex(GVertex *v)
Definition: GFace.h:104
GEdge::nbPointsTransfinite
int nbPointsTransfinite
Definition: GEdge.h:253
MElement::distoShapeMeasure
double distoShapeMeasure()
Definition: MElement.h:273
Range::low
T low() const
Definition: Range.h:18
GVertex::setPrescribedMeshSizeAtVertex
virtual void setPrescribedMeshSizeAtVertex(double l)
Definition: GVertex.h:76
OCC_Internals::booleanUnion
bool booleanUnion(int tag, const std::vector< std::pair< int, int > > &objectDimTags, const std::vector< std::pair< int, int > > &toolDimTags, std::vector< std::pair< int, int > > &outDimTags, std::vector< std::vector< std::pair< int, int > > > &outDimTagsMap, bool removeObject, bool removeTool)
Definition: GModelIO_OCC.h:709
PViewDataGModel::getStepData
stepData< double > * getStepData(int step)
Definition: PViewDataGModel.h:321
GEntity::isFullyDiscrete
virtual bool isFullyDiscrete()
Definition: GEntity.h:256
GEdge::secondDer
virtual SVector3 secondDer(double par) const
Definition: GEdge.cpp:460
PView::list
static std::vector< PView * > list
Definition: PView.h:112
GEO_Internals::synchronize
void synchronize(GModel *model, bool resetMeshAttributes=true)
Definition: GModelIO_GEO.cpp:1370
MallocUtils.h
SBoundingBox3d::max
SPoint3 max() const
Definition: SBoundingBox3d.h:91
CTX::terminal
int terminal
Definition: Context.h:167
GModel::addPhysicalGroup
void addPhysicalGroup(int dim, int tag, const std::vector< int > &tags)
Definition: GModel.cpp:881
GEntity::dim
virtual int dim() const
Definition: GEntity.h:196
GEntity::bounds
virtual SBoundingBox3d bounds(bool fast=false)
Definition: GEntity.h:301
GModel::getVertexByTag
GVertex * getVertexByTag(int n) const
Definition: GModel.cpp:346
partitionVertex.h
ghostEdge
Definition: ghostEdge.h:15
GRegion::setBoundFaces
void setBoundFaces(const std::set< int > &tagFaces)
Definition: GRegion.cpp:294
MElement::getFaceSolin
virtual MFace getFaceSolin(int numFace)
Definition: MElement.h:213
PView::setOptions
void setOptions(PViewOptions *val=nullptr)
Definition: PView.cpp:224
ExtrudeParams
Definition: ExtrudeParams.h:26
HierarchicalBasisH1Tetra
Definition: HierarchicalBasisH1Tetra.h:51
ghostRegion.h
ParseFile
int ParseFile(const std::string &fileName, bool close, bool errorIfMissing)
Definition: OpenFile.cpp:177
GModel::getGEOInternals
GEO_Internals * getGEOInternals()
Definition: GModel.h:315
stepData
Definition: PViewDataGModel.h:13
MElement::minIsotropyMeasure
double minIsotropyMeasure(bool knownValid=false, bool reversedOk=false)
Definition: MElement.cpp:280
OCC_Internals::healShapes
bool healShapes(const std::vector< std::pair< int, int > > &inDimTags, std::vector< std::pair< int, int > > &outDimTags, double tolerance, bool fixDegenerated, bool fixSmallEdges, bool fixSmallFaces, bool sewFaces, bool makeSolids)
Definition: GModelIO_OCC.h:791
GPoint::x
double x() const
Definition: GPoint.h:21
GEntity::getVisibility
virtual char getVisibility()
Definition: GEntity.cpp:35
MElement::getNumEdges
virtual int getNumEdges() const =0
GEntity::correspondingVertices
std::map< MVertex *, MVertex * > correspondingVertices
Definition: GEntity.h:406
onelab::server::set
bool set(const T &p, const std::string &client="")
Definition: onelab.h:1319
ExtrudeParams::hLayer
std::vector< double > hLayer
Definition: ExtrudeParams.h:41
CTX::unpackRed
int unpackRed(unsigned int X)
Definition: Context.cpp:136
GEntity::faces
virtual std::vector< GFace * > faces() const
Definition: GEntity.h:208
GModel::getOCCInternals
OCC_Internals * getOCCInternals()
Definition: GModel.h:314
TYPE_POLYH
#define TYPE_POLYH
Definition: GmshDefines.h:73
GFace::curvatures
virtual double curvatures(const SPoint2 &param, SVector3 &dirMax, SVector3 &dirMin, double &curvMax, double &curvMin) const
Definition: GFace.cpp:1031
MQuadrangle
Definition: MQuadrangle.h:26
GEdge::parFromPoint
virtual double parFromPoint(const SPoint3 &P) const
Definition: GEdge.cpp:595
GEO_Internals::setTransfiniteVolume
void setTransfiniteVolume(int tag, const std::vector< int > &cornerTags)
Definition: GModelIO_GEO.cpp:1201
GModel::addMEdge
std::size_t addMEdge(MEdge &edge, std::size_t num=0)
Definition: GModel.cpp:1561
OCC_Internals::remove
bool remove(int dim, int tag, bool recursive=false)
Definition: GModelIO_OCC.h:779
SBoundingBox3d
Definition: SBoundingBox3d.h:21
OCC_Internals::addCylinder
bool addCylinder(int &tag, double x, double y, double z, double dx, double dy, double dz, double r, double angle)
Definition: GModelIO_OCC.h:626
ElementType::getParentType
int getParentType(int type)
Definition: ElementType.cpp:10
SPoint3::transform
bool transform(const std::vector< double > &tfo)
Definition: SPoint3.h:78
OCC_Internals::chamfer
bool chamfer(const std::vector< int > &volumeTags, const std::vector< int > &curveTags, const std::vector< int > &surfaceTags, const std::vector< double > &distances, std::vector< std::pair< int, int > > &outDimTags, bool removeVolume)
Definition: GModelIO_OCC.h:690
OpenFile.h
GEdge::method
char method
Definition: GEdge.h:250
GFace::reverseMesh
bool reverseMesh
Definition: GFace.h:359
HierarchicalBasisHcurlTria
Definition: HierarchicalBasisHcurlTria.h:38
onelab::server::setChanged
void setChanged(int changed, const std::string &client="")
Definition: onelab.h:1345
GRegion::tetrahedra
std::vector< MTetrahedron * > tetrahedra
Definition: GRegion.h:163
_getIntegrationInfo
static bool _getIntegrationInfo(const std::string &intType, std::string &intName, int &intOrder)
Definition: gmsh.cpp:4420
GRegion::embeddedVertices
std::vector< GVertex * > & embeddedVertices()
Definition: GRegion.h:79
GModel::current
static GModel * current(int index=-1)
Definition: GModel.cpp:136
nodalBasis::getNumShapeFunctions
virtual int getNumShapeFunctions() const =0
MVertex::x
double x() const
Definition: MVertex.h:60
GEO_Internals::addCurveLoop
bool addCurveLoop(int &tag, const std::vector< int > &curveTags, bool reorient=false)
Definition: GModelIO_GEO.cpp:401
PViewDataGModel::addData
bool addData(GModel *model, const std::map< int, std::vector< double > > &data, int step, double time, int partition, int numComp)
Definition: PViewDataGModelIO.cpp:19
OCC_Internals::getMatrixOfInertia
bool getMatrixOfInertia(int dim, int tag, std::vector< double > &mat)
Definition: GModelIO_OCC.h:841
OCC_Internals::addTrimmedSurface
bool addTrimmedSurface(int &tag, int surfaceTag, const std::vector< int > &wireTags, bool wire3D)
Definition: GModelIO_OCC.h:602
GEO_Internals::addBezier
bool addBezier(int &tag, const std::vector< int > &pointTags)
Definition: GModelIO_GEO.cpp:271
GRegion::setOutwardOrientationMeshConstraint
bool setOutwardOrientationMeshConstraint()
Definition: GRegion.cpp:839
GModel::partitionMesh
int partitionMesh(int num, std::vector< std::pair< MElement *, int > > elementPartition=std::vector< std::pair< MElement *, int > >())
Definition: GModel.cpp:2208
GModel::lastMEdge
hashmapMEdge::const_iterator lastMEdge()
Definition: GModel.h:286
MElement::getGradShapeFunctions
virtual void getGradShapeFunctions(double u, double v, double w, double s[][3], int order=-1) const
Definition: MElement.cpp:468
discreteFace
Definition: discreteFace.h:18
GmshOpenProject
int GmshOpenProject(const std::string &fileName)
Definition: GmshGlobal.cpp:213
faces
static int faces[4][3]
Definition: meshGRegionDelaunayInsertion.cpp:165
SPoint2::y
double y(void) const
Definition: SPoint2.h:88
OCC_Internals::addThruSections
bool addThruSections(int tag, const std::vector< int > &wireTags, bool makeSolid, bool makeRuled, std::vector< std::pair< int, int > > &outDimTags, int maxDegree=-1, const std::string &continuity="", const std::string &parametrization="", bool smoothing=false)
Definition: GModelIO_OCC.h:648
FieldOption
Definition: Field.h:50
GModel::getMeshElementByCoord
MElement * getMeshElementByCoord(SPoint3 &p, SPoint3 &param, int dim=-1, bool strict=true)
Definition: GModel.cpp:1842
gmshPolarSphere::NewPolarSphere
static gmshSurface * NewPolarSphere(int _iSphere, double _x, double _y, double _z, double _r)
Definition: gmshSurface.cpp:70
FIELD_OPTION_STRING
@ FIELD_OPTION_STRING
Definition: Field.h:32
GFace::corners
std::vector< GVertex * > corners
Definition: GFace.h:350
drawContext.h
drawContext::hide
void hide(GModel *m)
Definition: drawContext.h:185
CTX::abortOnError
int abortOnError
Definition: Context.h:153