DFNgen  2.0
DFN Model Generator
domain.cpp
Go to the documentation of this file.
1 #include <cmath>
2 #include <vector>
3 #include "domain.h"
4 #include "input.h"
5 #include "structures.h"
6 #include "vectorFunctions.h"
7 
8 /******************************************************************************/
9 /*********************** Domain Truncation **********************************/
10 // NOTE: domainTruncation() may benefit from rewriting in a more
11 // efficient way which does not reallocate memory as often
12 // Truncates polygons along the defined domain ('domainSize' in input file)
13 // Arg 1: Polygon being truncated (if truncation is necessary)
14 // Arg 2: Point to domain size array, 3 doubles: {x, y, z}
15 // Return: 0 - If Poly is inside domain and was truncated to more than 2 vertices,
16 // of poly truncation was not needed
17 // 1 - If rejected due to being outside the domain or was truncated to
18 // less than 3 vertices
19 bool domainTruncation(Poly &newPoly, double *domainSize) {
20 
21  std::vector<double> points;
22  points.reserve(18); // Initialize with enough room for 6 vertices
23  int nNodes;
24 
25  double domainX = domainSize[0]*.5;
26  double domainY = domainSize[1]*.5;
27  double domainZ = domainSize[2]*.5;
28 
29  int stop = newPoly.numberOfNodes;
30 
31  // Check if truncation is necessay:
32  for (int k = 0; k < stop; k++) {
33  int idx = k*3;
34  if (newPoly.vertices[idx] > domainX || newPoly.vertices[idx] < -domainX) break;
35  if (newPoly.vertices[idx+1] > domainY || newPoly.vertices[idx+1] < -domainY) break;
36  if (newPoly.vertices[idx+2] > domainZ || newPoly.vertices[idx+2] < -domainZ) break;
37 
38  // If finished checking last node and code still hasn't broke
39  // from the for loop, then all nodes are inside domain
40  if (k + 1 == stop) {
41  return 0;
42  }
43  }
44 
45  // If code does not return above, truncation is needed/
46  newPoly.truncated = 1; // Mark poly as truncated
47 
48  int nVertices; // Same as newPoly.numberOfNodes;
49  double ntmp[3]; // Normal of domain side
50  double pttmp[3]; // Center point on domain side
51 
52  // Check against the all the walls of the domain
53  for ( int j = 0; j < 6; j++) {
54 
55  switch(j) {
56  case 0:
57  ntmp[0] = 0; ntmp[1] = 0; ntmp[2] = 1;
58  pttmp[0] = 0; pttmp[1] = 0; pttmp[2] = domainZ;
59  break;
60  case 1:
61  ntmp[0] = 0; ntmp[1] = 0; ntmp[2] = -1;
62  pttmp[0] = 0; pttmp[1] = 0; pttmp[2] = -domainZ;
63  break;
64  case 2:
65  ntmp[0] = 0; ntmp[1] = 1; ntmp[2] = 0;
66  pttmp[0] = 0; pttmp[1] = domainY; pttmp[2] = 0;
67  break;
68  case 3:
69  ntmp[0] = 0; ntmp[1] = -1; ntmp[2] = 0;
70  pttmp[0] = 0; pttmp[1] = -domainY; pttmp[2] = 0;
71  break;
72  case 4:
73  ntmp[0] = 1; ntmp[1] = 0; ntmp[2] = 0;
74  pttmp[0] = domainX; pttmp[1] = 0; pttmp[2] = 0;
75  break;
76  case 5:
77  ntmp[0] = -1; ntmp[1] = 0; ntmp[2] = 0;
78  pttmp[0] = -domainX; pttmp[1] = 0; pttmp[2] = 0;
79  break;
80  }
81 
82  nVertices = newPoly.numberOfNodes;
83  if(nVertices <= 0) {
84  return 1; // Reject
85  }
86 
87  nNodes = 0; // Counter for final number of nodes
88  points.clear(); // Clear any points from last iteration
89 
90 
91  int last = (nVertices-1)*3; // Index to last node starting position in array
92  double temp[3];
93  temp[0] = newPoly.vertices[last] - pttmp[0]; //x
94  temp[1] = newPoly.vertices[last+1] - pttmp[1]; //y
95  temp[2] = newPoly.vertices[last+2] - pttmp[2]; //z
96 
97  // Previous distance - the dot product of the domain side normal
98  // and the distance between vertex number nVertices and the temp point on the
99  // domain side.
100  double prevdist = dotProduct(temp, ntmp);
101 
102  for (int i = 0; i < nVertices; i++) {
103  int index = i*3;
104  temp[0] = newPoly.vertices[index] - pttmp[0];
105  temp[1] = newPoly.vertices[index+1] - pttmp[1];
106  temp[2] = newPoly.vertices[index+2] - pttmp[2];
107 
108  // Current distance, the dot product of domain side normal and
109  // the distance between the ii'th vertex and the temporary point
110  double currdist = dotProduct(temp, ntmp);
111 
112  if (currdist <= 0) { // if vertex is towards the domain relative to the domain side
113  // Save vertex
114  points.push_back(newPoly.vertices[index]); // x
115  points.push_back(newPoly.vertices[index+1]); // y
116  points.push_back(newPoly.vertices[index+2]); // z
117  nNodes++;
118  }
119 
120  if (currdist * prevdist < 0) { //if crosses boundary
121 
122  nNodes++;
123 
124  if (i == 0) { // Store point on boundary
125  // 'last' is index to last vertice
126  temp[0] = newPoly.vertices[last]
127  + (newPoly.vertices[0] - newPoly.vertices[last])
128  * std::abs(prevdist)/(std::abs(currdist)+std::abs(prevdist));
129  temp[1] = newPoly.vertices[last+1]
130  + (newPoly.vertices[1] - newPoly.vertices[last+1])
131  * std::abs(prevdist)/(std::abs(currdist)+std::abs(prevdist));
132  temp[2] = newPoly.vertices[last+2]
133  + (newPoly.vertices[2] - newPoly.vertices[last+2])
134  * std::abs(prevdist)/(std::abs(currdist)+std::abs(prevdist));
135  points.push_back(temp[0]);
136  points.push_back(temp[1]);
137  points.push_back(temp[2]);
138  }
139  else {
140 
141  // If from outside to inside
142  temp[0] = newPoly.vertices[index-3]
143  + (newPoly.vertices[index] - newPoly.vertices[index-3])
144  * std::abs(prevdist) / (std::abs(currdist)+std::abs(prevdist));
145  temp[1] = newPoly.vertices[index-2]
146  + (newPoly.vertices[index+1] - newPoly.vertices[index-2])
147  * std::abs(prevdist) / (std::abs(currdist)+std::abs(prevdist));
148  temp[2] = newPoly.vertices[index-1]
149  + (newPoly.vertices[index+2] - newPoly.vertices[index-1])
150  * std::abs(prevdist) / (std::abs(currdist)+std::abs(prevdist));
151  points.reserve(points.size()+3); // Resize vector if needed
152 
153  points.push_back(temp[0]);
154  points.push_back(temp[1]);
155  points.push_back(temp[2]);
156  }
157  if (currdist < 0) { // If from outside to inside - swap order
158 
159  int tmpIndex = (nNodes-1)*3; // Index to last saved point
160  points[tmpIndex] = points[tmpIndex - 3];
161  points[tmpIndex+1] = points[tmpIndex - 2];
162  points[tmpIndex+2] = points[tmpIndex - 1];
163  points[tmpIndex-3] = temp[0];
164  points[tmpIndex-2] = temp[1];
165  points[tmpIndex-1] = temp[2];
166  }
167  }
168 
169  prevdist = currdist;
170 
171  } // End vertice loops
172 
173  newPoly.numberOfNodes = nNodes;
174 
175  if (nNodes > 0) {
176 
177  delete[] newPoly.vertices;
178 
179  newPoly.vertices = new double[3*nNodes];
180 
181  // Copy new nodes back to newPoly
182  for (int k = 0; k < nNodes; k++) {
183  int idxx = k*3;
184  newPoly.vertices[idxx] = points[idxx];
185  newPoly.vertices[idxx+1] = points[idxx+1];
186  newPoly.vertices[idxx+2] = points[idxx+2];
187  }
188  }
189  } // End main loop
190 
191  int i = 0;
192 
193  while (i < nNodes) {
194  int next;
195  double temp[3];
196  int idx = i*3;
197 
198  if(i == nNodes-1){ // If last node
199  next = 0;
200  }
201  else {
202  next = (i+1)*3;
203  }
204 
205  temp[0] = newPoly.vertices[idx] - newPoly.vertices[next];
206  temp[1] = newPoly.vertices[idx+1] - newPoly.vertices[next+1];
207  temp[2] = newPoly.vertices[idx+2] - newPoly.vertices[next+2];
208 
209  if (magnitude(temp[0], temp[1], temp[2]) < (2*h)) { // If distance between current and next vertex < h
210  // If point is NOT on a boundary, delete current indexed point, ELSE delete next point
211  if ( std::abs(std::abs(newPoly.vertices[idx])-domainX) > eps && std::abs(std::abs(newPoly.vertices[idx+1])-domainY) > eps && std::abs(std::abs(newPoly.vertices[idx+2])-domainZ) > eps ) {
212 
213  // Loop deletes a vertice by shifting elements to the right of the element, to the left
214  for (int j = i; j < nNodes-1 ; j++) {
215  int idx = j*3;
216  newPoly.vertices[idx] = newPoly.vertices[idx+3]; // Shift x coordinate left
217  newPoly.vertices[idx+1] = newPoly.vertices[idx+4]; // Shift y coordinate left
218  newPoly.vertices[idx+2] = newPoly.vertices[idx+5]; // Shift z coordinate left
219  }
220  }
221  else {
222  // Loop deletes a vertice by shifting elements to the right of the element to the left
223  int end = (nNodes-1)*3;
224  for (int j = next; j < end; j += 3){
225  newPoly.vertices[j] = newPoly.vertices[j+3]; // Shift x coordinate left
226  newPoly.vertices[j+1] = newPoly.vertices[j+4]; // Shift y coordinate left
227  newPoly.vertices[j+2] = newPoly.vertices[j+5]; // Shift z coordinate left
228  }
229  }
230  nNodes--; // Update node counter
231  }
232  else {
233  i++;
234  }
235  } // End while loop
236 
237 
238  if(nNodes < 3) {
239  return 1; // Reject
240  }
241 
242  newPoly.numberOfNodes = nNodes;
243 
244  int temp = newPoly.numberOfNodes;
245  for (int k = 0; k < temp; k++){
246  // Check boundary faces
247  // Update which boundaries newPoly touches
248 
249  int idx = k*3;
250  if (newPoly.vertices[idx] >= domainX-eps) {
251  newPoly.faces[0] = 1;
252  }
253  else if (newPoly.vertices[idx] <= -domainX+eps) {
254  newPoly.faces[1] = 1;
255  }
256 
257  if (newPoly.vertices[idx+1] >= domainY-eps) {
258  newPoly.faces[2] = 1;
259  }
260  else if (newPoly.vertices[idx+1] <= -domainY+eps) {
261  newPoly.faces[3] = 1;
262  }
263 
264  if (newPoly.vertices[idx+2] >= domainZ-eps) {
265  newPoly.faces[4] = 1;
266  }
267  else if (newPoly.vertices[idx+2] <= -domainZ+eps) {
268  newPoly.faces[5] = 1;
269  }
270  }
271  return 0;
272 }
273 
274 
275 /******************************************************************/
276 /***************** Debug Print Function *************************/
277 // Prints a vector<Point> array to screen
278 // Arg 1: Vector<Point> array
279 void printPoints(std::vector<double> &point){
280 
281  for (unsigned int i = 0; i < point.size(); i++) {
282  if (i != 0 && i % 3 == 0){
283  std::cout<<"\n";
284  }
285  std::cout<<point[i]<<" ";
286  }
287  std::cout<<std::endl;
288 }
289 
290 
T magnitude(T x, T y, T z)
bool truncated
Definition: structures.h:95
int numberOfNodes
Definition: structures.h:14
double eps
Definition: DFNmain.cpp:39
double * vertices
Definition: structures.h:70
T dotProduct(const T *A, const T *B)
bool domainTruncation(Poly &newPoly, double *domainSize)
Definition: domain.cpp:19
void printPoints(std::vector< double > &point)
Definition: domain.cpp:279
double domainSize[3]
Definition: readInput.cpp:18
double h
Definition: readInput.cpp:21
bool faces[6]
Definition: structures.h:84