40 #include <boost/algorithm/string.hpp> 57 InputNek5000::create,
"Reads Nektar rea file.");
82 int nParam, nElements, nCurves;
83 int i, j, k, nodeCounter = 0;
93 cout <<
"InputNek5000: Start reading file..." << endl;
99 for (i = 0; i < 4; ++i)
104 stringstream s(line);
107 for (i = 0; i < nParam; ++i)
120 for (i = 0; i < j; ++i)
130 for (i = 0; i < j; ++i)
138 bool foundMesh =
false;
142 if (line.find(
"MESH") != string::npos)
151 cerr <<
"Couldn't find MESH tag inside file." << endl;
159 s >> nElements >>
m_mesh->m_expDim;
163 m_mesh->m_fields.push_back(
"u");
164 m_mesh->m_fields.push_back(
"v");
165 if (
m_mesh->m_spaceDim > 2)
167 m_mesh->m_fields.push_back(
"w");
169 m_mesh->m_fields.push_back(
"p");
172 for (i = 0; i < nElements; ++i)
177 if (
m_mesh->m_expDim == 2)
182 for (j = 0; j < 2; ++j)
187 for (k = 0; k < 4; ++k)
199 for (j = 0; j < 6; ++j)
204 int offset = j > 2 ? 4 : 0;
205 for (k = 0; k < 4; ++k)
207 s >> vertex[offset + k][j % 3];
215 vector<NodeSharedPtr> nodeList(nNodes);
216 for (k = 0; k < nNodes; ++k)
218 nodeList[k] = std::shared_ptr<Node>(
220 0, vertex[k][0], vertex[k][1], vertex[k][2]));
221 auto testIns =
m_mesh->m_vertexSet.insert(nodeList[k]);
225 nodeList[k] = *(testIns.first);
229 nodeList[k]->m_id = nodeCounter++;
233 vector<int> tags(1, 0);
236 elType, conf, nodeList, tags);
237 m_mesh->m_element[E->GetDim()].push_back(E);
242 if (line.find(
"CURVE") == string::npos)
244 cerr <<
"Cannot find curved side data." << endl;
262 int nek2nekedge[12] = {
263 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7
269 int nek2nekface[6] = {
275 for (i = 0; i < nCurves; ++i)
283 if (nElements < 1000)
286 s.str(line.substr(0, 3));
289 s.str(line.substr(3, 3));
291 line = line.substr(6);
293 else if (nElements < 1000000)
296 s.str(line.substr(0, 2));
299 s.str(line.substr(2, 6));
301 line = line.substr(8);
306 s.str(line.substr(0, 2));
309 s.str(line.substr(2, 12));
311 line = line.substr(14);
317 for (j = 0; j < 5; ++j)
325 side = nek2nekedge[side];
336 int convexity = radius < 0 ? -1 : 1;
337 radius = fabs(radius);
345 Node P1(*(edge->m_n1)), P2(*(edge->m_n2));
347 if (fabs(P1.m_z - P2.
m_z) > 1e-8)
349 cout <<
"warning: detected non x-y edge." << endl;
351 P1.m_z = P2.
m_z = 0.0;
353 Node unitNormal, link, centroid, centre;
354 Node midpoint = (P1 + P2)*0.5, dx = P2 - P1;
357 unitNormal.
m_x = -dx.m_y / l;
358 unitNormal.
m_y = dx.m_x / l;
360 if (2.0 * radius < l)
362 cerr <<
"failure" << endl;
366 semiangle = asin (0.5 * l / radius);
370 vector<NodeSharedPtr> elNodes = el->GetVertexList();
371 int nNodes = elNodes.size();
373 for (
int i = 0; i < nNodes; ++i)
376 Node tmp(*elNodes[i]);
382 link = centroid - midpoint;
385 centre = midpoint + unitNormal * (
sign * cos(semiangle) *
389 theta1 = atan2 (P1.m_y - centre.
m_y, P1.m_x - centre.
m_x);
390 theta2 = atan2 (P2.
m_y - centre.
m_y, P2.
m_x - centre.
m_x);
391 dtheta = theta2 - theta1;
393 if (fabs(dtheta) > 2.0*semiangle + 1e-15)
395 dtheta += (dtheta < 0.0) ? 2.0*M_PI : -2.0*M_PI;
398 edge->m_edgeNodes.clear();
400 for (j = 1; j < nq-1; ++j) {
401 phi = theta1 + dtheta * 0.5 * (rp[j] + 1.0);
404 centre.
m_x + radius * cos(phi),
405 centre.
m_y + radius * sin(phi),
407 edge->m_edgeNodes.push_back(asd);
415 cerr <<
"Curve type '" << curveType <<
"' on side " << side
416 <<
" of element " << elmt <<
" is unsupported;" 417 <<
"will ignore." << endl;
420 cerr <<
"Unknown curve type '" << curveType <<
"' on side " 421 << side <<
" of element " << elmt <<
"; will ignore." 431 if (line.find(
"BOUNDARY") == string::npos)
433 cerr <<
"Cannot find boundary conditions." << endl;
438 std::unordered_set<pair<int, int>,
PairHash> periodicIn;
439 int periodicInId = -1, periodicOutId = -1;
444 int perIn = 0, perOut = 0;
452 if (line.find(
"*") != string::npos)
464 s.str(line.substr(0, 4));
474 if (nElements < 1000)
478 s.str(line.substr(4, 3));
481 s.str(line.substr(7, 3));
483 line = line.substr(10);
485 else if (nElements < 100000)
489 s.str(line.substr(4, 5));
492 s.str(line.substr(9, 1));
494 line = line.substr(10);
496 else if (nElements < 1000000)
500 s.str(line.substr(4, 6));
502 side = lineCnt % (2 *
m_mesh->m_expDim);
503 line = line.substr(9);
509 s.str(line.substr(4, 12));
511 side = lineCnt % (2 *
m_mesh->m_expDim);
512 line = line.substr(15);
518 for (i = 0; i < 5; ++i)
532 std::string fields[] = {
"u",
"v",
"w",
"p" };
543 for (i = 0; i <
m_mesh->m_fields.size() - 1; ++i)
545 c->field.push_back(fields[i]);
546 c->value.push_back(
"0");
551 c->field.push_back(fields[3]);
552 c->value.push_back(
"0");
560 int perElmt = (int)(data[0] + 0.5) - 1;
561 int perFace = (int)(data[1] + 0.5) - 1;
564 if (periodicInId == -1)
566 periodicInId =
m_mesh->m_condition.size();
567 periodicOutId =
m_mesh->m_condition.size()+1;
571 bool hasIn = periodicIn.find(make_pair(perElmt, perFace)) !=
576 swap(periodicInId, periodicOutId);
581 periodicIn.insert(make_pair(elmt, side));
585 std::string periodicInStr =
"[" +
586 boost::lexical_cast<
string>(periodicInId) +
"]";
587 std::string periodicOutStr =
"[" +
588 boost::lexical_cast<
string>(periodicOutId) +
"]";
590 for (i = 0; i <
m_mesh->m_fields.size() - 1; ++i)
592 c->field.push_back(fields[i]);
593 c->value.push_back(periodicOutStr);
597 c->field.push_back(fields[3]);
598 c->value.push_back(periodicOutStr);
606 c->m_composite.push_back(nComposite++);
607 c2->m_composite.push_back(nComposite++);
609 c2->field = c->field;
611 for (i = 0; i < c->type.size(); ++i)
613 c2->value.push_back(periodicInStr);
616 m_mesh->m_condition[periodicInId] = c;
617 m_mesh->m_condition[periodicOutId] = c2;
622 swap(periodicInId, periodicOutId);
632 int compTag, conditionId;
636 if (el->GetDim() == 3)
639 vector<NodeSharedPtr> nodeList;
640 nodeList.insert(nodeList.begin(),
641 f->m_vertexList.begin(),
642 f->m_vertexList.end());
650 conf, nodeList, tags);
653 for (
int i = 0; i < f->m_vertexList.size(); ++i)
655 surfEl->GetEdge(i)->m_edgeNodes = f->m_edgeList[i]->m_edgeNodes;
656 surfEl->GetEdge(i)->m_curveType = f->m_edgeList[i]->m_curveType;
663 vector<NodeSharedPtr> nodeList;
664 nodeList.push_back(f->m_n1);
665 nodeList.push_back(f->m_n2);
680 for (
auto &it :
m_mesh->m_condition)
692 conditionId =
m_mesh->m_condition.size();
693 compTag = nComposite;
694 c->m_composite.push_back(compTag);
695 m_mesh->m_condition[conditionId] = c;
699 compTag = c->m_composite[0];
704 vector<int> existingTags = surfEl->GetTagList();
706 existingTags.insert(existingTags.begin(), compTag);
707 surfEl->SetTagList(existingTags);
708 surfEl->SetId(nSurfaces);
710 m_mesh->m_element[surfEl->GetDim()].push_back(surfEl);
714 if (lineCnt != nElements * (
m_mesh->m_expDim * 2))
716 cerr <<
"Warning: boundary conditions may not have been correctly read " 717 <<
"from Nek5000 input file." << endl;
722 cerr <<
"Warning: number of periodic faces does not match." << endl;
734 if (periodicInId != -1)
737 ->m_composite[0]]->m_reorder =
false;
739 ->m_composite[0]]->m_reorder =
false;
Basic information about an element.
#define sign(a, b)
return the sign(b)*a
NekDouble m_y
Y-coordinate.
NEKMESHUTILS_EXPORT NekDouble dot(const Node &pSrc) const
MeshSharedPtr m_mesh
Mesh object.
std::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
std::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
ElementFactory & GetElementFactory()
Represents a point in the domain.
std::shared_ptr< Node > NodeSharedPtr
std::shared_ptr< Face > FaceSharedPtr
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< Element > ElementSharedPtr
virtual NEKMESHUTILS_EXPORT void ProcessElements()
Generate element IDs.
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.
NekDouble m_x
X-coordinate.
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.
NekDouble m_z
Z-coordinate.
std::pair< ModuleType, std::string > ModuleKey
std::shared_ptr< Condition > ConditionSharedPtr
virtual NEKMESHUTILS_EXPORT void ProcessComposites()
Generate composites.
1D Gauss-Lobatto-Legendre quadrature points
ModuleFactory & GetModuleFactory()