rsvs3D  0.0.0
Codes for the c++ implementation of the 3D RSVS
meshrefinement.cpp
1 #include "meshrefinement.hpp"
2 
3 #include <cmath>
4 #include <iostream>
5 
6 #include "mesh.hpp"
7 #include "warning.hpp"
8 
9 using namespace std;
10 
11 void CoarsenMesh(const mesh &meshchild, mesh &newparent, const vector<int> &elmMapping)
12 {
13  int ii, n = 0, nDim;
14  bool flag = true;
15  HashedVector<int, int> hashedMapping;
16  vector<int> indRmvVert, indRmvEdge, indRmvSurf, indRmvVolu;
17 
18  newparent = meshchild;
19  nDim = newparent.WhatDim();
20  // Check Validity of elmMapping (that all the volumes already exist)
21 
22  switch (newparent.WhatDim())
23  {
24  case 0: // verts
25  RSVS3D_ERROR_ARGUMENT("unhandled dimension");
26  break;
27  case 1: // edges
28  RSVS3D_ERROR_ARGUMENT("unhandled dimension");
29  break;
30  case 2: // surfs
31  n = int(newparent.surfs.size());
32  flag = false;
33  flag = n != int(elmMapping.size());
34  if (!flag)
35  {
36  for (ii = 0; ii < n; ii++)
37  {
38  if (newparent.surfs.find(elmMapping[ii]) == -1)
39  {
40  flag = true;
41  break;
42  }
43  }
44  }
45  break;
46  case 3: // volumes
47  n = int(newparent.volus.size());
48  flag = false;
49  flag = n != int(elmMapping.size());
50  if (!flag)
51  {
52  for (ii = 0; ii < n; ii++)
53  {
54  if (newparent.volus.find(elmMapping[ii]) == -1)
55  {
56  flag = true;
57  break;
58  }
59  }
60  }
61  break;
62  default:
63  RSVS3D_ERROR_ARGUMENT("Dimensionality too high.");
64  break;
65  }
66 
67  if (flag)
68  {
69  RSVS3D_ERROR_ARGUMENT("Element mapping and mesh did not match");
70  }
71 
72  // Switch element indices according to elmMapping
73  // This is an error here as there can be index collision
74  switch (nDim)
75  {
76  case 0:
77  for (ii = 0; ii < n; ii++)
78  {
79  newparent.SwitchIndex(nDim + 1, newparent.verts(ii)->index, elmMapping[ii]);
80  }
81  break;
82  case 1:
83  for (ii = 0; ii < n; ii++)
84  {
85  newparent.SwitchIndex(nDim + 1, newparent.edges(ii)->index, elmMapping[ii]);
86  }
87  break;
88  case 2:
89  for (ii = 0; ii < n; ii++)
90  {
91  newparent.SwitchIndex(nDim + 1, newparent.surfs(ii)->index, elmMapping[ii]);
92  }
93  break;
94  case 3:
95  for (ii = 0; ii < n; ii++)
96  {
97  newparent.SwitchIndex(nDim + 1, newparent.volus(ii)->index, elmMapping[ii]);
98  }
99  break;
100  }
101  newparent.TightenConnectivity();
102 
103  // Identify Surfs, edges and verts to remove after merging of the higher order
104  // elements
107  if (nDim >= 3)
108  {
109  for (ii = 0; ii < newparent.surfs.size(); ++ii)
110  {
111  if (newparent.surfs(ii)->voluind[0] == newparent.surfs(ii)->voluind[1])
112  {
113  newparent.RemoveIndex(3, newparent.surfs(ii)->index);
114  indRmvSurf.push_back(newparent.surfs(ii)->index);
115  }
116  }
117  }
118  if (nDim >= 2)
119  {
120  if (nDim == 2)
121  {
122  for (ii = 0; ii < newparent.edges.size(); ++ii)
123  {
124  if (newparent.edges(ii)->surfind.size() == 1)
125  {
126  newparent.RemoveIndex(2, newparent.edges(ii)->index);
127  indRmvEdge.push_back(newparent.edges(ii)->index);
128  }
129  }
130  }
131  else
132  {
133  for (ii = 0; ii < newparent.edges.size(); ++ii)
134  {
135  if (newparent.edges(ii)->surfind.size() == 0)
136  {
137  newparent.RemoveIndex(2, newparent.edges(ii)->index);
138  indRmvEdge.push_back(newparent.edges(ii)->index);
139  }
140  }
141  }
142  }
143  if (nDim >= 1)
144  {
145  for (ii = 0; ii < newparent.verts.size(); ++ii)
146  {
147  if (newparent.verts(ii)->edgeind.size() == 0)
148  {
149  indRmvVert.push_back(newparent.verts(ii)->index);
150  }
151  }
152  }
154 
155  // Build list of elements to remove
156  hashedMapping.vec = elmMapping;
157  hashedMapping.GenerateHash();
158 
159  switch (nDim)
160  {
161  case 0:
162  break;
163  case 1:
164  break;
165  case 2:
166  for (ii = 0; ii < n; ++ii)
167  {
168  if (hashedMapping.find(newparent.surfs(ii)->index) == -1)
169  {
170  indRmvSurf.push_back(newparent.surfs(ii)->index);
171  }
172  }
173  break;
174  case 3:
175  for (ii = 0; ii < n; ++ii)
176  {
177  if (hashedMapping.find(newparent.volus(ii)->index) == -1)
178  {
179  indRmvVolu.push_back(newparent.volus(ii)->index);
180  }
181  }
182  break;
183  }
184 
185  // Remove elements
186  sort(indRmvVert);
187  sort(indRmvEdge);
188  sort(indRmvSurf);
189  sort(indRmvVolu);
190  unique(indRmvVert);
191  unique(indRmvEdge);
192  unique(indRmvSurf);
193  unique(indRmvVolu);
194  newparent.surfs.remove(indRmvSurf);
195  newparent.edges.remove(indRmvEdge);
196  newparent.verts.remove(indRmvVert);
197  newparent.volus.remove(indRmvVolu);
198 
199  newparent.PrepareForUse();
200 }
201 
202 void CartesianMapping(const mesh &meshin, vector<int> &elmMapping, vector<int> &dims)
203 {
204  int ii, jj, kk, n, nBox, sub;
205  coordvec minCoord, maxCoord, cellCoord, deltaCoord;
206  vector<int> boxMap, vertList, edgeList;
207 
208  n = meshin.verts.size();
209  // Define bounds;
210  minCoord = meshin.verts(0)->coord;
211  maxCoord = meshin.verts(0)->coord;
212  for (ii = 1; ii < n; ii++)
213  {
214  minCoord.min(meshin.verts(ii)->coord);
215  maxCoord.max(meshin.verts(ii)->coord);
216  }
217  deltaCoord = maxCoord;
218  deltaCoord.substract(minCoord.usedata());
219  // integer vector for each possible locations based on dim split
220  nBox = 1;
221  for (ii = 0; ii < 3; ++ii)
222  {
223  dims[ii] = dims[ii] > 0 ? dims[ii] : 1;
224  deltaCoord[ii] = dims[ii] > 0 ? deltaCoord[ii] : 2;
225  minCoord[ii] = dims[ii] > 0 ? minCoord[ii] : minCoord[ii] - 1;
226  maxCoord[ii] = dims[ii] > 0 ? maxCoord[ii] : maxCoord[ii] + 1;
227  nBox = nBox * dims[ii];
228  }
229  boxMap.assign(nBox, 0);
230  elmMapping.clear();
231  if (meshin.WhatDim() == 3)
232  {
233  elmMapping.assign(meshin.volus.size(), 0);
234  // Go through volumes calculating their location find which box it fits in
235  n = meshin.volus.size();
236  for (ii = 0; ii < n; ii++)
237  {
238  edgeList =
239  ConcatenateVectorField(meshin.surfs, &surf::edgeind, meshin.surfs.find_list(meshin.volus(ii)->surfind));
240  vertList = ConcatenateVectorField(meshin.edges, &edge::vertind, meshin.edges.find_list(edgeList));
241  vertList = meshin.verts.find_list(vertList);
242  sort(vertList);
243  unique(vertList);
244  kk = int(vertList.size());
245  cellCoord.assign(0.0, 0.0, 0.0);
246  for (jj = 0; jj < kk; ++jj)
247  {
248  cellCoord.add(meshin.verts(vertList[jj])->coord);
249  }
250  cellCoord.div(double(kk));
251 
252  cellCoord.substract(minCoord.usedata());
253  cellCoord.div(deltaCoord.usedata());
254  for (jj = 0; jj < 3; ++jj)
255  {
256  cellCoord[jj] = cellCoord[jj] * double(dims[jj]);
257  cellCoord[jj] = floor(cellCoord[jj]);
258  cellCoord[jj] = (cellCoord[jj] >= double(dims[jj])) ? double(dims[jj] - 1) : cellCoord[jj];
259  }
260  sub = int(cellCoord[0]) + (dims[0]) * int(cellCoord[1]) + (dims[0]) * (dims[1]) * int(cellCoord[2]);
261  if (sub >= nBox)
262  {
263  RSVS3D_ERROR_ARGUMENT("sub was larger than available size");
264  }
265  if (boxMap[sub] == 0)
266  {
267  // if the box as never been explored put the index in it
268  boxMap[sub] = meshin.volus(ii)->index;
269  elmMapping[ii] = boxMap[sub];
270  }
271  else
272  {
273  // put the number of the box in the elmMapping
274  elmMapping[ii] = boxMap[sub];
275  }
276  }
277  }
278  else if (meshin.WhatDim() == 2)
279  {
280  elmMapping.assign(meshin.surfs.size(), 0);
281  // Go through volumes calculating their location find which box it fits in
282  n = meshin.surfs.size();
283  for (ii = 0; ii < n; ii++)
284  {
285  vertList =
286  ConcatenateVectorField(meshin.edges, &edge::vertind, meshin.edges.find_list(meshin.surfs(ii)->edgeind));
287  vertList = meshin.verts.find_list(vertList);
288  sort(vertList);
289  unique(vertList);
290  kk = int(vertList.size());
291  cellCoord.assign(0.0, 0.0, 0.0);
292  for (jj = 0; jj < kk; ++jj)
293  {
294  cellCoord.add(meshin.verts(vertList[jj])->coord);
295  }
296  cellCoord.div(double(kk));
297 
298  cellCoord.substract(minCoord.usedata());
299  cellCoord.div(deltaCoord.usedata());
300  for (jj = 0; jj < 3; ++jj)
301  {
302  cellCoord[jj] = cellCoord[jj] * double(dims[jj]);
303  cellCoord[jj] = floor(cellCoord[jj]);
304  cellCoord[jj] = (cellCoord[jj] >= double(dims[jj])) ? double(dims[jj] - 1) : cellCoord[jj];
305  }
306  sub = int(cellCoord[0]) + (dims[0]) * int(cellCoord[1]) + (dims[0]) * (dims[1]) * int(cellCoord[2]);
307  if (sub >= nBox)
308  {
309  RSVS3D_ERROR_ARGUMENT("sub was larger than available size");
310  }
311  if (boxMap[sub] == 0)
312  {
313  // if the box as never been explored put the index in it
314  boxMap[sub] = meshin.surfs(ii)->index;
315  elmMapping[ii] = boxMap[sub];
316  }
317  else
318  {
319  // put the number of the box in the elmMapping
320  elmMapping[ii] = boxMap[sub];
321  }
322  }
323  }
324 }
Handles the use and norm of a vector for which the norm and the unit value might be needed.
Definition: mesh.hpp:114
Class for mesh handling.
Definition: mesh.hpp:592
Provides all the mesh tools used for the generation of 3D grids and geometries.
Tools for the refinement and coarsening of meshes.
void CoarsenMesh(const mesh &meshchild, mesh &newparent, const std::vector< int > &elmMapping)
Provides the error and warning system used by the RSVS3D project.
#define RSVS3D_ERROR_ARGUMENT(M)
Throw a invalid_argument.
Definition: warning.hpp:148