48 map<LibUtilities::ShapeType, DerivUtilSharedPtr> ProcessVarOpti::BuildDerivUtil(
52 map<LibUtilities::ShapeType, DerivUtilSharedPtr> ret;
57 typedef std::pair<LibUtilities::PointsType, LibUtilities::PointsType>
60 map<LibUtilities::ShapeType, PTypes> typeMap;
62 if (m_mesh->m_nummode + o <= 11)
77 for (
auto &it : typeMap)
79 PTypes pType = it.second;
85 const int pDim = pkey1.GetPointsDim();
86 const int order = m_mesh->m_nummode - 1;
108 der->ptsStd = u1[0].num_elements();
109 der->pts = u2[0].num_elements();
140 "Unknown element type for derivative utility setup");
146 VandermondeI.Invert();
148 for (
int i = 0; i < pDim; ++i)
152 der->VdmD[i] = interp * der->VdmDStd[i];
174 value_vector(val_vec) {}
178 return value_vector[i1] > value_vector[i2];
184 vector<vector<NodeSharedPtr> > ProcessVarOpti::GetColouredNodes(
185 vector<ElUtilSharedPtr> elLock)
190 for (
int i = 0; i < elLock.size(); i++)
192 vector<NodeSharedPtr> nodes;
193 elLock[i]->GetEl()->GetCurvedNodes(nodes);
194 for (
int j = 0; j < nodes.size(); j++)
196 ignoredNodes.insert(nodes[j]);
203 switch (m_mesh->m_spaceDim)
207 for(
auto &edge : m_mesh->m_edgeSet)
209 if(edge->m_elLink.size() == 2)
214 boundaryNodes.insert(edge->m_n1);
215 boundaryNodes.insert(edge->m_n2);
216 for(
int i = 0; i < edge->m_edgeNodes.size(); i++)
218 boundaryNodes.insert(edge->m_edgeNodes[i]);
227 for (
auto &face : m_mesh->m_faceSet)
229 if (face->m_elLink.size() == 2)
234 vector<NodeSharedPtr> vs = face->m_vertexList;
235 for (
int j = 0; j < vs.size(); j++)
237 boundaryNodes.insert(vs[j]);
240 vector<EdgeSharedPtr> es = face->m_edgeList;
241 for (
int j = 0; j < es.size(); j++)
243 for (
int k = 0; k < es[j]->m_edgeNodes.size(); k++)
245 boundaryNodes.insert(es[j]->m_edgeNodes[k]);
249 for (
int i = 0; i < face->m_faceNodes.size(); i++)
251 boundaryNodes.insert(face->m_faceNodes[i]);
258 for (
auto &node : m_mesh->m_vertexSet)
260 if(node->GetNumCadCurve() > 1)
262 boundaryNodes.insert(node);
274 vector<NodeSharedPtr> remainEdgeVertex;
275 vector<NodeSharedPtr> remainFace;
276 vector<NodeSharedPtr> remainVolume;
280 for (
auto &node : m_mesh->m_vertexSet)
282 if (boundaryNodes.find(node) == boundaryNodes.end() &&
283 ignoredNodes.find(node) == ignoredNodes.end())
285 remainEdgeVertex.push_back(node);
286 if (node->GetNumCadCurve() == 1)
290 else if (node->GetNumCADSurf() == 1)
296 m_res->nDoF += m_mesh->m_spaceDim;
302 for (
auto &edge : m_mesh->m_edgeSet)
304 vector<NodeSharedPtr> &n = edge->m_edgeNodes;
305 for (
int j = 0; j < n.size(); j++)
307 if (boundaryNodes.find(n[j]) == boundaryNodes.end() &&
308 ignoredNodes.find(n[j]) == ignoredNodes.end())
310 remainEdgeVertex.push_back(n[j]);
311 if (n[j]->GetNumCadCurve() == 1)
315 else if (n[j]->GetNumCADSurf() == 1)
321 m_res->nDoF += m_mesh->m_spaceDim;
328 for (
auto &face : m_mesh->m_faceSet)
330 vector<NodeSharedPtr> &n = face->m_faceNodes;
331 for (
int j = 0; j < n.size(); j++)
333 if (boundaryNodes.find(n[j]) == boundaryNodes.end() &&
334 ignoredNodes.find(n[j]) == ignoredNodes.end())
336 remainFace.push_back(n[j]);
337 if (n[j]->GetNumCADSurf() == 1)
343 m_res->nDoF += m_mesh->m_spaceDim;
350 for (
int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++)
352 vector<NodeSharedPtr> ns =
353 m_mesh->m_element[m_mesh->m_expDim][i]->GetVolumeNodes();
354 for (
int j = 0; j < ns.size(); j++)
356 if (boundaryNodes.find(ns[j]) == boundaryNodes.end() &&
357 ignoredNodes.find(ns[j]) == ignoredNodes.end())
359 remainVolume.push_back(ns[j]);
360 m_res->nDoF += m_mesh->m_spaceDim;
366 m_res->n = remainEdgeVertex.size()
367 + remainFace.size() + remainVolume.size();
370 vector<vector<NodeSharedPtr> > ret;
371 vector<vector<NodeSharedPtr> > retPart;
375 vector<int> num_el(remainEdgeVertex.size());
376 for (
int i = 0; i < remainEdgeVertex.size(); i++)
379 auto it = m_nodeElMap.find(remainEdgeVertex[i]->m_id);
380 vector<ElUtilSharedPtr> &elUtils = it->second;
381 num_el[i] = elUtils.size();
384 vector<int> permNode(remainEdgeVertex.size());
385 for (
int i = 0; i < remainEdgeVertex.size(); ++i)
389 std::sort(permNode.begin(), permNode.end(),
NodeComparator(num_el));
391 vector<NodeSharedPtr> remainEdgeVertexSort(remainEdgeVertex.size());
392 for (
int i = 0; i < remainEdgeVertex.size(); ++i)
395 remainEdgeVertexSort[i] = remainEdgeVertex[j];
398 retPart = CreateColoursets(remainEdgeVertexSort);
399 if(m_mesh->m_verbose)
401 cout <<
"Number of Edge/Vertex Coloursets: " << retPart.size() << endl;
403 for (
int i = 0; i < retPart.size(); i++)
405 ret.push_back(retPart[i]);
409 retPart = CreateColoursets(remainFace);
410 if(m_mesh->m_verbose)
412 cout <<
"Number of Face Coloursets: " << retPart.size() << endl;
414 for (
int i = 0; i < retPart.size(); i++)
416 ret.push_back(retPart[i]);
420 retPart = CreateColoursets(remainVolume);
421 if(m_mesh->m_verbose)
423 cout <<
"Number of Volume Coloursets: " << retPart.size() << endl;
425 for (
int i = 0; i < retPart.size(); i++)
427 ret.push_back(retPart[i]);
431 if(m_mesh->m_verbose)
439 vector<vector<NodeSharedPtr> > ProcessVarOpti::CreateColoursets(
440 vector<NodeSharedPtr> remain)
442 vector<vector<NodeSharedPtr> > retPart;
445 while (remain.size() > 0)
447 vector<NodeSharedPtr> layer;
450 for (
int i = 0; i < remain.size(); i++)
453 auto it = m_nodeElMap.find(remain[i]->m_id);
454 ASSERTL0(it != m_nodeElMap.end(),
"could not find node");
457 vector<ElUtilSharedPtr> &elUtils = it->second;
460 bool islocked =
false;
463 for (
int j = 0; j < elUtils.size(); j++)
467 if (locked.find(elUtils[j]->GetId()) != locked.end())
479 layer.push_back(remain[i]);
480 completed.insert(remain[i]->m_id);
481 for (
int j = 0; j < elUtils.size(); j++)
483 locked.insert(elUtils[j]->GetId());
490 vector<NodeSharedPtr> tmp = remain;
492 for (
int i = 0; i < tmp.size(); i++)
494 if (completed.find(tmp[i]->m_id) == completed.end())
496 remain.push_back(tmp[i]);
501 retPart.push_back(layer);
504 if(m_mesh->m_verbose)
507 m_res->n - remain.size(), m_res->n,
"Node Coloring");
515 void ProcessVarOpti::GetElementMap(
516 int o, map<LibUtilities::ShapeType, DerivUtilSharedPtr> derMap)
518 for (
int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++)
521 vector<NodeSharedPtr> ns;
522 el->GetCurvedNodes(ns);
524 el, derMap[el->GetShapeType()], m_res, m_mesh->m_nummode, o));
525 m_dataSet.push_back(d);
528 for (
int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++)
531 vector<NodeSharedPtr> ns;
532 el->GetCurvedNodes(ns);
534 for (
int j = 0; j < ns.size(); j++)
536 m_nodeElMap[ns[j]->m_id].push_back(m_dataSet[i]);
539 ASSERTL0(derMap[el->GetShapeType()]->ptsStd == ns.size(),
540 "mismatch node count");
544 vector<ElUtilSharedPtr> ProcessVarOpti::GetLockedElements(
NekDouble thres)
546 vector<ElUtilSharedPtr> elBelowThres;
547 for (
int i = 0; i < m_dataSet.size(); ++i)
549 if (m_dataSet[i]->GetScaledJac() < thres)
551 elBelowThres.push_back(m_dataSet[i]);
555 std::unordered_set<int> inmesh;
556 vector<ElUtilSharedPtr> totest;
558 for (
int i = 0; i < elBelowThres.size(); i++)
560 auto t = inmesh.insert(elBelowThres[i]->GetId());
562 vector<FaceSharedPtr> f = elBelowThres[i]->GetEl()->GetFaceList();
563 for (
int j = 0; j < f.size(); j++)
565 for (
int k = 0; k < f[j]->m_elLink.size(); k++)
567 if (f[j]->m_elLink[k].first->GetId() ==
568 elBelowThres[i]->GetId())
573 t = inmesh.insert(f[j]->m_elLink[k].first->GetId());
577 m_dataSet[f[j]->m_elLink[k].first->GetId()]);
583 for (
int i = 0; i < 6; i++)
585 vector<ElUtilSharedPtr> tmp = totest;
587 for (
int j = 0; j < tmp.size(); j++)
589 vector<FaceSharedPtr> f = tmp[j]->GetEl()->GetFaceList();
590 for (
int k = 0; k < f.size(); k++)
592 for (
int l = 0; l < f[k]->m_elLink.size(); l++)
594 if (f[k]->m_elLink[l].first->GetId() == tmp[j]->GetId())
599 auto t = inmesh.insert(f[k]->m_elLink[l].first->GetId());
603 m_dataSet[f[k]->m_elLink[l].first->GetId()]);
611 vector<ElUtilSharedPtr> ret;
612 for (
int i = 0; i < m_dataSet.size(); ++i)
614 if (inmesh.find(m_dataSet[i]->GetId()) == inmesh.end())
616 ret.push_back(m_dataSet[i]);
623 void ProcessVarOpti::RemoveLinearCurvature()
625 for(
int i = 0; i < m_dataSet.size(); i++)
627 if(m_dataSet[i]->GetScaledJac() > 0.999)
630 vector<NodeSharedPtr> ns;
631 el->SetVolumeNodes(ns);
635 map<int, vector<FaceSharedPtr> > edgeToFace;
637 for(
auto &face : m_mesh->m_faceSet)
640 for(
int i = 0; i < face->m_elLink.size(); i++)
642 int id = face->m_elLink[i].first->GetId();
643 if(m_dataSet[
id]->GetScaledJac() <= 0.999)
651 face->m_faceNodes.clear();
654 vector<EdgeSharedPtr> es = face->m_edgeList;
655 for(
int i = 0; i < es.size(); i++)
657 edgeToFace[es[i]->m_id].push_back(face);
661 for(
auto &edge : m_mesh->m_edgeSet)
663 auto it = edgeToFace.find(edge->m_id);
664 ASSERTL0(it != edgeToFace.end(),
"not found");
666 for(
int i = 0; i < it->second.size(); i++)
668 if(it->second[i]->m_faceNodes.size() > 0)
676 edge->m_edgeNodes.clear();
std::shared_ptr< DerivUtil > DerivUtilSharedPtr
#define ASSERTL0(condition, msg)
int PrintProgressbar(const int position, const int goal, const std::string message, int lastprogress=-1)
Prints a progressbar.
A class to assist in the construction of nodal simplex and hybrid elements in two and three dimension...
Specialisation of the NodalUtil class to support nodal triangular elements.
3D Nodal Symmetric positive internal tet (Whitherden, Vincent)
SharedMatrix GetVandermondeForDeriv(int dir)
Return the Vandermonde matrix of the derivative of the basis functions for the nodal distribution...
std::unordered_set< NodeSharedPtr, NodeHash > NodeSet
SharedMatrix GetInterpolationMatrix(Array< OneD, Array< OneD, NekDouble > > &xi)
Construct the interpolation matrix used to evaluate the basis at the points xi inside the element...
const vector< int > & value_vector
Specialisation of the NodalUtil class to support nodal hex elements.
std::shared_ptr< Element > ElementSharedPtr
3D Nodal Electrostatic Points on a Tetrahedron
PointsManagerT & PointsManager(void)
Defines a specification for a set of points.
Specialisation of the NodalUtil class to support nodal prismatic elements.
SharedMatrix GetVandermonde()
Return the Vandermonde matrix for the nodal distribution.
NodeComparator(const vector< int > &val_vec)
Specialisation of the NodalUtil class to support nodal quad elements.
std::shared_ptr< ElUtil > ElUtilSharedPtr
bool operator()(int i1, int i2)
2D Nodal Electrostatic Points on a Triangle
3D electrostatically spaced points on a Prism
Specialisation of the NodalUtil class to support nodal tetrahedral elements.
2D Nodal Symmetric positive internal triangle (Whitherden, Vincent)