59 "Refines a prismatic or quadrilateral boundary layer.");
63 int **ret =
new int *[lda];
64 for (
int i = 0; i < lda; ++i)
67 ret[i][0] = arr[i][0];
68 ret[i][1] = arr[i][1];
75 int **ret =
new int *[lda];
76 for (
int i = 0; i < lda; ++i)
79 ret[i][0] = arr[i][0];
80 ret[i][1] = arr[i][1];
81 ret[i][2] = arr[i][2];
82 ret[i][3] = arr[i][3];
112 ConfigOption(
false,
"2",
"Number of layers to refine.");
114 ConfigOption(
false,
"5",
"Number of points in high order elements.");
116 ConfigOption(
false,
"",
"Tag identifying surface connected to prism.");
118 ConfigOption(
false,
"2.0",
"Ratio to use in geometry progression.");
129 cout <<
"ProcessBL: Refining boundary layer..." << endl;
131 int dim =
m_mesh->m_expDim;
147 ASSERTL0(0,
"Dimension not supported");
161 int nodeId =
m_mesh->m_vertexSet.size();
162 int nl =
m_config[
"layers"].as<
int>();
169 bool ratioIsString =
false;
171 if (
m_config[
"r"].isType<NekDouble>())
177 std::string rstr =
m_config[
"r"].as<
string>();
178 rExprId = rEval.DefineFunction(
"x y z", rstr);
179 ratioIsString =
true;
187 map<int, int> splitEls;
193 std::unordered_map<int, vector<NodeSharedPtr> > edgeMap;
195 string surf =
m_config[
"surf"].as<
string>();
198 vector<unsigned int> surfs;
200 sort(surfs.begin(), surfs.end());
204 for (
int i = 0; i <
m_mesh->m_element[
m_mesh->m_expDim].size(); ++i)
207 int nSurf = el->GetEdgeCount();
209 for (
int j = 0; j < nSurf; ++j)
211 int bl = el->GetBoundaryLink(j);
218 vector<int> tags = bEl->GetTagList();
221 sort(tags.begin(), tags.end());
222 set_intersection(surfs.begin(), surfs.end(),
223 tags .begin(), tags .end(),
224 back_inserter(inter));
226 "Intersection of surfaces wrong");
228 if (inter.size() == 1)
232 cerr <<
"WARNING: Found non-quad element " 233 <<
"to split in surface " << surf
234 <<
"; ignoring" << endl;
238 if (splitEls.count(el->GetId()) > 0)
240 cerr <<
"WARNING: quad already found; " 241 <<
"ignoring" << endl;
245 splitEls[el->GetId()] = j;
252 ASSERTL0(
false,
"Surface must be specified.");
255 if (splitEls.size() == 0)
257 cerr <<
"WARNING: No elements detected to split." << endl;
263 vector<ElementSharedPtr> el =
m_mesh->m_element[
m_mesh->m_expDim];
267 for (
int i = 0; i < el.size(); ++i)
271 if (splitEls.count(el[i]->GetId()) == 0)
278 std::map<int, int> bLink;
279 for (
int j = 0; j < 4; j++)
281 int bl = el[i]->GetBoundaryLink(j);
282 if ( (bl != -1) && ( j != splitEls[el[i]->GetId()]) )
291 el[i]->GetGeom(
m_mesh->m_spaceDim));
304 int nverts = geom->GetNumVerts();
308 for(
int i = 0; i < nverts; ++i)
310 geom->GetVertex(i)->GetCoords(x1,y1,z1);
311 x += x1; y += y1; z += z1;
316 r = rEval.Evaluate(rExprId,x,y,z,0.0);
329 if (splitEls[el[i]->GetId()] % 2)
346 vector<vector<NodeSharedPtr> > edgeNodes(2);
349 for (
int j = 0; j < 2; ++j)
351 int locEdge = (splitEls[el[i]->GetId()]+1+2*j)%4;
352 int edgeId = el[i]->GetEdge(locEdge)->m_id;
356 auto eIt = edgeMap.find(edgeId);
358 if (eIt == edgeMap.end())
361 edgeNodes[j].resize(nl+1);
365 edgeNodes[j][0] = el[i]->GetVertex(locEdge);
366 edgeNodes[j][nl] = el[i]->GetVertex((locEdge+1)%4);
376 x0 = edgeNodes[j][0]->m_x;
377 y0 = edgeNodes[j][0]->m_y;
379 x1 = edgeNodes[j][nl]->m_x;
380 y1 = edgeNodes[j][nl]->m_y;
387 rnew = rEval.Evaluate(rExprId,xm,ym,zm,0.0);
399 for (
int k = 1; k < nl; ++k)
401 xm = 0.5*(1+z[k])*(x1-x0) + x0;
402 ym = 0.5*(1+z[k])*(y1-y0) + y0;
405 new Node(nodeId++, xm,ym,zm));
412 for (
int k = 1; k < nl; ++k)
423 pos = nq*(nl+1) -1 - k;
430 "Quad edge should be < 4.");
434 new Node(nodeId++, x[pos], y[pos], z[pos]));
439 edgeMap[edgeId] = edgeNodes[j];
444 if (eIt->second[0] == el[i]->GetVertex(locEdge))
447 edgeNodes[j] = eIt->second;
452 edgeNodes[j].resize(nl+1);
453 for (
int k = 0; k < nl+1; ++k)
455 edgeNodes[j][k] = eIt->second[nl-k];
463 for (
int j = 0; j < nl; ++j)
466 vector<NodeSharedPtr> nodeList(4);
467 switch (splitEls[el[i]->GetId()])
471 nodeList[0] = edgeNodes[1][nl-j ];
472 nodeList[1] = edgeNodes[0][j ];
473 nodeList[2] = edgeNodes[0][j+1];
474 nodeList[3] = edgeNodes[1][nl-j-1];
479 nodeList[0] = edgeNodes[1][j];
480 nodeList[1] = edgeNodes[1][j+1];
481 nodeList[2] = edgeNodes[0][nl-j-1];
482 nodeList[3] = edgeNodes[0][nl-j];
487 nodeList[0] = edgeNodes[0][nl-j ];
488 nodeList[1] = edgeNodes[1][j ];
489 nodeList[2] = edgeNodes[1][j+1];
490 nodeList[3] = edgeNodes[0][nl-j-1];
495 nodeList[0] = edgeNodes[0][j];
496 nodeList[1] = edgeNodes[0][j+1];
497 nodeList[2] = edgeNodes[1][nl-j-1];
498 nodeList[3] = edgeNodes[1][nl-j];
509 for (
int l = 0; l < 2; ++l)
511 int locEdge = (splitEls[el[i]->GetId()]+2*l)%4;
515 for (
int k = 1; k < nq-1; ++k)
523 pos = j+1 + k*(nl+1);
526 pos = (j+1)*nq + (nq-1) - k;
529 pos = (nl+1)*(nq-1) + j - k*(nl+1);
533 "Quad edge should be < 4.");
536 HOedge->m_edgeNodes.push_back(
538 new Node(nodeId++,x[pos],y[pos],0.0)));
540 HOedge->m_curveType = pt;
545 for (
auto &it : bLink)
554 for (
int k = 0; k < 2; ++k)
557 k, nodeList[(eid+k)%4]);
563 vector<NodeSharedPtr> qNodeList(2);
564 for (
int k = 0; k < 2; ++k)
566 qNodeList[k] = nodeList[(eid+k)%4];
569 tagBE =
m_mesh->m_element[
m_mesh->m_expDim-1][bl]->GetTagList();
574 m_mesh->m_element[
m_mesh->m_expDim-1].push_back(boundaryElmt);
586 set<LibUtilities::ShapeType> validElTypes;
590 int nodeId =
m_mesh->m_vertexSet.size();
591 int nl =
m_config[
"layers"].as<
int>();
598 bool ratioIsString =
false;
600 if (
m_config[
"r"].isType<NekDouble>())
606 std::string rstr =
m_config[
"r"].as<
string>();
607 rExprId = rEval.DefineFunction(
"x y z", rstr);
608 ratioIsString =
true;
612 int prismFaceNodes[5][4] = {
613 {0, 1, 2, 3}, {0, 1, 4, -1}, {1, 2, 5, 4}, {3, 2, 5, -1}, {0, 3, 5, 4}};
614 int hexFaceNodes[6][4] = {{0, 1, 2, 3},
620 map<LibUtilities::ShapeType, int **> faceNodeMap;
629 std::unordered_map<int, int> splitEls;
636 map<LibUtilities::ShapeType, map<int, SplitMapHelper> > splitMap;
637 int po = nq * (nl + 1);
640 int splitMapEdgePrism[6] = {0, 2, 4, 5, 6, 7};
641 int splitMapOffsetPrism[6] = {0, nq, 0, nq - 1, nq + nq - 1, nq};
642 int splitMapIncPrism[6] = {1, 1, po, po, po, po};
643 int splitMapBFacesPrism[3] = {0, 2, 4};
644 int splitMapConnPrism[6][2] = {
645 {0, 0}, {1, 0}, {1, 1}, {0, 1}, {2, 0}, {2, 1}};
647 splitPrism.layerOff = nq;
648 splitPrism.edge = splitMapEdgePrism;
649 splitPrism.offset = splitMapOffsetPrism;
650 splitPrism.inc = splitMapIncPrism;
651 splitPrism.conn =
helper2d(6, splitMapConnPrism);
652 splitPrism.bfacesSize = 3;
653 splitPrism.bfaces = splitMapBFacesPrism;
657 int ho = nq * (nq - 1);
660 int splitMapEdgeHex0[8] = {0, 1, 2, 3, 8, 9, 10, 11};
661 int splitMapOffsetHex0[8] = {
662 0, nq - 1, tl - 1, ho, tl, tl + nq - 1, 2 * tl - 1, tl + ho};
663 int splitMapIncHex0[8] = {1, nq, -1, -nq, 1, nq, -1, -nq};
664 int splitMapBFacesHex0[4] = {1, 2, 3, 4};
665 int splitMapConnHex0[8][2] = {
666 {0, 0}, {1, 0}, {2, 0}, {3, 0}, {0, 1}, {1, 1}, {2, 1}, {3, 1}};
669 splitHex0.
edge = splitMapEdgeHex0;
670 splitHex0.
offset = splitMapOffsetHex0;
671 splitHex0.
inc = splitMapIncHex0;
674 splitHex0.
bfaces = splitMapBFacesHex0;
688 map<LibUtilities::ShapeType, map<int, SplitEdgeHelper> > splitEdge;
690 int splitPrismEdges[3] = {3, 1, 8};
691 int splitPrismEdgeVert[3][2] = {{0, 3}, {1, 2}, {4, 5}};
692 int splitPrismOffset[3] = {0, nq - 1, nq * (nl + 1) * (nq - 1)};
693 int splitPrismInc[3] = {nq, nq, nq};
695 splitPrismEdge.
size = 3;
696 splitPrismEdge.
edge = splitPrismEdges;
698 splitPrismEdge.
offset = splitPrismOffset;
699 splitPrismEdge.
inc = splitPrismInc;
703 int splitHex0Edges[4] = {4, 5, 6, 7};
704 int splitHex0EdgeVert[4][2] = {{0, 4}, {1, 5}, {2, 6}, {3, 7}};
705 int splitHex0Offset[4] = {0, nq - 1, nq * nq - 1, nq * (nq - 1)};
706 int splitHex0Inc[4] = {nq * nq, nq * nq, nq * nq, nq * nq};
708 splitHex0Edge.
size = 4;
709 splitHex0Edge.
edge = splitHex0Edges;
711 splitHex0Edge.
offset = splitHex0Offset;
712 splitHex0Edge.
inc = splitHex0Inc;
716 map<LibUtilities::ShapeType, map<int, bool> > revPoints;
727 std::unordered_map<int, vector<NodeSharedPtr> > edgeMap;
729 string surf =
m_config[
"surf"].as<
string>();
732 vector<unsigned int> surfs;
734 sort(surfs.begin(), surfs.end());
738 for (
int i = 0; i <
m_mesh->m_element[
m_mesh->m_expDim].size(); ++i)
741 int nSurf = el->GetFaceCount();
743 for (
int j = 0; j < nSurf; ++j)
745 int bl = el->GetBoundaryLink(j);
753 vector<int> tags = bEl->GetTagList();
756 sort(tags.begin(), tags.end());
757 set_intersection(surfs.begin(),
761 back_inserter(inter));
762 ASSERTL0(inter.size() <= 1,
"Intersection of surfaces wrong");
764 if (inter.size() == 1)
770 cerr <<
"WARNING: Found quadrilateral face " << j
771 <<
" on surface " << surf
772 <<
" connected to prism; ignoring." << endl;
776 if (splitEls.count(el->GetId()) > 0)
778 cerr <<
"WARNING: prism already found; " 779 <<
"ignoring" << endl;
782 splitEls[el->GetId()] = j;
784 else if (validElTypes.count(el->GetConf().m_e) == 0)
786 cerr <<
"WARNING: Unsupported element type " 787 <<
"found in surface " << j <<
"; " 788 <<
"ignoring" << endl;
799 for (
int i = 0; i <
m_mesh->m_element[
m_mesh->m_expDim].size(); ++i)
805 splitEls[el->GetId()] = 1;
807 else if (validElTypes.count(el->GetConf().m_e) > 0)
809 splitEls[el->GetId()] = 0;
818 if (splitEls.size() == 0)
820 cerr <<
"WARNING: No elements detected to split." << endl;
826 vector<ElementSharedPtr> el =
m_mesh->m_element[
m_mesh->m_expDim];
829 map<int, SpatialDomains::Geometry3DSharedPtr> geomMap;
830 for (
int i = 0; i < el.size(); ++i)
832 const int elId = el[i]->GetId();
833 if (splitEls.find(elId) == splitEls.end())
840 el[i]->GetGeom(
m_mesh->m_spaceDim));
844 for (
int i = 0; i < el.size(); ++i)
846 const int elId = el[i]->GetId();
847 auto sIt = splitEls.find(elId);
849 if (sIt == splitEls.end())
857 const int faceNum = sIt->second;
864 std::map<int, int> bLink;
867 int bl = el[i]->GetBoundaryLink(sMap.
bfaces[j]);
870 bLink[sMap.
bfaces[j]] = bl;
884 int nverts = geom->GetNumVerts();
888 for (
int i = 0; i < nverts; ++i)
890 geom->GetVertex(i)->GetCoords(x1, y1, z1);
898 r = rEval.Evaluate(rExprId, x, y, z, 0.0);
940 q->GetCoords(x, y, z);
942 int nSplitEdge = sEdge.
size;
943 vector<vector<NodeSharedPtr> > edgeNodes(nSplitEdge);
946 for (
int j = 0; j < nSplitEdge; ++j)
948 int locEdge = sEdge.
edge[j];
949 int edgeId = el[i]->GetEdge(locEdge)->m_id;
953 auto eIt = edgeMap.find(edgeId);
955 if (eIt == edgeMap.end())
958 edgeNodes[j].resize(nl + 1);
962 edgeNodes[j][0] = el[i]->GetVertex(sEdge.
edgeVert[j][0]);
963 edgeNodes[j][nl] = el[i]->GetVertex(sEdge.
edgeVert[j][1]);
977 x1 = x[sEdge.
offset[j] + nl * nq];
978 y1 = y[sEdge.
offset[j] + nl * nq];
979 z1 = z[sEdge.
offset[j] + nl * nq];
981 xm = 0.5 * (x0 + x1);
982 ym = 0.5 * (y0 + y1);
983 zm = 0.5 * (z0 + z1);
987 rnew = rEval.Evaluate(rExprId, xm, ym, zm, 0.0);
997 for (
int k = 1; k < nl; ++k)
999 xm = 0.5 * (1 + z[k]) * (x1 - x0) + x0;
1000 ym = 0.5 * (1 + z[k]) * (y1 - y0) + y0;
1001 zm = 0.5 * (1 + z[k]) * (z1 - z0) + z0;
1009 for (
int k = 1; k < nl; ++k)
1011 int pos = sEdge.
offset[j] + k * sEdge.
inc[j];
1013 new Node(nodeId++, x[pos], y[pos], z[pos]));
1018 edgeMap[edgeId] = edgeNodes[j];
1022 edgeNodes[j] = eIt->second;
1027 for (
int j = 0; j < nl; ++j)
1034 vector<NodeSharedPtr> nodeList(sMap.
size);
1035 for (
int k = 0; k < sMap.
size; ++k)
1037 nodeList[k] = edgeNodes[sMap.
conn[k][0]][j + sMap.
conn[k][1]];
1041 ElmtConfig conf(elType, 1,
true,
true,
false);
1043 elType, conf, nodeList, el[i]->GetTagList());
1046 for (
int l = 0; l < sMap.
size; ++l)
1049 for (
int k = 1; k < nq - 1; ++k)
1051 int pos = offset + sMap.
offset[l] + k * sMap.
inc[l];
1053 new Node(nodeId++, x[pos], y[pos], z[pos])));
1055 HOedge->m_curveType = pt;
1060 for (
auto &it : bLink)
1065 vector<NodeSharedPtr> qNodeList(4);
1066 for (
int k = 0; k < 4; ++k)
1068 qNodeList[k] = nodeList[faceNodeMap[elType][fid][k]];
1072 m_mesh->m_element[
m_mesh->m_expDim - 1][bl]->GetTagList();
1084 m_mesh->m_element[
m_mesh->m_expDim - 1][bl] = boundaryElmt;
#define ASSERTL0(condition, msg)
Basic information about an element.
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
std::shared_ptr< Geometry3D > Geometry3DSharedPtr
std::shared_ptr< QuadGeom > QuadGeomSharedPtr
Principle Modified Functions .
MeshSharedPtr m_mesh
Mesh object.
std::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
int ** helper2d(int lda, int arr[][2])
std::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
ElementFactory & GetElementFactory()
std::shared_ptr< Node > NodeSharedPtr
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
std::pair< ModuleType, std::string > ModuleKey
virtual NEKMESHUTILS_EXPORT void ProcessFaces(bool ReprocessFaces=true)
Extract element faces.
std::shared_ptr< Points< NekDouble > > PointsSharedPtr
virtual void Process()
Write mesh to output file.
Principle Modified Functions .
std::shared_ptr< Element > ElementSharedPtr
virtual NEKMESHUTILS_EXPORT void ProcessElements()
Generate element IDs.
Represents a command-line configuration option.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
PointsManagerT & PointsManager(void)
Defines a specification for a set of points.
std::map< std::string, ConfigOption > m_config
List of configuration values.
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
Interpreter class for the evaluation of mathematical expressions.
std::shared_ptr< Expansion > ExpansionSharedPtr
1D power law distribution for boundary layer points
Abstract base class for processing modules.
std::shared_ptr< HexGeom > HexGeomSharedPtr
virtual NEKMESHUTILS_EXPORT void ProcessVertices()
Extract element vertices.
1D power law distribution for boundary layer points
virtual NEKMESHUTILS_EXPORT void ProcessEdges(bool ReprocessEdges=true)
Extract element edges.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
std::shared_ptr< PrismGeom > PrismGeomSharedPtr
std::pair< ModuleType, std::string > ModuleKey
std::shared_ptr< QuadExp > QuadExpSharedPtr
Describes the specification for a Basis.
virtual NEKMESHUTILS_EXPORT void ProcessComposites()
Generate composites.
int ** helper2d(int lda, int arr[][4])
1D Gauss-Lobatto-Legendre quadrature points
ModuleFactory & GetModuleFactory()
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector. ...