25 int BuildBlockGrid(std::array<int, 3> &dimGrid,
mesh &blockGrid)
28 Eigen::RowVector3i dimGridEig;
32 for (
int i = 0; i < 3; ++i)
34 dimGridEig[i] = dimGrid[i];
37 out = BuildBlockGrid(dimGridEig, blockGrid);
42 int BuildBlockGrid(
const Eigen::RowVector3i &dimGrid,
mesh &blockGrid)
44 int nVolu, nVert, nSurf, nEdge;
45 Eigen::RowVector3i nSurfDim, nEdgeDim;
46 Eigen::Matrix3i surfProp, edgeProp;
51 nVolu = dimGrid.prod();
52 nVert = (dimGrid.array() + 1).prod();
54 surfProp = (Eigen::MatrixXi::Identity(3, 3)).rowwise().reverse();
55 edgeProp = (1 - Eigen::MatrixXi::Identity(3, 3).array());
57 nSurfDim = ((dimGrid.colwise().replicate(3).array()) + surfProp.array()).rowwise().prod();
58 nEdgeDim = ((dimGrid.colwise().replicate(3).array()) + edgeProp.array()).rowwise().prod();
60 nSurf = nSurfDim.sum();
61 nEdge = nEdgeDim.sum();
63 blockGrid.Init(nVert, nEdge, nSurf, nVolu);
66 cout <<
"nVert: " << nVert <<
" nVolu: " << nVolu <<
" nEdge: " << nEdge <<
" nSurf: " << nSurf << endl;
67 cout <<
"surfProp: " << endl << surfProp << endl;
68 cout <<
"edgeProp: " << endl << edgeProp << endl;
69 cout <<
"nSurfDim: " << endl << nSurfDim << endl;
70 cout <<
"nEdgeDim: " << endl << nEdgeDim << endl;
76 cout <<
"cumprod(nSurfDim): " << endl <<
cumprod(nSurfDim, 0) << endl;
77 cout <<
"nSurfDim: " << endl << nSurfDim << endl;
78 cout <<
"cumsum(nSurfDim): " << endl <<
cumsum(nSurfDim, 0) << endl;
79 cout <<
"nSurfDim: " << endl << nSurfDim << endl;
80 cout <<
"cumsum(surfProp) : " << endl <<
cumsum(surfProp, 0) << endl;
81 cout <<
"cumprod(edgeProp): " << endl <<
cumprod(edgeProp, 0) << endl;
82 cout <<
"edgeProp: " << endl << edgeProp << endl;
83 cout <<
"cumsum(edgeProp')'' : " << endl <<
cumsum(edgeProp, 1) << endl;
84 cout <<
"edgeProp: " << endl << edgeProp << endl;
85 cout <<
"cumprod(edgeProp')': " << endl <<
cumprod(edgeProp, 1) << endl;
86 cout <<
"edgeProp: " << endl << edgeProp << endl;
87 cout << endl <<
"------------------------" << endl << endl;
90 BuildBlockVolu(dimGrid, nVolu, blockGrid, nSurfDim, surfProp);
91 BuildBlockSurf(dimGrid, nSurf, blockGrid, surfProp, edgeProp, nSurfDim, nEdgeDim);
92 BuildBlockEdge(dimGrid, blockGrid, nEdge, nEdgeDim, nSurfDim, edgeProp, surfProp);
93 BuildBlockVert(dimGrid, blockGrid, nVert, edgeProp, nEdgeDim);
95 blockGrid.PrepareForUse();
96 blockGrid.TightenConnectivity();
97 blockGrid.OrderEdges();
102 int BuildBlockVolu(
const Eigen::RowVector3i &dimGrid,
int nVolu,
mesh &blockGrid,
const Eigen::RowVector3i &nSurfDim,
103 const Eigen::Matrix3i &surfProp)
105 Eigen::RowVector3i incrSurf, pos;
106 Eigen::Matrix3i matSurf;
107 Eigen::Matrix<int, 3, 3> incPos;
108 Eigen::Matrix<int, 6, 1> incrSurf2, tempSurfInd;
111 matSurf = (dimGrid.colwise().replicate(3).array()) + surfProp.array();
113 incrSurf << 0, nSurfDim.head<2>();
114 incrSurf =
cumsum(incrSurf, 0);
115 incrSurf2 << incrSurf.rowwise().replicate(2).transpose();
117 incPos << Eigen::Matrix<int, 3, 1>::Ones(), matSurf.leftCols<2>();
122 for (
int ii = 0; ii < nVolu; ++ii)
124 blockGrid.volus[ii].index = ii + 1;
125 blockGrid.volus[ii].fill = double(rand() % 1000 + 1) / 1000.0;
127 pos(0) = ii % (dimGrid(0));
128 pos(1) = int(floor(
float(ii) /
float(dimGrid(0)))) % (dimGrid(1));
129 pos(2) = int(floor(
double(ii) /
double(dimGrid(0) * dimGrid(1)))) % dimGrid(2);
131 tempSurfInd.head<3>() = pos.colwise().replicate(3).cwiseProduct(incPos).rowwise().sum();
132 tempSurfInd.tail<3>() = (pos.colwise().replicate(3) + surfProp).cwiseProduct(incPos).rowwise().sum();
133 tempSurfInd = (tempSurfInd + incrSurf2).array() + 1;
135 blockGrid.volus[ii].surfind.assign(tempSurfInd.size(), 0);
136 for (jj = 0; jj < tempSurfInd.size(); jj++)
138 blockGrid.volus[ii].surfind[jj] = tempSurfInd(jj);
142 #ifdef TEST_VOXEL_VOLU
143 cout <<
"--------------------------------------------" << endl <<
"Test BuildBlockVolu" << endl;
144 cout <<
"matSurf: " << endl << matSurf << endl;
145 cout <<
"incrSurf: " << endl << incrSurf << endl;
146 cout <<
"incrSurf2: " << endl << incrSurf2 << endl;
147 cout <<
"incPos: " << endl << incPos << endl;
148 cout <<
"tempSurfInd: " << endl << tempSurfInd << endl;
149 blockGrid.volus.disp();
155 int BuildBlockSurf(
const Eigen::RowVector3i &dimGrid,
int nSurf,
mesh &blockGrid,
const Eigen::Matrix3i &surfProp,
156 const Eigen::Matrix3i &edgeProp,
const Eigen::RowVector3i &nSurfDim,
157 const Eigen::RowVector3i &nEdgeDim)
162 Eigen::RowVector3i incrSurf, incrEdge, cumSurfDim, dimGridCur, pos, cumProdDimGrid, ind;
163 Eigen::Matrix<bool, 1, 3> maskVec;
164 Eigen::RowVector2i currDim;
165 Eigen::Matrix3i matSurf, matEdge;
166 Eigen::Matrix<int, 3, 3> incPos;
167 Eigen::Matrix<int, 6, 1> incrSurf2;
168 Eigen::Matrix<int, 4, 3> mask, incPosTemp;
169 Eigen::Matrix<int, 4, 1> tempEdgeInd, incrEdge2;
170 int isFill, jPlane, boundaryFlag, jj, kk;
173 matSurf = (dimGrid.colwise().replicate(3).array()) + surfProp.array();
174 matEdge = (dimGrid.colwise().replicate(3).array()) + edgeProp.array();
176 incrSurf << 0, nSurfDim.head<2>();
177 incrSurf =
cumsum(incrSurf, 0);
178 incrSurf2 << incrSurf.rowwise().replicate(2).transpose();
180 incrEdge << 0, nEdgeDim.head<2>();
181 incrEdge =
cumsum(incrEdge, 0);
183 incPos << Eigen::Matrix<int, 3, 1>::Ones(), matEdge.leftCols<2>();
186 cumSurfDim =
cumsum(nSurfDim, 0);
188 cumProdDimGrid << 1, dimGrid.head(2);
189 cumProdDimGrid =
cumprod(cumProdDimGrid, 0);
190 isFill = 1 - (dimGrid.all());
193 for (
int ii = 0; ii < nSurf; ++ii)
195 blockGrid.surfs[ii].index = ii + 1;
196 blockGrid.surfs[ii].fill = isFill * double(rand() % 1000 + 1) / 1000.0;
198 jPlane = (ii >= cumSurfDim.array()).cast<int>().sum();
200 dimGridCur = matSurf.row(jPlane);
202 pos(0) = (ii - incrSurf[jPlane]) % (dimGridCur[0]);
203 pos(1) = int(floor(
double(ii - incrSurf[jPlane]) /
double(dimGridCur[0]))) % dimGridCur[1];
204 pos(2) = int(floor(
double(ii - incrSurf[jPlane]) /
double(dimGridCur[0] * dimGridCur[1]))) % dimGridCur[2];
207 boundaryFlag = !((pos.array() >= dimGrid.array()).any());
208 blockGrid.surfs[ii].voluind[0] = boundaryFlag * ((pos * cumProdDimGrid.transpose()) + 1);
209 boundaryFlag = !(((pos - surfProp.row(jPlane)).array() < 0).any());
210 blockGrid.surfs[ii].voluind[1] =
211 boundaryFlag * (((pos - surfProp.row(jPlane)) * cumProdDimGrid.transpose()) + 1);
214 maskVec = (ind.reverse().array() != jPlane);
216 for (jj = 0; jj < 3; jj++)
218 currDim(kk) = ind(jj);
219 kk = kk + maskVec(jj);
226 mask = mask.setZero();
228 for (jj = 0; jj < 2; jj++)
230 mask(jj + 1, currDim(jj)) = 1;
231 incPosTemp.row(jj) = incPos.row(currDim(jj));
232 incPosTemp.row(jj + 2) = incPos.row(currDim(jj));
233 incrEdge2(jj) = incrEdge(currDim(jj));
234 incrEdge2(jj + 2) = incrEdge(currDim(jj));
237 ((pos.colwise().replicate<4>() + mask).cwiseProduct(incPosTemp).rowwise().sum() + incrEdge2).array() + 1;
239 blockGrid.surfs[ii].edgeind.reserve(tempEdgeInd.size());
240 blockGrid.surfs[ii].edgeind.assign(tempEdgeInd.size(), 0);
241 for (jj = 0; jj < tempEdgeInd.size(); jj++)
243 blockGrid.surfs[ii].edgeind[jj] = tempEdgeInd[jj];
247 #ifdef TEST_VOXEL_SURF
248 cout <<
"--------------------------------------------" << endl <<
"Test BuildBlockSurf" << endl;
249 cout <<
"matSurf: " << endl << matSurf << endl;
250 cout <<
"incrSurf: " << endl << incrSurf << endl;
251 cout <<
"incrSurf2: " << endl << incrSurf2 << endl;
252 cout <<
"incrEdge: " << endl << incrEdge << endl;
253 cout <<
"incrEdge2: " << endl << incrEdge2 << endl;
254 cout <<
"incPos: " << endl << incPos << endl;
255 cout <<
"tempEdgeInd: " << endl << tempEdgeInd << endl;
256 blockGrid.surfs.disp();
262 int BuildBlockEdge(
const Eigen::RowVector3i &dimGrid,
mesh &blockGrid,
int nEdge,
const Eigen::RowVector3i &nEdgeDim,
263 const Eigen::RowVector3i &nSurfDim,
const Eigen::Matrix3i &edgeProp,
const Eigen::Matrix3i &surfProp)
267 Eigen::RowVector3i incrSurf, incrEdge, cumSurfDim, dimGridCur, pos, cumProdDimGrid, ind;
268 Eigen::RowVector2i currDim;
269 Eigen::Matrix3i matSurf, matEdge;
270 Eigen::Matrix<bool, 1, 3> maskVec;
271 Eigen::Matrix<bool, 6, 1> surfLog;
272 Eigen::Matrix<int, 3, 3> incPos;
273 Eigen::Matrix<int, 6, 1> incrSurf2, surfIndTemp;
274 Eigen::Matrix<int, 6, 3> mask, surfLogTemp;
275 Eigen::Matrix<int, 4, 3> incPosTemp;
276 Eigen::Matrix<int, 4, 1> tempEdgeInd, incrEdge2;
277 Eigen::Matrix<int, 2, 1> vertIndTemp, indTemp1, indTemp2;
278 Eigen::Matrix<int, 2, 3> posMatTemp;
280 int jPlane, jj, kk, nSurfEdge;
283 matSurf = (dimGrid.colwise().replicate(3).array()) + surfProp.array();
284 matEdge = (dimGrid.colwise().replicate(3).array()) + edgeProp.array();
286 incrSurf << 0, nSurfDim.head<2>();
287 incrSurf =
cumsum(incrSurf, 0);
288 incrSurf2 << incrSurf.rowwise().replicate(2).transpose();
290 incrEdge << 0, nEdgeDim.head<2>();
291 incrEdge =
cumsum(incrEdge, 0);
293 incPos << Eigen::Matrix<int, 3, 1>::Ones(), matSurf.leftCols<2>();
296 cumSurfDim =
cumsum(nSurfDim, 0);
299 dimGrid.head(2).array() + 1;
300 cumProdDimGrid =
cumprod(cumProdDimGrid, 0);
304 for (
int ii = 0; ii < nEdge; ii++)
306 blockGrid.edges[ii].index = ii + 1;
307 jPlane = (incrEdge.array() <= ii).cast<int>().sum() - 1;
308 dimGridCur = matEdge.row(jPlane);
310 pos(0) = (ii - incrEdge[jPlane]) % (dimGridCur[0]);
311 pos(1) = int(floor(
double(ii - incrEdge[jPlane]) /
double(dimGridCur[0]))) % dimGridCur[1];
312 pos(2) = int(floor(
double(ii - incrEdge[jPlane]) /
double(dimGridCur[0] * dimGridCur[1]))) % dimGridCur[2];
316 posMatTemp.row(0) = pos;
317 posMatTemp.row(1) = (pos.array() + 1) - edgeProp.row(jPlane).array();
318 vertIndTemp = (posMatTemp * cumProdDimGrid.transpose()).array() + 1;
320 blockGrid.edges[ii].vertind.reserve(vertIndTemp.size());
321 blockGrid.edges[ii].vertind.assign(vertIndTemp.size(), 0);
322 for (jj = 0; jj < vertIndTemp.size(); jj++)
324 blockGrid.edges[ii].vertind[jj] = vertIndTemp[jj];
328 mask = mask.setZero();
329 maskVec = (ind.reverse().array() != jPlane);
331 for (jj = 0; jj < 3; jj++)
333 indTemp1(kk) = ind(jj);
334 kk = kk + maskVec(jj);
340 maskVec = (ind.array() != jPlane);
342 for (jj = 0; jj < 3; jj++)
344 indTemp2(kk) = ind(jj);
345 kk = kk + maskVec(jj);
351 for (jj = 0; jj < 2; jj++)
353 mask(indTemp1(jj) + 3, indTemp2(jj)) = -1;
356 surfLogTemp = pos.colwise().replicate(6) + mask;
358 surfIndTemp = (surfLogTemp.cwiseProduct(incPos.colwise().replicate(2)).rowwise().sum() + incrSurf2).array() + 1;
360 surfLog = !(((surfLogTemp.array() < 0) || (surfLogTemp.array() > (matSurf.colwise().replicate(2).array() - 1)))
363 (ind.rowwise().replicate(2).reverse().array() == jPlane).transpose());
364 nSurfEdge = max(surfLog.cast<
int>().sum(), 2);
365 blockGrid.edges[ii].surfind.reserve(nSurfEdge);
366 blockGrid.edges[ii].surfind.assign(nSurfEdge, 0);
368 for (jj = 0; jj < surfLog.size(); jj++)
372 blockGrid.edges[ii].surfind[kk] = surfIndTemp[jj];
380 #ifdef TEST_VOXEL_EDGE
381 cout <<
"--------------------------------------------" << endl <<
"Test BuildBlockEdge" << endl;
382 cout <<
"matSurf: " << endl << matSurf << endl;
383 cout <<
"incrSurf: " << endl << incrSurf << endl;
384 cout <<
"incrEdge: " << endl << incrEdge << endl;
385 cout <<
"incPos: " << endl << incPos << endl;
386 cout <<
"vertIndTemp: " << endl << vertIndTemp << endl;
387 blockGrid.edges.disp();
393 int BuildBlockVert(
const Eigen::RowVector3i &dimGrid,
mesh &blockGrid,
int nVert,
const Eigen::Matrix3i &edgeProp,
394 const Eigen::RowVector3i &nEdgeDim)
397 Eigen::RowVector3i cumSurfDim, dimGridVert, dimGridAct, pos, cumProdDimGrid, incrEdge;
398 Eigen::RowVector3d coordTemp;
399 Eigen::RowVector2i currDim;
400 Eigen::Matrix3i matEdge, incPos;
401 Eigen::Matrix<int, 6, 1> edgeIndTemp;
402 Eigen::Matrix<bool, 6, 1> edgeLog;
403 Eigen::Matrix<int, 6, 3> edgeLogTemp;
407 incrEdge << 0, nEdgeDim.head<2>();
408 incrEdge =
cumsum(incrEdge, 0);
410 dimGridVert = dimGrid.array() + 1;
411 dimGridAct = dimGrid.cwiseMax(1);
413 matEdge = (dimGrid.colwise().replicate(3).array()) + edgeProp.array();
414 Eigen::Matrix3i edgeProp2 = 1 - edgeProp.array();
415 incPos << Eigen::Matrix<int, 3, 1>::Ones(), matEdge.leftCols<2>();
418 for (ii = 0; ii < nVert; ii++)
420 blockGrid.verts[ii].index = ii + 1;
422 pos(0) = ii % (dimGridVert[0]);
423 pos(1) = int(floor(
float(ii) /
float(dimGridVert[0]))) % (dimGridVert[1]);
424 pos(2) = int(floor(
double(ii) /
double(dimGridVert[0] * dimGridVert[1]))) % dimGridVert[2];
426 coordTemp = pos.cast<
double>().array() / dimGridAct.cast<
double>().array();
427 for (jj = 0; jj < 3; jj++)
429 blockGrid.verts[ii].coord[jj] = coordTemp[jj];
432 edgeLogTemp << pos.colwise().replicate(3), (pos.colwise().replicate(3) - edgeProp2);
433 edgeIndTemp = (edgeLogTemp.cwiseProduct(incPos.colwise().replicate(2)).rowwise().sum() +
434 (incrEdge.rowwise().replicate(2).transpose()))
438 edgeLog = !(((edgeLogTemp.array() < 0) || (edgeLogTemp.array() > (matEdge.colwise().replicate(2).array() - 1)))
442 blockGrid.verts[ii].edgeind.assign(
int(edgeLog.cast<
int>().sum()), 0);
445 for (jj = 0; jj < 6; jj++)
449 blockGrid.verts[ii].edgeind[kk] = edgeIndTemp[jj];
455 #ifdef TEST_VOXEL_VERT
456 cout <<
"--------------------------------------------" << endl <<
"Test BuildBlockVert" << endl;
457 cout <<
"matEdge: " << endl << matEdge << endl;
458 cout <<
"incPos: " << endl << incPos << endl;
460 blockGrid.verts.disp();
468 int Test_BuildBlockGrid_noout()
472 int errFlag, errTest;
473 Eigen::RowVector3i dimGrid(2, 3, 4);
478 errTest = BuildBlockGrid(dimGrid, blockGrid);
479 errFlag = errFlag | (errTest != 0);
486 int errFlag, errTest, start_s, stop_s;
487 Eigen::RowVector3i dimGrid1(6, 6, 12), dimGrid2(100, 100, 0), dimGrid3(20, 30, 10), dimGrid4(2, 3, 4);
489 const char *fileToOpen;
491 tecplotfile outmesh1, outmesh3, outmesh2, outmesh4;
494 errTest = BuildBlockGrid(dimGrid1, blockGrid);
495 errFlag += (errTest != 0);
496 fileToOpen =
"../TESTOUT/tecout6612.plt";
497 errTest = outmesh1.OpenFile(fileToOpen);
498 errFlag += (errTest != 0);
499 errTest = outmesh1.PrintMesh(blockGrid);
500 errFlag += (errTest != 0);
501 fileToOpen =
"../TESTOUT/mesh6612.dat";
502 errFlag += TestCompareReadWrite(fileToOpen, blockGrid, outmesh1);
504 errTest += BuildBlockGrid(dimGrid2, blockGrid);
505 errFlag += (errTest != 0);
506 fileToOpen =
"../TESTOUT/tecout100100.plt";
507 errTest = outmesh2.OpenFile(fileToOpen);
508 errFlag += (errTest != 0);
509 fileToOpen =
"../TESTOUT/tecout100100.dat";
510 errFlag += TestCompareReadWrite(fileToOpen, blockGrid, outmesh2);
512 errTest = outmesh2.PrintMesh(blockGrid);
513 errFlag += (errTest != 0);
516 errTest = BuildBlockGrid(dimGrid3, blockGrid);
517 errFlag += (errTest != 0);
520 cout <<
"time: " << (stop_s - start_s) /
double(CLOCKS_PER_SEC) * 1000 <<
"ms" << endl;
521 fileToOpen =
"../TESTOUT/tecout203010.plt";
522 errTest = outmesh3.OpenFile(fileToOpen);
523 errFlag += (errTest != 0);
524 errTest = outmesh3.PrintMesh(blockGrid);
525 errFlag += (errTest != 0);
527 fileToOpen =
"../TESTOUT/mesh203010.dat";
528 errFlag += TestCompareReadWrite(fileToOpen, blockGrid, outmesh3);
536 Eigen::RowVector3i dimGrid1(6, 6, 12), dimGrid2(100, 100, 0), dimGrid3(20, 30, 10), dimGrid4(2, 3, 4);
539 errFlag += Test_MeshOut_Size(dimGrid1,
false);
540 errFlag += Test_MeshOut_Size(dimGrid2,
false);
541 errFlag += Test_MeshOut_Size(dimGrid3,
false);
542 errFlag += Test_MeshOut_Size(dimGrid4,
false);
547 int Test_MeshOut_Size(Eigen::RowVector3i dimGrid,
bool runReOrder)
550 std::string fileToOpen, gridSize;
551 int errFlag, errTest, start_s;
554 gridSize = std::to_string(dimGrid[0]) + std::to_string(dimGrid[1]) + std::to_string(dimGrid[2]);
558 gridSize +=
"_reordered";
564 errTest = BuildBlockGrid(dimGrid, blockGrid);
569 errFlag += (errTest != 0);
570 rsvs3d::TimeStamp((std::string(
"Grid of size ") + gridSize +
" : ").c_str(), start_s);
573 fileToOpen = std::string(
"../TESTOUT/tecout") + gridSize +
".plt";
574 errTest = outmesh.OpenFile(fileToOpen.c_str());
575 errFlag += (errTest != 0);
576 errTest = outmesh.PrintMesh(blockGrid);
577 errFlag += (errTest != 0);
580 fileToOpen = std::string(
"../TESTOUT/mesh") + gridSize +
".dat";
581 errFlag += TestCompareReadWrite(fileToOpen.c_str(), blockGrid, outmesh);
583 std::cout << std::endl;
587 int Test_MeshReOrder()
590 Eigen::RowVector3i dimGrid1(6, 6, 12), dimGrid2(100, 100, 0), dimGrid3(20, 30, 10), dimGrid4(2, 3, 4);
593 errFlag += Test_MeshOut_Size(dimGrid1,
true);
594 errFlag += Test_MeshOut_Size(dimGrid2,
true);
595 errFlag += Test_MeshOut_Size(dimGrid3,
true);
596 errFlag += Test_MeshOut_Size(dimGrid4,
true);
void OrientFaces()
Orients either surfaces or edges depending on the dimensionality of the object.
Provides all the mesh tools used for the generation of 3D grids and geometries.
Provide tecplot file formating for mesh and snake outputs.
Generation of cartesian grids.
T cumprod(const T &matIn, int d)
template which applies cumulative product to Eigen Matrix.
T cumsum(const T &matIn, int d)
template which applies cumulative sum to Eigen Matrix.