G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsPeriodicParametrization.hpp
Go to the documentation of this file.
1 
16 
17 namespace gismo
18 {
19 
20 /* Nested class FlatMesh */
21 
22 template<class T>
24  const VertexHandle& h1,
25  real_t u) const
26 {
27  real_t u0 = (*h0)[0];
28  real_t u1 = (*h1)[0];
29  real_t v0 = (*h0)[1];
30  real_t v1 = (*h1)[1];
31 
32  real_t t = (u - u0) / (u1 - u0);
33 
34  return ((T)(1) - t) * v0 + t * v1;
35 }
36 
37 template<class T>
39  const VertexHandle& v0,
40  const VertexHandle& v1,
41  const VertexHandle& v2) const
42 {
43  // Note: v are in the input mesh, w in the output.
44 
45  typename gsMesh<T>::VertexHandle w0 = mesh.addVertex(v0->x(), v0->y());
46  typename gsMesh<T>::VertexHandle w2 = mesh.addVertex(v2->x(), v2->y());
47 
48  if(v1->x() < 0)
49  {
50  // Two triangles on the left.
51  typename gsMesh<T>::VertexHandle w01 = mesh.addVertex(0, correspondingV(v0, v1, 0));
52  typename gsMesh<T>::VertexHandle w12 = mesh.addVertex(0, correspondingV(v1, v2, 0));
53 
54  mesh.addFace(w0, w01, w12);
55  mesh.addFace(w0, w12, w2);
56 
57  // One triangle on the right.
58  typename gsMesh<T>::VertexHandle vvv01 = mesh.addVertex(1, correspondingV(v0, v1, 0));
59  typename gsMesh<T>::VertexHandle vvv12 = mesh.addVertex(1, correspondingV(v1, v2, 0));
60  typename gsMesh<T>::VertexHandle v1copy = mesh.addVertex(v1->x() + (T)(1), v1->y());
61  mesh.addFace(vvv01, v1copy, vvv12);
62  }
63  else if(v1->x() > 1)
64  {
65  // Two triangles on the left.
66  typename gsMesh<T>::VertexHandle w01 = mesh.addVertex(1, correspondingV(v0, v1, 1));
67  typename gsMesh<T>::VertexHandle w12 = mesh.addVertex(1, correspondingV(v1, v2, 1));
68 
69  mesh.addFace(w0, w01, w12);
70  mesh.addFace(w0, w12, w2);
71 
72  // One triangle on the right.
73  typename gsMesh<T>::VertexHandle vvv01 = mesh.addVertex(0, correspondingV(v0, v1, 1));
74  typename gsMesh<T>::VertexHandle vvv12 = mesh.addVertex(0, correspondingV(v1, v2, 1));
75  typename gsMesh<T>::VertexHandle v1copy = mesh.addVertex(v1->x() - (T)(1), v1->y());
76  mesh.addFace(vvv01, v1copy, vvv12);
77  }
78  else
79  gsWarn << "This situation of addThreeFlatTriangles should not happen, v1->x() = "
80  << v1->x() << "." << std::endl;
81 }
82 
83 template<class T>
85  const VertexHandle& v0,
86  const VertexHandle& v1,
87  const VertexHandle& v2) const
88 {
89  if(v0->x() < 0 && v2->x() < 0)
90  {
91  typename gsMesh<T>::VertexHandle w0 = mesh.addVertex(v0->x() + (T)(1), v0->y());
92  typename gsMesh<T>::VertexHandle w1 = mesh.addVertex(v1->x() + (T)(1), v1->y());
93  typename gsMesh<T>::VertexHandle w2 = mesh.addVertex(v2->x() + (T)(1), v2->y());
94  addThreeFlatTrianglesOneOut(mesh, w0, w1, w2);
95  }
96  else if(v0->x() > 1 && v2->x() > 1)
97  {
98  typename gsMesh<T>::VertexHandle w0 = mesh.addVertex(v0->x() - (T)(1), v0->y());
99  typename gsMesh<T>::VertexHandle w1 = mesh.addVertex(v1->x() - (T)(1), v1->y());
100  typename gsMesh<T>::VertexHandle w2 = mesh.addVertex(v2->x() - (T)(1), v2->y());
101  addThreeFlatTrianglesOneOut(mesh, w0, w1, w2);
102  }
103  else
104  gsWarn << "This situation of addThreeFlatTrianglesTwoOut should not happen, v1->x()="
105  << v1->x() << "." << std::endl;
106 }
107 
108 template<class T>
110  const typename gsMesh<T>::VertexHandle& v0,
111  const typename gsMesh<T>::VertexHandle& v1,
112  const typename gsMesh<T>::VertexHandle& v2) const
113 {
114  // Note: I wanted to solve this by modifying the x-coordinates of
115  // the vertex handles and recursion. However, this creates mess,
116  // as the vertex handles are shared among several triangles.
117  real_t v0x = v0->x();
118  real_t v1x = v1->x();
119  real_t v2x = v2->x();
120 
121  while(v0x > 1 && v1x > 1 && v2x > 1)
122  {
123  v0x -= 1;
124  v1x -= 1;
125  v2x -= 1;
126  }
127 
128  while(v0x < 0 && v1x < 0 && v2x < 0)
129  {
130  v0x += 1;
131  v1x += 1;
132  v2x += 1;
133  }
134 
135  if(v0x >= 0 && v0x <= 1 &&
136  v1x >= 0 && v1x <= 1 &&
137  v2x >= 0 && v2x <= 1)
138  {
139  mesh.addFace(
140  mesh.addVertex(v0x, v0->y()),
141  mesh.addVertex(v1x, v1->y()),
142  mesh.addVertex(v2x, v2->y()));
143  }
144  else
145  {
146  gsWarn << "This triangle does intersect the boundary.";
147  gsWarn << "v0: " << v0x << ", " << v0->y() << std::endl;
148  gsWarn << "v1: " << v1x << ", " << v1->y() << std::endl;
149  gsWarn << "v2: " << v2x << ", " << v2->y() << std::endl;
150  }
151 }
152 
153 template<class T>
155 {
156  gsMesh<T> result;
157 
158  for(size_t i=0; i<m_unfolded.getNumberOfTriangles(); i++)
159  {
160  // Remember the corners and which of them are inside the domain.
161  bool out[3];
162  typename gsMesh<T>::VertexHandle vh[3];
163  for(size_t j=1; j<=3; ++j)
164  {
165  vh[j-1] = m_unfolded.getVertex(m_unfolded.getGlobalVertexIndex(j, i));
166  real_t u = vh[j-1]->x();
167 
168  if(u < 0 || u > 1)
169  out[j-1] = true;
170  else
171  out[j-1] = false;
172  }
173  if( !out[0] && !out[1] && !out[2] )
174  addOneFlatTriangleNotIntersectingBoundary(result, vh[0], vh[1], vh[2]);
175 
176  else if( out[0] && !out[1] && out[2] )
177  addThreeFlatTrianglesTwoOut(result, vh[0], vh[1], vh[2]);
178  else if( out[0] && out[1] && !out[2] )
179  addThreeFlatTrianglesTwoOut(result, vh[1], vh[2], vh[0]);
180  else if( !out[0] && out[1] && out[2] )
181  addThreeFlatTrianglesTwoOut(result, vh[2], vh[0], vh[1]);
182 
183  else if( !out[0] && !out[1] && out[2] )
184  addThreeFlatTrianglesOneOut(result, vh[1], vh[2], vh[0]);
185  else if( !out[0] && out[1] && !out[2] )
186  addThreeFlatTrianglesOneOut(result, vh[0], vh[1], vh[2]);
187  else if( out[0] && !out[1] && !out[2] )
188  addThreeFlatTrianglesOneOut(result, vh[2], vh[0], vh[1]);
189 
190  else
191  addOneFlatTriangleNotIntersectingBoundary(result, vh[0], vh[1], vh[2]);
192  }
193  return result.cleanMesh();
194 }
195 
196 // back to implementing the main class
197 
198 template <class T>
199 void gsPeriodicParametrization<T>::restrictMatrices(gsMatrix<T>& uv, const gsMatrix<T>& xyz,
200  real_t uMin, real_t uMax) const
201 {
202  real_t uLength = uMax - uMin;
203  for(index_t j=0; j<uv.cols(); j++)
204  {
205  real_t u = uv(0, j);
206 
207  if(u < uMin)
208  uv(0, j) += uLength;
209  else if(u > uMax)
210  uv(0 ,j) -= uLength;
211  }
212 }
213 
214 template <class T>
215 void gsPeriodicParametrization<T>::initParameterPoints()
216 {
217  typedef typename gsParametrization<T>::Point2D Point2D;
218 
219  size_t n = this->m_mesh.getNumberOfInnerVertices();
220  size_t N = this->m_mesh.getNumberOfVertices();
221 
222  this->m_parameterPoints.reserve(N);
223  for (size_t i = 1; i <= n; i++)
224  this->m_parameterPoints.push_back(Point2D(0, 0, i));
225 
226  // Save the sizes as size_t to compare without warnings.
227  size_t v0size = m_paramsV0.cols();
228  size_t v1size = m_paramsV1.cols();
229  GISMO_ASSERT(m_indicesV0.size() == v0size, "Different sizes of u0.");
230  GISMO_ASSERT(m_indicesV1.size() == v1size, "Different sizes of u1.");
231  GISMO_ASSERT(v0size + v1size == this->m_mesh.getNumberOfBoundaryVertices(),
232  "Not prescribing all boundary points.");
233 
234  size_t numPtsSoFar = n;
235  this->m_parameterPoints.resize(n + v0size + v1size);
236 
237  // Set the parameter values on the v=0 boundary.
238  for(size_t i=0; i<v0size; i++)
239  this->m_parameterPoints[m_indicesV0[i]-1] = Point2D(m_paramsV0(0, i), 0, numPtsSoFar++);
240 
241  // Set the parameter values on the v=1 boundary.
242  for(size_t i=0; i<v1size; i++)
243  this->m_parameterPoints[m_indicesV1[i]-1] = Point2D(m_paramsV1(0, i), 1, numPtsSoFar++);
244 }
245 
246 } // namespace gismo
real_t correspondingV(const VertexHandle &v0, const VertexHandle &v1, real_t u) const
Definition: gsPeriodicParametrization.hpp:23
#define index_t
Definition: gsConfig.h:32
gsMesh< T > createRestrictedFlatMesh() const
Trims the mesh to [0, 1]^2.
Definition: gsPeriodicParametrization.hpp:154
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Class Representing a triangle mesh with 3D vertices.
Definition: gsMesh.h:31
gsMesh & cleanMesh()
reorders the vertices of all faces of an .stl mesh, such that only 1 vertex is used instead of #(adja...
Definition: gsMesh.hpp:250
#define gsWarn
Definition: gsDebug.h:50
void addOneFlatTriangleNotIntersectingBoundary(gsMesh< T > &mesh, const VertexHandle &v0, const VertexHandle &v1, const VertexHandle &v2) const
Adds a flat triangle and shifts it inside the domain if necessary.
Definition: gsPeriodicParametrization.hpp:109
T x() const
Definition: gsVertex.h:108
T y() const
Definition: gsVertex.h:110
void addThreeFlatTrianglesOneOut(gsMesh< T > &mesh, const VertexHandle &v0, const VertexHandle &v1, const VertexHandle &v2) const
Definition: gsPeriodicParametrization.hpp:38
Abstract class with the functionality common to gsPeriodicStitch and gsPeriodicOverlap.
void addThreeFlatTrianglesTwoOut(gsMesh< T > &mesh, const VertexHandle &v0, const VertexHandle &v1, const VertexHandle &v2) const
Definition: gsPeriodicParametrization.hpp:84
gsVertex class that represents a 3D vertex for a gsMesh.
Definition: gsVertex.h:26