gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
Skin.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 <set>
7 #include "Skin.h"
8 #include "Context.h"
9 #include "GmshDefines.h"
10 #include "MTriangle.h"
11 #include "MQuadrangle.h"
12 #include "MLine.h"
13 #include "MFace.h"
14 #include "MEdge.h"
15 #include "discreteFace.h"
16 #include "discreteEdge.h"
17 
18 StringXNumber SkinOptions_Number[] = {{GMSH_FULLRC, "Visible", nullptr, 1.},
19  {GMSH_FULLRC, "FromMesh", nullptr, 0.},
20  {GMSH_FULLRC, "View", nullptr, -1.}};
21 
22 extern "C" {
24 }
25 
26 std::string GMSH_SkinPlugin::getHelp() const
27 {
28  return "Plugin(Skin) extracts the boundary (skin) of the current "
29  "mesh (if `FromMesh' = 1), or from the the view `View' (in which "
30  "case it creates a new view). If `View' < 0 and `FromMesh' = 0, "
31  "the plugin is run on the current view.\n"
32  "If `Visible' is set, the plugin only extracts the skin of visible "
33  "entities.";
34 }
35 
37 {
38  return sizeof(SkinOptions_Number) / sizeof(StringXNumber);
39 }
40 
42 {
43  return &SkinOptions_Number[iopt];
44 }
45 
46 class ElmData {
47 public:
48  int numComp;
49  std::vector<double> x, y, z;
50  std::vector<double> v;
51  ElmData(int n) : numComp(n) {}
53  {
54  SPoint3 p(0., 0., 0.);
55  int N = x.size();
56  for(int i = 0; i < N; i++) {
57  p[0] += x[i];
58  p[1] += y[i];
59  p[2] += z[i];
60  }
61  p[0] /= (double)N;
62  p[1] /= (double)N;
63  p[2] /= (double)N;
64  return p;
65  }
66  void addInView(PViewDataList *data) const
67  {
68  std::vector<double> *vec = nullptr;
69  switch(x.size()) {
70  case 1:
71  if(numComp == 1) {
72  data->NbSP++;
73  vec = &data->SP;
74  break;
75  }
76  else if(numComp == 3) {
77  data->NbVP++;
78  vec = &data->VP;
79  break;
80  }
81  else if(numComp == 9) {
82  data->NbTP++;
83  vec = &data->TP;
84  break;
85  }
86  break;
87  case 2:
88  if(numComp == 1) {
89  data->NbSL++;
90  vec = &data->SL;
91  break;
92  }
93  else if(numComp == 3) {
94  data->NbVL++;
95  vec = &data->VL;
96  break;
97  }
98  else if(numComp == 9) {
99  data->NbTL++;
100  vec = &data->TL;
101  break;
102  }
103  break;
104  case 3:
105  if(numComp == 1) {
106  data->NbST++;
107  vec = &data->ST;
108  break;
109  }
110  else if(numComp == 3) {
111  data->NbVT++;
112  vec = &data->VT;
113  break;
114  }
115  else if(numComp == 9) {
116  data->NbTT++;
117  vec = &data->TT;
118  break;
119  }
120  break;
121  case 4:
122  if(numComp == 1) {
123  data->NbSQ++;
124  vec = &data->SQ;
125  break;
126  }
127  else if(numComp == 3) {
128  data->NbVQ++;
129  vec = &data->VQ;
130  break;
131  }
132  else if(numComp == 9) {
133  data->NbTQ++;
134  vec = &data->TQ;
135  break;
136  }
137  break;
138  }
139  if(!vec) return;
140  for(std::size_t i = 0; i < x.size(); i++) vec->push_back(x[i]);
141  for(std::size_t i = 0; i < y.size(); i++) vec->push_back(y[i]);
142  for(std::size_t i = 0; i < z.size(); i++) vec->push_back(z[i]);
143  for(std::size_t i = 0; i < v.size(); i++) vec->push_back(v[i]);
144  }
145 };
146 
148 public:
149  static double tolerance;
150  bool operator()(const ElmData &e1, const ElmData &e2) const
151  {
152  SPoint3 p1 = e1.barycenter();
153  SPoint3 p2 = e2.barycenter();
154  if(p1.x() - p2.x() > tolerance) return true;
155  if(p1.x() - p2.x() < -tolerance) return false;
156  if(p1.y() - p2.y() > tolerance) return true;
157  if(p1.y() - p2.y() < -tolerance) return false;
158  if(p1.z() - p2.z() > tolerance) return true;
159  return false;
160  }
161 };
162 
163 double ElmDataLessThan::tolerance = 1.e-12;
164 
165 static int getBoundary(int type, const int (**boundary)[6][4])
166 {
167  static const int tri[6][4] = {{0, 1, -1, -1}, {1, 2, -1, -1}, {2, 0, -1, -1}};
168  static const int qua[6][4] = {
169  {0, 1, -1, -1}, {1, 2, -1, -1}, {2, 3, -1, -1}, {3, 0, -1, -1}};
170  static const int tet[6][4] = {
171  {0, 1, 3, -1}, {0, 2, 1, -1}, {0, 3, 2, -1}, {1, 2, 3, -1}};
172  static const int hex[6][4] = {{0, 1, 5, 4}, {0, 3, 2, 1}, {0, 4, 7, 3},
173  {1, 2, 6, 5}, {2, 3, 7, 6}, {4, 5, 6, 7}};
174  static const int pri[6][4] = {
175  {0, 1, 4, 3}, {0, 3, 5, 2}, {1, 2, 5, 4}, {0, 2, 1, -1}, {3, 4, 5, -1}};
176  static const int pyr[6][4] = {
177  {0, 3, 2, 1}, {0, 1, 4, -1}, {0, 4, 3, -1}, {1, 2, 4, -1}, {2, 3, 4, -1}};
178  switch(type) {
179  case TYPE_TRI: *boundary = &tri; return 3;
180  case TYPE_QUA: *boundary = &qua; return 4;
181  case TYPE_TET: *boundary = &tet; return 4;
182  case TYPE_HEX: *boundary = &hex; return 6;
183  case TYPE_PRI: *boundary = &pri; return 5;
184  case TYPE_PYR: *boundary = &pyr; return 5;
185  default: return 0;
186  }
187 }
188 
189 static void getBoundaryFromMesh(GModel *m, int visible)
190 {
191  int dim = m->getDim();
192  std::vector<GEntity *> entities;
193  m->getEntities(entities);
194  std::set<MFace, MFaceLessThan> bndFaces;
195  std::set<MEdge, MEdgeLessThan> bndEdges;
196  for(std::size_t i = 0; i < entities.size(); i++) {
197  GEntity *ge = entities[i];
198  if(ge->dim() != dim) continue;
199  if(visible && !ge->getVisibility()) continue;
200  for(std::size_t j = 0; j < ge->getNumMeshElements(); j++) {
201  MElement *e = ge->getMeshElement(j);
202  if(dim == 2) {
203  for(int i = 0; i < e->getNumEdges(); i++) {
204  MEdge f = e->getEdge(i);
205  if(bndEdges.find(f) == bndEdges.end())
206  bndEdges.insert(f);
207  else
208  bndEdges.erase(f);
209  }
210  }
211  else if(dim == 3) {
212  for(int i = 0; i < e->getNumFaces(); i++) {
213  MFace f = e->getFace(i);
214  if(bndFaces.find(f) == bndFaces.end())
215  bndFaces.insert(f);
216  else
217  bndFaces.erase(f);
218  }
219  }
220  }
221  }
222 
223  if(dim == 2) {
224  discreteEdge *e =
225  new discreteEdge(m, m->getMaxElementaryNumber(1) + 1, nullptr, nullptr);
226  m->add(e);
227  for(auto it = bndEdges.begin(); it != bndEdges.end(); it++) {
228  e->lines.push_back(new MLine(it->getVertex(0), it->getVertex(1)));
229  }
230  }
231  else if(dim == 3) {
232  discreteFace *f = new discreteFace(m, m->getMaxElementaryNumber(2) + 1);
233  m->add(f);
234  for(auto it = bndFaces.begin(); it != bndFaces.end(); it++) {
235  if(it->getNumVertices() == 3)
236  f->triangles.push_back(
237  new MTriangle(it->getVertex(0), it->getVertex(1), it->getVertex(2)));
238  else if(it->getNumVertices() == 4)
239  f->quadrangles.push_back(
240  new MQuadrangle(it->getVertex(0), it->getVertex(1), it->getVertex(2),
241  it->getVertex(3)));
242  }
243  }
244 }
245 
247 {
248  int visible = (int)SkinOptions_Number[0].def;
249  int fromMesh = (int)SkinOptions_Number[1].def;
250  int iView = (int)SkinOptions_Number[2].def;
251 
252  // compute boundary of current mesh
253  if(fromMesh) {
255  return v;
256  }
257 
258  // compute boundary of post-processing data set
259  PView *v1 = getView(iView, v);
260  if(!v1) return v;
261  PViewData *data1 = getPossiblyAdaptiveData(v1);
262 
263  if(data1->hasMultipleMeshes()) {
264  Msg::Error("Skin plugin cannot be applied to multi-mesh views");
265  return v;
266  }
267 
268  Msg::Info("Extracting boundary from View[%d]", v1->getIndex());
269 
270  PView *v2 = new PView();
271  PViewDataList *data2 = getDataList(v2);
272 
273  std::set<ElmData, ElmDataLessThan> skin;
275 
276  int firstNonEmptyStep = data1->getFirstNonEmptyTimeStep();
277  for(int ent = 0; ent < data1->getNumEntities(firstNonEmptyStep); ent++) {
278  if(visible && data1->skipEntity(firstNonEmptyStep, ent)) continue;
279  for(int ele = 0; ele < data1->getNumElements(firstNonEmptyStep, ent);
280  ele++) {
281  if(data1->skipElement(firstNonEmptyStep, ent, ele, visible)) continue;
282  int numComp = data1->getNumComponents(firstNonEmptyStep, ent, ele);
283  int type = data1->getType(firstNonEmptyStep, ent, ele);
284  const int(*boundary)[6][4];
285  int numBoundary = getBoundary(type, &boundary);
286  if(!numBoundary) continue;
287  for(int i = 0; i < numBoundary; i++) {
288  ElmData e(numComp);
289  for(int j = 0; j < 4; j++) {
290  int nod = (*boundary)[i][j];
291  if(nod < 0) continue;
292  double x, y, z;
293  data1->getNode(firstNonEmptyStep, ent, ele, nod, x, y, z);
294  e.x.push_back(x);
295  e.y.push_back(y);
296  e.z.push_back(z);
297  }
298  auto it = skin.find(e);
299  if(it == skin.end()) {
300  for(int step = 0; step < data1->getNumTimeSteps(); step++) {
301  if(data1->hasTimeStep(step)) {
302  for(int j = 0; j < 4; j++) {
303  int nod = (*boundary)[i][j];
304  if(nod < 0) continue;
305  double v;
306  for(int comp = 0; comp < numComp; comp++) {
307  data1->getValue(step, ent, ele, nod, comp, v);
308  e.v.push_back(v);
309  }
310  }
311  }
312  }
313  skin.insert(e);
314  }
315  else
316  skin.erase(it);
317  }
318  }
319  }
320 
321  for(auto it = skin.begin(); it != skin.end(); it++) it->addInView(data2);
322 
323  for(int i = 0; i < data1->getNumTimeSteps(); i++)
324  if(data1->hasTimeStep(i)) data2->Time.push_back(data1->getTime(i));
325  data2->setName(data1->getName() + "_Skin");
326  data2->setFileName(data1->getName() + "_Skin.pos");
327  data2->finalize();
328 
329  return v2;
330 }
ElmData::barycenter
SPoint3 barycenter() const
Definition: Skin.cpp:52
PViewDataList::VQ
std::vector< double > VQ
Definition: PViewDataList.h:33
MTriangle.h
PView
Definition: PView.h:27
PViewDataList::TQ
std::vector< double > TQ
Definition: PViewDataList.h:33
MEdge
Definition: MEdge.h:14
PViewData::skipElement
virtual bool skipElement(int step, int ent, int ele, bool checkVisibility=false, int samplingRate=1)
Definition: PViewData.cpp:90
GModel::getMaxElementaryNumber
int getMaxElementaryNumber(int dim)
Definition: GModel.cpp:817
ElmData::numComp
int numComp
Definition: Skin.cpp:48
PViewDataList::NbTL
int NbTL
Definition: PViewDataList.h:28
PViewDataList::TL
std::vector< double > TL
Definition: PViewDataList.h:29
GMSH_RegisterSkinPlugin
GMSH_Plugin * GMSH_RegisterSkinPlugin()
Definition: Skin.cpp:23
GMSH_SkinPlugin::getOption
StringXNumber * getOption(int iopt)
Definition: Skin.cpp:41
GMSH_Plugin
Definition: Plugin.h:26
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
GEdge::lines
std::vector< MLine * > lines
Definition: GEdge.h:42
PViewData::getNumTimeSteps
virtual int getNumTimeSteps()=0
PViewDataList::NbTP
int NbTP
Definition: PViewDataList.h:26
GMSH_SkinPlugin
Definition: Skin.h:15
PViewDataList::NbTT
int NbTT
Definition: PViewDataList.h:30
PViewDataList
Definition: PViewDataList.h:17
discreteEdge
Definition: discreteEdge.h:12
PViewData::getNode
virtual int getNode(int step, int ent, int ele, int nod, double &x, double &y, double &z)
Definition: PViewData.h:141
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
PViewDataList::NbSP
int NbSP
Definition: PViewDataList.h:26
SPoint3
Definition: SPoint3.h:14
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
StringXNumber
Definition: Options.h:918
PViewData::getValue
virtual void getValue(int step, int ent, int ele, int idx, double &val)
Definition: PViewData.h:159
PViewDataList::NbSQ
int NbSQ
Definition: PViewDataList.h:32
ElmData::ElmData
ElmData(int n)
Definition: Skin.cpp:51
ElmData::v
std::vector< double > v
Definition: Skin.cpp:50
PView::getIndex
int getIndex()
Definition: PView.h:92
TYPE_TRI
#define TYPE_TRI
Definition: GmshDefines.h:66
PViewDataList::VL
std::vector< double > VL
Definition: PViewDataList.h:29
PViewData::hasMultipleMeshes
virtual bool hasMultipleMeshes()
Definition: PViewData.h:216
MLine.h
PViewData::getNumEntities
virtual int getNumEntities(int step=-1)
Definition: PViewData.h:127
GEntity
Definition: GEntity.h:31
TYPE_PRI
#define TYPE_PRI
Definition: GmshDefines.h:70
PViewData::setFileName
virtual void setFileName(const std::string &val)
Definition: PViewData.h:75
ElmDataLessThan::operator()
bool operator()(const ElmData &e1, const ElmData &e2) const
Definition: Skin.cpp:150
MLine
Definition: MLine.h:21
ElmDataLessThan
Definition: Skin.cpp:147
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
SPoint3::x
double x(void) const
Definition: SPoint3.h:125
MElement::getEdge
virtual MEdge getEdge(int num) const =0
GMSH_SkinPlugin::getHelp
std::string getHelp() const
Definition: Skin.cpp:26
MFace
Definition: MFace.h:20
PViewDataList::TP
std::vector< double > TP
Definition: PViewDataList.h:27
PViewData::getTime
virtual double getTime(int step)
Definition: PViewData.h:94
MFace.h
PViewData::getType
virtual int getType(int step, int ent, int ele)
Definition: PViewData.h:183
PViewDataList::VP
std::vector< double > VP
Definition: PViewDataList.h:27
MElement::getNumFaces
virtual int getNumFaces()=0
GEntity::getNumMeshElements
virtual std::size_t getNumMeshElements() const
Definition: GEntity.h:348
PViewDataList::SP
std::vector< double > SP
Definition: PViewDataList.h:27
ElmData::addInView
void addInView(PViewDataList *data) const
Definition: Skin.cpp:66
CTX::lc
double lc
Definition: Context.h:234
GMSH_FULLRC
#define GMSH_FULLRC
Definition: Options.h:20
GModel::getDim
int getDim() const
Definition: GModel.cpp:989
SkinOptions_Number
StringXNumber SkinOptions_Number[]
Definition: Skin.cpp:18
PViewData::hasTimeStep
virtual bool hasTimeStep(int step)
Definition: PViewData.h:211
MElement::getFace
virtual MFace getFace(int num) const =0
GModel
Definition: GModel.h:44
PViewDataList::SL
std::vector< double > SL
Definition: PViewDataList.h:29
GmshDefines.h
SPoint3::y
double y(void) const
Definition: SPoint3.h:127
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
MElement
Definition: MElement.h:30
discreteFace.h
getBoundary
static int getBoundary(int type, const int(**boundary)[6][4])
Definition: Skin.cpp:165
PViewDataList::ST
std::vector< double > ST
Definition: PViewDataList.h:31
PViewDataList::TT
std::vector< double > TT
Definition: PViewDataList.h:31
GModel::getEntities
void getEntities(std::vector< GEntity * > &entities, int dim=-1) const
Definition: GModel.cpp:651
getBoundaryFromMesh
static void getBoundaryFromMesh(GModel *m, int visible)
Definition: Skin.cpp:189
PViewDataList::NbVP
int NbVP
Definition: PViewDataList.h:26
PViewData
Definition: PViewData.h:29
MTriangle
Definition: MTriangle.h:26
TYPE_PYR
#define TYPE_PYR
Definition: GmshDefines.h:69
PViewDataList::NbSL
int NbSL
Definition: PViewDataList.h:28
TYPE_QUA
#define TYPE_QUA
Definition: GmshDefines.h:67
MEdge.h
discreteEdge.h
Context.h
GEntity::getMeshElement
virtual MElement * getMeshElement(std::size_t index) const
Definition: GEntity.h:363
PViewData::getNumComponents
virtual int getNumComponents(int step, int ent, int ele)
Definition: PViewData.h:152
PViewDataList::NbVL
int NbVL
Definition: PViewDataList.h:28
z
const double z
Definition: GaussQuadratureQuad.cpp:56
MQuadrangle.h
ElmData
Definition: Skin.cpp:46
ElmDataLessThan::tolerance
static double tolerance
Definition: Skin.cpp:149
GMSH_PostPlugin::getView
virtual PView * getView(int index, PView *view)
Definition: Plugin.cpp:81
GMSH_SkinPlugin::execute
PView * execute(PView *)
Definition: Skin.cpp:246
GMSH_PostPlugin::getPossiblyAdaptiveData
virtual PViewData * getPossiblyAdaptiveData(PView *view)
Definition: Plugin.cpp:94
PViewDataList::Time
std::vector< double > Time
Definition: PViewDataList.h:25
TYPE_HEX
#define TYPE_HEX
Definition: GmshDefines.h:71
ElmData::y
std::vector< double > y
Definition: Skin.cpp:49
TYPE_TET
#define TYPE_TET
Definition: GmshDefines.h:68
PViewDataList::NbTQ
int NbTQ
Definition: PViewDataList.h:32
SPoint3::z
double z(void) const
Definition: SPoint3.h:129
PViewData::getNumElements
virtual int getNumElements(int step=-1, int ent=-1)
Definition: PViewData.h:131
PViewDataList::NbVT
int NbVT
Definition: PViewDataList.h:30
PViewData::getName
virtual std::string getName()
Definition: PViewData.h:70
ElmData::x
std::vector< double > x
Definition: Skin.cpp:49
PViewDataList::NbVQ
int NbVQ
Definition: PViewDataList.h:32
PViewDataList::VT
std::vector< double > VT
Definition: PViewDataList.h:31
GEntity::dim
virtual int dim() const
Definition: GEntity.h:196
PViewDataList::SQ
std::vector< double > SQ
Definition: PViewDataList.h:33
GEntity::getVisibility
virtual char getVisibility()
Definition: GEntity.cpp:35
MElement::getNumEdges
virtual int getNumEdges() const =0
GMSH_SkinPlugin::getNbOptions
int getNbOptions() const
Definition: Skin.cpp:36
MQuadrangle
Definition: MQuadrangle.h:26
PViewDataList::NbST
int NbST
Definition: PViewDataList.h:30
GModel::current
static GModel * current(int index=-1)
Definition: GModel.cpp:136
ElmData::z
std::vector< double > z
Definition: Skin.cpp:49
GMSH_PostPlugin::getDataList
virtual PViewDataList * getDataList(PView *view, bool showError=true)
Definition: Plugin.cpp:107
Skin.h
PViewData::skipEntity
virtual bool skipEntity(int step, int ent)
Definition: PViewData.h:206
discreteFace
Definition: discreteFace.h:18
PViewData::getFirstNonEmptyTimeStep
virtual int getFirstNonEmptyTimeStep(int start=0)
Definition: PViewData.h:91