gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
MEdge.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 <algorithm>
7 #include "MEdge.h"
8 #include "Numeric.h"
9 #include "GmshDefines.h"
10 #include "ElementType.h"
11 #include "nodalBasis.h"
12 #include "BasisFactory.h"
13 
14 // FIXME
15 // remove that when MElementCut is removed
16 bool MEdge::isInside(MVertex *v) const
17 {
19  MVertex *v0 = _v[0];
20  MVertex *v1 = _v[1];
22  if(lt(v0, v1)) {
23  v0 = _v[1];
24  v1 = _v[0];
25  }
26  double x = v->x(), y = v->y(), z = v->z();
27  double x0 = v0->x(), y0 = v0->y(), z0 = v0->z();
28  double x1 = v1->x(), y1 = v1->y(), z1 = v1->z();
29  if(fabs(x - x0) < tol && fabs(y - y0) < tol && fabs(z - z0) < tol)
30  return true;
31  if(fabs(x - x1) < tol && fabs(y - y1) < tol && fabs(z - z1) < tol)
32  return true;
33  if(x < x0 - tol || x > x1 + tol || y < std::min(y0, y1) - tol ||
34  y > std::max(y0, y1) + tol || z < std::min(z0, z1) - tol ||
35  z > std::max(z0, z1) + tol)
36  return false;
37  if(fabs(x1 - x0) > tol) {
38  double tx = (x - x0) / (x1 - x0);
39  if(fabs(y1 - y0) > tol) {
40  double ty = (y - y0) / (y1 - y0);
41  if(fabs(z1 - z0) > tol) {
42  double tz = (z - z0) / (z1 - z0);
43  if(fabs(tx - ty) > tol || fabs(tx - tz) > tol) return false;
44  }
45  else {
46  if(fabs(tx - ty) > tol) return false;
47  }
48  }
49  else {
50  if(fabs(z1 - z0) > tol) {
51  double tz = (z - z0) / (z1 - z0);
52  if(fabs(tx - tz) > tol) return false;
53  }
54  }
55  }
56  else {
57  if(fabs(y1 - y0) > tol) {
58  double ty = (y - y0) / (y1 - y0);
59  if(fabs(z1 - z0) > tol) {
60  double tz = (z - z0) / (z1 - z0);
61  if(fabs(ty - tz) > tol) return false;
62  }
63  }
64  }
65  return true;
66 }
67 
68 bool SortEdgeConsecutive(const std::vector<MEdge> &e,
69  std::vector<std::vector<MVertex *> > &vs)
70 {
71  vs.clear();
72  if(e.empty()) return true;
73  std::map<MVertex *, std::pair<MVertex *, MVertex *>, MVertexPtrLessThan> c;
74 
75  for(size_t i = 0; i < e.size(); i++) {
76  MVertex *v0 = e[i].getVertex(0);
77  MVertex *v1 = e[i].getVertex(1);
78 
79  auto it0 = c.find(v0), it1 = c.find(v1);
80  if(it0 == c.end())
81  c[v0] = std::make_pair(v1, (MVertex *)nullptr);
82  else {
83  if(it0->second.second == nullptr) { it0->second.second = v1; }
84  else {
85  Msg::Debug("A list of edges has points that are adjacent to 3 edges");
86  return false;
87  }
88  }
89  if(it1 == c.end())
90  c[v1] = std::make_pair(v0, (MVertex *)nullptr);
91  else {
92  if(it1->second.second == nullptr) { it1->second.second = v0; }
93  else {
94  Msg::Debug("Wrong topology for a list of edges");
95  Msg::Debug("Node %d is adjacent to more than 2 nodes %d %d",
96  v1->getNum(), it1->second.first->getNum(),
97  it1->second.second->getNum());
98  return false;
99  }
100  }
101  }
102 
103  while(!c.empty()) {
104  std::vector<MVertex *> v;
105  MVertex *start = nullptr;
106  {
107  auto it = c.begin();
108  start = it->first;
109  for(; it != c.end(); ++it) {
110  if(it->second.second == nullptr) {
111  start = it->first;
112  break;
113  }
114  }
115  }
116 
117  auto its = c.find(start);
118 
119  MVertex *prev =
120  (its->second.second == start) ? its->second.first : its->second.second;
121  MVertex *current = start;
122 
123  do {
124  if(c.size() == 0) {
125  Msg::Warning("Wrong topology in a wire");
126  return false;
127  }
128  v.push_back(current);
129  auto it = c.find(current);
130  if(it == c.end() || it->first == nullptr) {
131  Msg::Error("Impossible to find %d", current->getNum());
132  return false;
133  }
134  MVertex *v1 = it->second.first;
135  MVertex *v2 = it->second.second;
136  c.erase(it);
137  MVertex *temp = current;
138  if(v1 == prev)
139  current = v2;
140  else if(v2 == prev)
141  current = v1;
142  else {
143  break;
144  }
145  prev = temp;
146  if(current == start) { v.push_back(current); }
147  } while(current != start && current != nullptr);
148  if(v.size() > 2 && v[v.size() - 2] == v[v.size() - 1]) {
149  v.erase(v.begin() + v.size() - 1);
150  }
151  vs.push_back(v);
152  }
153  return true;
154 }
155 
156 MEdgeN::MEdgeN(const std::vector<MVertex *> &v)
157 {
158  _v.resize(v.size());
159  for(std::size_t i = 0; i < v.size(); i++) _v[i] = v[i];
160 }
161 
162 MEdge MEdgeN::getEdge() const { return MEdge(_v[0], _v[1]); }
163 
164 SPoint3 MEdgeN::pnt(double u) const
165 {
167  const nodalBasis *fs = BasisFactory::getNodalBasis(tagLine);
168 
169  double f[100];
170  fs->f(u, 0, 0, f);
171 
172  double x = 0, y = 0, z = 0;
173  for(int i = 0; i < fs->getNumShapeFunctions(); i++) {
174  x += f[i] * _v[i]->x();
175  y += f[i] * _v[i]->y();
176  z += f[i] * _v[i]->z();
177  }
178  return SPoint3(x, y, z);
179 }
180 
181 SVector3 MEdgeN::tangent(double u) const
182 {
184  const nodalBasis *fs = BasisFactory::getNodalBasis(tagLine);
185 
186  double sf[100][3];
187  fs->df(u, 0, 0, sf);
188 
189  double dx = 0, dy = 0, dz = 0;
190  for(int i = 0; i < fs->getNumShapeFunctions(); i++) {
191  dx += sf[i][0] * _v[i]->x();
192  dy += sf[i][0] * _v[i]->y();
193  dz += sf[i][0] * _v[i]->z();
194  }
195  return SVector3(dx, dy, dz).unit();
196 }
197 
198 double MEdgeN::interpolate(const double val[], double u, int stride) const
199 {
201  const nodalBasis *fs = BasisFactory::getNodalBasis(tagLine);
202 
203  double f[100];
204  fs->f(u, 0, 0, f);
205 
206  double sum = 0;
207  for(int i = 0, k = 0; i < fs->getNumShapeFunctions(); i++, k += stride) {
208  sum += f[i] * val[k];
209  }
210  return sum;
211 }
MVertexPtrLessThan
Definition: MVertex.h:218
MEdgeN::interpolate
double interpolate(const double val[], double u, int stride=1) const
Definition: MEdge.cpp:198
MEdge
Definition: MEdge.h:14
TYPE_LIN
#define TYPE_LIN
Definition: GmshDefines.h:65
nodalBasis::df
virtual void df(double u, double v, double w, double grads[][3]) const =0
MEdgeN::getPolynomialOrder
int getPolynomialOrder() const
Definition: MEdge.h:146
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
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
MVertex
Definition: MVertex.h:24
nodalBasis.h
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
SPoint3
Definition: SPoint3.h:14
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
MVertex::getNum
std::size_t getNum() const
Definition: MVertex.h:86
SVector3
Definition: SVector3.h:16
MEdgeN::MEdgeN
MEdgeN()
Definition: MEdge.h:141
MEdgeN::_v
std::vector< MVertex * > _v
Definition: MEdge.h:138
SortEdgeConsecutive
bool SortEdgeConsecutive(const std::vector< MEdge > &e, std::vector< std::vector< MVertex * > > &vs)
Definition: MEdge.cpp:68
BasisFactory::getNodalBasis
static const nodalBasis * getNodalBasis(int tag)
Definition: BasisFactory.cpp:23
nodalBasis::f
virtual void f(double u, double v, double w, double *sf) const =0
ElementType::getType
int getType(int parentType, int order, bool serendip=false)
Definition: ElementType.cpp:757
Numeric.h
GmshDefines.h
MVertexPtrLessThanLexicographic
Definition: MVertex.h:210
SVector3::unit
SVector3 unit() const
Definition: SVector3.h:48
MVertexPtrLessThanLexicographic::getTolerance
static double getTolerance()
Definition: MVertex.cpp:410
MEdgeN::pnt
SPoint3 pnt(double u) const
Definition: MEdge.cpp:164
MEdge.h
nodalBasis
Definition: nodalBasis.h:12
MEdgeN::tangent
SVector3 tangent(double u) const
Definition: MEdge.cpp:181
z
const double z
Definition: GaussQuadratureQuad.cpp:56
MVertex::y
double y() const
Definition: MVertex.h:61
ElementType.h
MEdgeN::getEdge
MEdge getEdge() const
Definition: MEdge.cpp:162
MEdge::_v
MVertex * _v[2]
Definition: MEdge.h:16
nodalBasis::getNumShapeFunctions
virtual int getNumShapeFunctions() const =0
MEdge::isInside
bool isInside(MVertex *v) const
Definition: MEdge.cpp:16
MVertex::x
double x() const
Definition: MVertex.h:60
BasisFactory.h