Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PreProcessing.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: ProcessJac.h
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: Calculate jacobians of elements.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #include "ProcessVarOpti.h"
37 
41 
42 using namespace std;
43 
44 namespace Nektar
45 {
46 namespace Utilities
47 {
48 
49 map<LibUtilities::ShapeType, DerivUtilSharedPtr> ProcessVarOpti::BuildDerivUtil(
50  int o)
51 {
52  // build Vandermonde information
53  map<LibUtilities::ShapeType, DerivUtilSharedPtr> ret;
54 
55  // Typedef for points types used in the variational optimser. First entry is
56  // the evaluation points; second entry is the distributions used for the
57  // full element (includes element boundary)
58  typedef std::pair<LibUtilities::PointsType, LibUtilities::PointsType>
59  PTypes;
60 
61  map<LibUtilities::ShapeType, PTypes> typeMap;
63 
64  if (m_mesh->m_nummode + o <= 11)
65  {
66  typeMap[LibUtilities::eTriangle] =
70  typeMap[LibUtilities::ePrism] =
72  }
73 
76  // typeMap[LibUtilities::eHexahedron] =
77  // PTypes(LibUtilities::eNodalHexElec, LibUtilities::eNodalHexElec);
78 
79  for (it = typeMap.begin(); it != typeMap.end(); it++)
80  {
81  PTypes pType = it->second;
82  DerivUtilSharedPtr der = boost::shared_ptr<DerivUtil>(new DerivUtil());
83 
84  LibUtilities::PointsKey pkey1(m_mesh->m_nummode, pType.second);
85  LibUtilities::PointsKey pkey2(m_mesh->m_nummode + o, pType.first);
86 
87  const int pDim = pkey1.GetPointsDim();
88  const int order = m_mesh->m_nummode - 1;
89 
90  Array<OneD, Array<OneD, NekDouble> > u1(pDim), u2(pDim);
91 
92  switch (pDim)
93  {
94  case 2:
95  {
96  LibUtilities::PointsManager()[pkey1]->GetPoints(u1[0], u1[1]);
97  LibUtilities::PointsManager()[pkey2]->GetPoints(u2[0], u2[1]);
98  break;
99  }
100  case 3:
101  {
102  LibUtilities::PointsManager()[pkey1]->GetPoints(u1[0], u1[1],
103  u1[2]);
104  LibUtilities::PointsManager()[pkey2]->GetPoints(u2[0], u2[1],
105  u2[2]);
106  break;
107  }
108  }
109 
110  der->ptsStd = u1[0].num_elements();
111  der->pts = u2[0].num_elements();
112 
113  LibUtilities::NodalUtil *nodalUtil = NULL;
114 
115  if (it->first == LibUtilities::eTriangle)
116  {
117  nodalUtil =
118  new LibUtilities::NodalUtilTriangle(order, u1[0], u1[1]);
119  }
120  else if (it->first == LibUtilities::eQuadrilateral)
121  {
122  nodalUtil = new LibUtilities::NodalUtilQuad(order, u1[0], u1[1]);
123  }
124  else if (it->first == LibUtilities::eTetrahedron)
125  {
126  nodalUtil = new LibUtilities::NodalUtilTetrahedron(order, u1[0],
127  u1[1], u1[2]);
128  }
129  else if (it->first == LibUtilities::ePrism)
130  {
131  nodalUtil =
132  new LibUtilities::NodalUtilPrism(order, u1[0], u1[1], u1[2]);
133  }
134  else if (it->first == LibUtilities::eHexahedron)
135  {
136  nodalUtil =
137  new LibUtilities::NodalUtilHex(order, u1[0], u1[1], u1[2]);
138  }
139  else
140  {
141  ASSERTL0(false,
142  "Unknown element type for derivative utility setup");
143  }
144 
145  NekMatrix<NekDouble> interp = *nodalUtil->GetInterpolationMatrix(u2);
146  NekMatrix<NekDouble> Vandermonde = *nodalUtil->GetVandermonde();
147  NekMatrix<NekDouble> VandermondeI = Vandermonde;
148  VandermondeI.Invert();
149 
150  for (int i = 0; i < pDim; ++i)
151  {
152  der->VdmDStd[i] =
153  *nodalUtil->GetVandermondeForDeriv(i) * VandermondeI;
154  der->VdmD[i] = interp * der->VdmDStd[i];
155  }
156 
158  LibUtilities::PointsManager()[pkey2]->GetW();
159  NekVector<NekDouble> quadWi(qds);
160  der->quadW = quadWi;
161 
162  ret[it->first] = der;
163  //delete nodalUtil;
164  }
165 
166  return ret;
167 }
168 
169 
170 
172 {
173  const vector<int> & value_vector;
174 
175  NodeComparator(const vector<int> & val_vec):
176  value_vector(val_vec) {}
177 
178  bool operator()(int i1, int i2)
179  {
180  return value_vector[i1] > value_vector[i2];
181  }
182 };
183 
184 
185 
186 vector<vector<NodeSharedPtr> > ProcessVarOpti::GetColouredNodes(
187  vector<ElUtilSharedPtr> elLock)
188 {
189 
190  // create set of nodes to be ignored and hence not included in the coloursets
191  NodeSet ignoredNodes;
192  for (int i = 0; i < elLock.size(); i++)
193  {
194  vector<NodeSharedPtr> nodes;
195  elLock[i]->GetEl()->GetCurvedNodes(nodes);
196  for (int j = 0; j < nodes.size(); j++)
197  {
198  ignoredNodes.insert(nodes[j]);
199  }
200  }
201 
202  // create set of nodes which are at the boundary and hence not included in the colourset
203  NodeSet boundaryNodes;
204 
205  switch (m_mesh->m_spaceDim)
206  {
207  case 2:
208  {
210  for(it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end(); it++)
211  {
212  if((*it)->m_elLink.size() == 2)
213  {
214  continue;
215  }
216 
217  boundaryNodes.insert((*it)->m_n1);
218  boundaryNodes.insert((*it)->m_n2);
219  for(int i = 0; i < (*it)->m_edgeNodes.size(); i++)
220  {
221  boundaryNodes.insert((*it)->m_edgeNodes[i]);
222  }
223  }
224  break;
225  }
226  case 3:
227  {
228  if(!m_mesh->m_cad)
229  {
231  for (it = m_mesh->m_faceSet.begin();
232  it != m_mesh->m_faceSet.end(); it++)
233  {
234  if ((*it)->m_elLink.size() == 2)
235  {
236  continue;
237  }
238 
239  vector<NodeSharedPtr> vs = (*it)->m_vertexList;
240  for (int j = 0; j < vs.size(); j++)
241  {
242  boundaryNodes.insert(vs[j]);
243  }
244 
245  vector<EdgeSharedPtr> es = (*it)->m_edgeList;
246  for (int j = 0; j < es.size(); j++)
247  {
248  for (int k = 0; k < es[j]->m_edgeNodes.size(); k++)
249  {
250  boundaryNodes.insert(es[j]->m_edgeNodes[k]);
251  }
252  }
253 
254  for (int i = 0; i < (*it)->m_faceNodes.size(); i++)
255  {
256  boundaryNodes.insert((*it)->m_faceNodes[i]);
257  }
258  }
259  }
260  else
261  {
262  //if we have CAD therefore the only fixed nodes exist on vertices only
263  NodeSet::iterator nit;
264  for (nit = m_mesh->m_vertexSet.begin(); nit != m_mesh->m_vertexSet.end(); ++nit)
265  {
266  if((*nit)->GetNumCadCurve() > 1)
267  {
268  boundaryNodes.insert((*nit));
269  }
270  }
271  }
272  break;
273  }
274  default:
275  ASSERTL0(false,"space dim issue");
276  }
277 
278 
279  //create vector of free nodes which "remain", hence will be included in the coloursets
280  vector<NodeSharedPtr> remainEdgeVertex;
281  vector<NodeSharedPtr> remainFace;
282  vector<NodeSharedPtr> remainVolume;
283  m_res->nDoF = 0;
284 
285  // check if vertex nodes are in boundary or ignored nodes, otherwise add to EDGE-VERTEX remain nodes
286  NodeSet::iterator nit;
287  for (nit = m_mesh->m_vertexSet.begin(); nit != m_mesh->m_vertexSet.end();
288  ++nit)
289  {
290  NodeSet::iterator nit2 = boundaryNodes.find(*nit);
291  NodeSet::iterator nit3 = ignoredNodes.find(*nit);
292  if (nit2 == boundaryNodes.end() && nit3 == ignoredNodes.end())
293  {
294  remainEdgeVertex.push_back(*nit);
295  if ((*nit)->GetNumCadCurve() == 1)
296  {
297  m_res->nDoF++;
298  }
299  else if ((*nit)->GetNumCADSurf() == 1)
300  {
301  m_res->nDoF += 2;
302  }
303  else
304  {
305  m_res->nDoF += m_mesh->m_spaceDim;
306  }
307  }
308  }
309 
310  // check if edge nodes are in boundary or ignored nodes, otherwise add to EDGE-VERTEX remain nodes
311  EdgeSet::iterator eit;
312  for (eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++)
313  {
314  vector<NodeSharedPtr> n = (*eit)->m_edgeNodes;
315  for (int j = 0; j < n.size(); j++)
316  {
317  NodeSet::iterator nit2 = boundaryNodes.find(n[j]);
318  NodeSet::iterator nit3 = ignoredNodes.find(n[j]);
319  if (nit2 == boundaryNodes.end() && nit3 == ignoredNodes.end())
320  {
321  remainEdgeVertex.push_back(n[j]);
322  if (n[j]->GetNumCadCurve() == 1)
323  {
324  m_res->nDoF++;
325  }
326  else if (n[j]->GetNumCADSurf() == 1)
327  {
328  m_res->nDoF += 2;
329  }
330  else
331  {
332  m_res->nDoF += m_mesh->m_spaceDim;
333  }
334  }
335  }
336  }
337 
338  // check if face nodes are in boundary or ignored nodes, otherwise add to FACE remain nodes
339  FaceSet::iterator fit;
340  for (fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++)
341  {
342  for (int j = 0; j < (*fit)->m_faceNodes.size(); j++)
343  {
344  NodeSet::iterator nit2 = boundaryNodes.find((*fit)->m_faceNodes[j]);
345  NodeSet::iterator nit3 = ignoredNodes.find((*fit)->m_faceNodes[j]);
346  if (nit2 == boundaryNodes.end() && nit3 == ignoredNodes.end())
347  {
348  remainFace.push_back((*fit)->m_faceNodes[j]);
349  if ((*fit)->m_faceNodes[j]->GetNumCADSurf() == 1)
350  {
351  m_res->nDoF += 2;
352  }
353  else
354  {
355  m_res->nDoF += m_mesh->m_spaceDim;
356  }
357  }
358  }
359  }
360 
361  // check if volume nodes are in boundary or ignored nodes, otherwise add to VOLUME remain nodes
362  for (int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++)
363  {
364  vector<NodeSharedPtr> ns =
365  m_mesh->m_element[m_mesh->m_expDim][i]->GetVolumeNodes();
366  for (int j = 0; j < ns.size(); j++)
367  {
368  NodeSet::iterator nit2 = boundaryNodes.find(ns[j]);
369  NodeSet::iterator nit3 = ignoredNodes.find(ns[j]);
370  if (nit2 == boundaryNodes.end() && nit3 == ignoredNodes.end())
371  {
372  remainVolume.push_back(ns[j]);
373  m_res->nDoF += m_mesh->m_spaceDim;
374  }
375  }
376  }
377 
378  // size of all free nodes to be included in the coloursets
379  m_res->n = remainEdgeVertex.size()
380  + remainFace.size() + remainVolume.size();
381 
382  // data structure for coloursets, that will ultimately contain all free nodes
383  vector<vector<NodeSharedPtr> > ret;
384  vector<vector<NodeSharedPtr> > retPart;
385 
386 
387  // edge and vertex nodes
388  // create vector num_el of number of associated elements of each node
389  vector<int> num_el(remainEdgeVertex.size());
390  for (int i = 0; i < remainEdgeVertex.size(); i++)
391  {
392  //try to find node within all elements
393  NodeElMap::iterator it = m_nodeElMap.find(remainEdgeVertex[i]->m_id);
394  vector<ElUtilSharedPtr> &elUtils = it->second;
395  num_el[i] = elUtils.size();
396  }
397  // finding the permutation according to num_el
398  vector<int> permNode(remainEdgeVertex.size());
399  for (int i = 0; i < remainEdgeVertex.size(); ++i)
400  {
401  permNode[i] = i;
402  }
403  std::sort(permNode.begin(), permNode.end(), NodeComparator(num_el));
404  // applying the permutation to remainEdgeVertex
405  vector<NodeSharedPtr> remainEdgeVertexSort(remainEdgeVertex.size());
406  for (int i = 0; i < remainEdgeVertex.size(); ++i)
407  {
408  int j = permNode[i];
409  remainEdgeVertexSort[i] = remainEdgeVertex[j];
410  }
411 
412  retPart = CreateColoursets(remainEdgeVertexSort);
413  if(m_mesh->m_verbose)
414  {
415  cout << "Number of Edge/Vertex Coloursets: " << retPart.size() << endl;
416  }
417  for (int i = 0; i < retPart.size(); i++)
418  {
419  ret.push_back(retPart[i]);
420  }
421 
422 
423  // face nodes
424  retPart = CreateColoursets(remainFace);
425  if(m_mesh->m_verbose)
426  {
427  cout << "Number of Face Coloursets: " << retPart.size() << endl;
428  }
429  for (int i = 0; i < retPart.size(); i++)
430  {
431  ret.push_back(retPart[i]);
432  }
433 
434 
435  // volume nodes
436  retPart = CreateColoursets(remainVolume);
437  if(m_mesh->m_verbose)
438  {
439  cout << "Number of Volume Coloursets: " << retPart.size() << endl;
440  }
441  for (int i = 0; i < retPart.size(); i++)
442  {
443  ret.push_back(retPart[i]);
444  }
445 
446 
447  if(m_mesh->m_verbose)
448  {
449  cout << endl;
450  }
451 
452  return ret;
453 }
454 
455 vector<vector<NodeSharedPtr> > ProcessVarOpti::CreateColoursets(
456  vector<NodeSharedPtr> remain)
457 {
458  vector<vector<NodeSharedPtr> > retPart;
459 
460  // loop until all free nodes have been sorted
461  while (remain.size() > 0)
462  {
463  vector<NodeSharedPtr> layer; // one colourset
464  set<int> locked;
465  set<int> completed;
466  for (int i = 0; i < remain.size(); i++)
467  {
468  NodeElMap::iterator it = m_nodeElMap.find(remain[i]->m_id); //try to find node within all elements
469  ASSERTL0(it != m_nodeElMap.end(), "could not find node");
470 
471  vector<ElUtilSharedPtr> &elUtils = it->second; // identify the vector of all associated elements of the node
472 
473  bool islocked = false; // suppose node is not locked
474  for (int j = 0; j < elUtils.size(); j++) // loop over all associated elements of the node
475  {
476  set<int>::iterator sit = locked.find(elUtils[j]->GetId()); // check all nodes of the element
477  if (sit != locked.end()) //if node is within the set of locked nodes
478  {
479  islocked = true; // if yes, flag node as locked
480  break; // and go to next node
481  }
482  }
483  if (!islocked) // if the node is not locked
484  {
485  layer.push_back(remain[i]); // insert node into colourset
486  completed.insert(remain[i]->m_id); // insert sorted node into "completed" list
487  for (int j = 0; j < elUtils.size(); j++) // loop over all other nodes of the same element
488  {
489  locked.insert(elUtils[j]->GetId()); // and flag these nodes as locked
490  }
491  }
492  }
493 
494  // identify nodes which are not sorted, yet and create new "remain" vector
495  vector<NodeSharedPtr> tmp = remain;
496  remain.clear();
497  for (int i = 0; i < tmp.size(); i++)
498  {
499  set<int>::iterator sit = completed.find(tmp[i]->m_id);
500  if (sit == completed.end())
501  {
502  remain.push_back(tmp[i]);
503  }
504  }
505 
506  // include layer or colourset into vector of coloursets
507  retPart.push_back(layer);
508 
509  // print out progress
510  if(m_mesh->m_verbose)
511  {
512  LibUtilities::PrintProgressbar(m_res->n - remain.size(), m_res->n, "Node Coloring");
513  }
514 
515  }
516  return retPart;
517 }
518 
519 
520 void ProcessVarOpti::GetElementMap(
521  int o, map<LibUtilities::ShapeType, DerivUtilSharedPtr> derMap)
522 {
523  for (int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++)
524  {
525  ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i];
526  vector<NodeSharedPtr> ns;
527  el->GetCurvedNodes(ns);
528  ElUtilSharedPtr d = boost::shared_ptr<ElUtil>(new ElUtil(
529  el, derMap[el->GetShapeType()], m_res, m_mesh->m_nummode, o));
530  m_dataSet.push_back(d);
531  }
532 
533  for (int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); i++)
534  {
535  ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i];
536  vector<NodeSharedPtr> ns;
537  el->GetCurvedNodes(ns);
538 
539  for (int j = 0; j < ns.size(); j++)
540  {
541  m_nodeElMap[ns[j]->m_id].push_back(m_dataSet[i]);
542  }
543 
544  ASSERTL0(derMap[el->GetShapeType()]->ptsStd == ns.size(),
545  "mismatch node count");
546  }
547 }
548 
549 vector<ElUtilSharedPtr> ProcessVarOpti::GetLockedElements(NekDouble thres)
550 {
551  vector<ElUtilSharedPtr> elBelowThres;
552  for (int i = 0; i < m_dataSet.size(); ++i)
553  {
554  if (m_dataSet[i]->GetScaledJac() < thres)
555  {
556  elBelowThres.push_back(m_dataSet[i]);
557  }
558  }
559 
560  boost::unordered_set<int> inmesh;
562  vector<ElUtilSharedPtr> totest;
563 
564  for (int i = 0; i < elBelowThres.size(); i++)
565  {
566  t = inmesh.insert(elBelowThres[i]->GetId());
567 
568  vector<FaceSharedPtr> f = elBelowThres[i]->GetEl()->GetFaceList();
569  for (int j = 0; j < f.size(); j++)
570  {
571  for (int k = 0; k < f[j]->m_elLink.size(); k++)
572  {
573  if (f[j]->m_elLink[k].first->GetId() ==
574  elBelowThres[i]->GetId())
575  continue;
576 
577  t = inmesh.insert(f[j]->m_elLink[k].first->GetId());
578  if (t.second)
579  {
580  totest.push_back(
581  m_dataSet[f[j]->m_elLink[k].first->GetId()]);
582  }
583  }
584  }
585  }
586 
587  for (int i = 0; i < 6; i++)
588  {
589  vector<ElUtilSharedPtr> tmp = totest;
590  totest.clear();
591  for (int j = 0; j < tmp.size(); j++)
592  {
593  vector<FaceSharedPtr> f = tmp[j]->GetEl()->GetFaceList();
594  for (int k = 0; k < f.size(); k++)
595  {
596  for (int l = 0; l < f[k]->m_elLink.size(); l++)
597  {
598  if (f[k]->m_elLink[l].first->GetId() == tmp[j]->GetId())
599  continue;
600 
601  t = inmesh.insert(f[k]->m_elLink[l].first->GetId());
602  if (t.second)
603  {
604  totest.push_back(
605  m_dataSet[f[k]->m_elLink[l].first->GetId()]);
606  }
607  }
608  }
609  }
610  }
611 
612  // now need to invert the list
613  vector<ElUtilSharedPtr> ret;
614  for (int i = 0; i < m_dataSet.size(); ++i)
615  {
617  inmesh.find(m_dataSet[i]->GetId());
618  if (s == inmesh.end())
619  {
620  ret.push_back(m_dataSet[i]);
621  }
622  }
623 
624  return ret;
625 }
626 
627 void ProcessVarOpti::RemoveLinearCurvature()
628 {
629  for(int i = 0; i < m_dataSet.size(); i++)
630  {
631  if(m_dataSet[i]->GetScaledJac() > 0.999)
632  {
633  ElementSharedPtr el = m_dataSet[i]->GetEl();
634  vector<NodeSharedPtr> ns;
635  el->SetVolumeNodes(ns);
636  }
637  }
638 
639  map<int, vector<FaceSharedPtr> > edgeToFace;
640 
641  FaceSet::iterator fit;
642  for(fit = m_mesh->m_faceSet.begin(); fit != m_mesh->m_faceSet.end(); fit++)
643  {
644  bool rm = true;
645  for(int i = 0; i < (*fit)->m_elLink.size(); i++)
646  {
647  int id = (*fit)->m_elLink[i].first->GetId();
648  if(m_dataSet[id]->GetScaledJac() <= 0.999)
649  {
650  rm = false;
651  break;
652  }
653  }
654  if(rm)
655  {
656  (*fit)->m_faceNodes.clear();
657  }
658 
659  vector<EdgeSharedPtr> es = (*fit)->m_edgeList;
660  for(int i = 0; i < es.size(); i++)
661  {
662  edgeToFace[es[i]->m_id].push_back(*fit);
663  }
664  }
665 
666  EdgeSet::iterator eit;
667  for(eit = m_mesh->m_edgeSet.begin(); eit != m_mesh->m_edgeSet.end(); eit++)
668  {
669  map<int, vector<FaceSharedPtr> >::iterator it;
670  it = edgeToFace.find((*eit)->m_id);
671  ASSERTL0(it != edgeToFace.end(),"not found");
672  bool rm = true;
673  for(int i = 0; i < it->second.size(); i++)
674  {
675  if(it->second[i]->m_faceNodes.size() > 0)
676  {
677  rm = false;
678  break;
679  }
680  }
681  if(rm)
682  {
683  (*eit)->m_edgeNodes.clear();
684  }
685  }
686 }
687 
688 }
689 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
int PrintProgressbar(const int position, const int goal, const string message, int lastprogress=-1)
Prints a progressbar.
Definition: Progressbar.hpp:69
A class to assist in the construction of nodal simplex and hybrid elements in two and three dimension...
Definition: NodalUtil.h:84
Specialisation of the NodalUtil class to support nodal triangular elements.
Definition: NodalUtil.h:170
STL namespace.
boost::unordered_set< NodeSharedPtr, NodeHash > NodeSet
Definition: Node.h:441
3D Nodal Symmetric positive internal tet (Whitherden, Vincent)
Definition: PointsType.h:78
SharedMatrix GetVandermondeForDeriv(int dir)
Return the Vandermonde matrix of the derivative of the basis functions for the nodal distribution...
Definition: NodalUtil.cpp:135
SharedMatrix GetInterpolationMatrix(Array< OneD, Array< OneD, NekDouble > > &xi)
Construct the interpolation matrix used to evaluate the basis at the points xi inside the element...
Definition: NodalUtil.cpp:202
const vector< int > & value_vector
Specialisation of the NodalUtil class to support nodal hex elements.
Definition: NodalUtil.h:353
3D Nodal Electrostatic Points on a Tetrahedron
Definition: PointsType.h:74
PointsManagerT & PointsManager(void)
Defines a specification for a set of points.
Definition: Points.h:58
double NekDouble
Specialisation of the NodalUtil class to support nodal prismatic elements.
Definition: NodalUtil.h:264
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
SharedMatrix GetVandermonde()
Return the Vandermonde matrix for the nodal distribution.
Definition: NodalUtil.cpp:102
NodeComparator(const vector< int > &val_vec)
boost::shared_ptr< DerivUtil > DerivUtilSharedPtr
Definition: ElUtil.h:51
Specialisation of the NodalUtil class to support nodal quad elements.
Definition: NodalUtil.h:312
boost::shared_ptr< Element > ElementSharedPtr
Definition: Edge.h:49
boost::shared_ptr< ElUtil > ElUtilSharedPtr
Definition: ElUtil.h:114
2D Nodal Electrostatic Points on a Triangle
Definition: PointsType.h:70
3D electrostatically spaced points on a Prism
Definition: PointsType.h:76
Specialisation of the NodalUtil class to support nodal tetrahedral elements.
Definition: NodalUtil.h:215
2D Nodal Symmetric positive internal triangle (Whitherden, Vincent)
Definition: PointsType.h:77