Nektar++
Classes | Typedefs | Enumerations | Functions | Variables
Nektar::Utilities Namespace Reference

Classes

struct  cmpop
 
struct  DerivUtil
 
struct  EdgeInfo
 
struct  ElmtConfigHash
 
class  ElUtil
 
class  ElUtilJob
 
struct  GmshEntity
 Representation of Gmsh entity so that we can extract physical tag IDs. More...
 
class  InputGmsh
 
class  InputMCF
 
class  InputNek
 
class  InputNek5000
 
class  InputNekpp
 
class  InputPly
 Converter for Ply files. More...
 
class  InputSem
 
class  InputStar
 Converter for VTK files. More...
 
class  InputSwan
 Converter for Swansea mesh format. More...
 
class  InputTec
 Converter for VTK files. More...
 
class  InputVtk
 Converter for VTK files. More...
 
class  NodalUtilTriMonomial
 
struct  NodeComparator
 
class  NodeOpti
 
class  NodeOpti1D3D
 
class  NodeOpti2D2D
 
class  NodeOpti2D3D
 
class  NodeOpti3D3D
 
class  NodeOptiJob
 
class  OutputGmsh
 Converter for Gmsh files. More...
 
class  OutputNekpp
 Converter for Gmsh files. More...
 
class  OutputSTL
 
class  OutputVtk
 Converter for Gmsh files. More...
 
class  ProcessBL
 This processing module calculates the Jacobian of elements using SpatialDomains::GeomFactors and the Element::GetGeom method. For now it simply prints a list of elements which have negative Jacobian. More...
 
class  ProcessCurve
 
class  ProcessCurvedEdges
 
class  ProcessCyl
 
class  ProcessDetectSurf
 This processing module calculates the Jacobian of elements using SpatialDomains::GeomFactors and the Element::GetGeom method. For now it simply prints a list of elements which have negative Jacobian. More...
 
class  ProcessExtractSurf
 This processing module calculates the Jacobian of elements using SpatialDomains::GeomFactors and the Element::GetGeom method. For now it simply prints a list of elements which have negative Jacobian. More...
 
class  ProcessExtractTetPrismInterface
 Module to extract interface between prismatic and tetrahedral elements. More...
 
class  ProcessExtrude
 This processing module extrudes a 2d mesh in the z direction. More...
 
class  ProcessInsertSurface
 This processing module calculates the Jacobian of elements using SpatialDomains::GeomFactors and the Element::GetGeom method. For now it simply prints a list of elements which have negative Jacobian. More...
 
class  ProcessJac
 This processing module calculates the Jacobian of elements using SpatialDomains::GeomFactors and the Element::GetGeom method. For now it simply prints a list of elements which have negative Jacobian. More...
 
class  ProcessLinear
 This processing module removes all the high-order information from the mesh leaving just the linear elements. More...
 
class  ProcessLinkCheck
 This processing module calculates the Jacobian of elements using SpatialDomains::GeomFactors and the Element::GetGeom method. For now it simply prints a list of elements which have negative Jacobian. More...
 
class  ProcessOptiExtract
 
class  ProcessPerAlign
 
class  ProcessProjectCAD
 
class  ProcessScalar
 This processing module calculates the Jacobian of elements using SpatialDomains::GeomFactors and the Element::GetGeom method. For now it simply prints a list of elements which have negative Jacobian. More...
 
class  ProcessSpherigon
 
class  ProcessTetSplit
 This processing module calculates the Jacobian of elements using SpatialDomains::GeomFactors and the Element::GetGeom method. For now it simply prints a list of elements which have negative Jacobian. More...
 
class  ProcessVarOpti
 
struct  Residual
 
struct  SplitEdgeHelper
 
struct  SplitMapHelper
 

Typedefs

typedef std::tuple< int, int, int > Mode
 
typedef std::shared_ptr< InputPlyInputPlySharedPtr
 
typedef std::pair< int, int > ipair
 
typedef std::shared_ptr< DerivUtilDerivUtilSharedPtr
 
typedef std::shared_ptr< ResidualResidualSharedPtr
 
typedef std::shared_ptr< ElUtilElUtilSharedPtr
 
typedef std::shared_ptr< NodeOptiNodeOptiSharedPtr
 
typedef LibUtilities::NekFactory< int, NodeOpti, NodeSharedPtr, std::vector< ElUtilSharedPtr >, ResidualSharedPtr, std::map< LibUtilities::ShapeType, DerivUtilSharedPtr >, optiTypeNodeOptiFactory
 

Enumerations

enum  NekCurve { eFile, eRecon }
 
enum  optiType { eLinEl, eWins, eRoca, eHypEl }
 

Functions

std::vector< int > quadTensorNodeOrdering (const std::vector< int > &nodes, int n)
 Reorder Gmsh nodes so that they appear in a tensor product format suitable for the interior of a Nektar++ quadrilateral. More...
 
std::vector< int > triTensorNodeOrdering (const std::vector< int > &nodes, int n)
 Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Nektar++ triangle. More...
 
std::vector< int > tetTensorNodeOrdering (const std::vector< int > &nodes, int n)
 Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Nektar++ tetrahedron. More...
 
std::vector< int > prismTensorNodeOrdering (const std::vector< int > &nodes, int n)
 Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Nektar++ prism. This routine is specifically designed for interior Gmsh nodes only. More...
 
std::vector< int > hexTensorNodeOrdering (const std::vector< int > &nodes, int n)
 Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Nektar++ hexahedron. More...
 
static void PrismLineFaces (int prismid, map< int, int > &facelist, vector< vector< int > > &FacesToPrisms, vector< vector< int > > &PrismsToFaces, vector< bool > &PrismDone)
 
static void PrismLineFaces (int prismid, map< int, int > &facelist, vector< vector< int > > &FacesToPrisms, vector< vector< int > > &PrismsToFaces, vector< bool > &PrismDone)
 
bool operator== (NekMeshUtils::ElmtConfig const &p1, NekMeshUtils::ElmtConfig const &p2)
 
template<typename T >
void TestElmts (const std::map< int, std::shared_ptr< T > > &geomMap, SpatialDomains::MeshGraphSharedPtr &graph, LibUtilities::Interpreter &strEval, int exprId)
 
int ** helper2d (int lda, int arr[][2])
 
int ** helper2d (int lda, int arr[][4])
 
template<int DIM>
NekDouble Determinant (NekDouble jac[][DIM])
 Calculate determinant of input matrix. More...
 
template<>
NekDouble Determinant< 2 > (NekDouble jac[][2])
 
template<>
NekDouble Determinant< 3 > (NekDouble jac[][3])
 
template<int DIM>
void InvTrans (NekDouble in[][DIM], NekDouble out[][DIM])
 Calculate inverse transpose of input matrix. More...
 
template<>
void InvTrans< 2 > (NekDouble in[][2], NekDouble out[][2])
 
template<>
void InvTrans< 3 > (NekDouble in[][3], NekDouble out[][3])
 
template<int DIM>
NekDouble ScalarProd (NekDouble(&in1)[DIM], NekDouble(&in2)[DIM])
 Calculate Scalar product of input vectors. More...
 
template<>
NekDouble ScalarProd< 2 > (NekDouble(&in1)[2], NekDouble(&in2)[2])
 
template<>
NekDouble ScalarProd< 3 > (NekDouble(&in1)[3], NekDouble(&in2)[3])
 
template<int DIM>
void EMatrix (NekDouble in[][DIM], NekDouble out[][DIM])
 Calculate \( E = F^\top F - I \) tensor used in derivation of linear elasticity gradients. More...
 
template<>
void EMatrix< 2 > (NekDouble in[][2], NekDouble out[][2])
 
template<>
void EMatrix< 3 > (NekDouble in[][3], NekDouble out[][3])
 
template<int DIM>
NekDouble FrobProd (NekDouble in1[][DIM], NekDouble in2[][DIM])
 Calculate Frobenius inner product of input matrices. More...
 
template<>
NekDouble FrobProd< 2 > (NekDouble in1[][2], NekDouble in2[][2])
 
template<>
NekDouble FrobProd< 3 > (NekDouble in1[][3], NekDouble in2[][3])
 
template<int DIM>
NekDouble FrobeniusNorm (NekDouble inarray[][DIM])
 Calculate Frobenius norm \( \| A \|_f ^2 \) of a matrix \( A \). More...
 
template<>
NekDouble FrobeniusNorm< 2 > (NekDouble inarray[][2])
 
template<>
NekDouble FrobeniusNorm< 3 > (NekDouble inarray[][3])
 
NodeOptiFactoryGetNodeOptiFactory ()
 

Variables

const NekDouble prismU1 [6] = {-1.0, 1.0, 1.0,-1.0,-1.0,-1.0}
 
const NekDouble prismV1 [6] = {-1.0,-1.0, 1.0, 1.0,-1.0, 1.0}
 
const NekDouble prismW1 [6] = {-1.0,-1.0,-1.0,-1.0, 1.0, 1.0}
 
std::mutex mtx2
 
std::mutex mtx
 

Typedef Documentation

◆ DerivUtilSharedPtr

Definition at line 50 of file ElUtil.h.

◆ ElUtilSharedPtr

typedef std::shared_ptr<ElUtil> Nektar::Utilities::ElUtilSharedPtr

Definition at line 113 of file ElUtil.h.

◆ InputPlySharedPtr

Definition at line 67 of file InputPly.h.

◆ ipair

typedef std::pair<int, int> Nektar::Utilities::ipair

Definition at line 52 of file ProcessTetSplit.cpp.

◆ Mode

typedef std::tuple<int, int, int> Nektar::Utilities::Mode

Definition at line 220 of file InputGmsh.cpp.

◆ NodeOptiFactory

Definition at line 140 of file NodeOpti.h.

◆ NodeOptiSharedPtr

Definition at line 135 of file NodeOpti.h.

◆ ResidualSharedPtr

typedef std::shared_ptr< Residual > Nektar::Utilities::ResidualSharedPtr

Definition at line 53 of file ElUtil.h.

Enumeration Type Documentation

◆ NekCurve

Enumerator
eFile 
eRecon 

Definition at line 50 of file InputNek.h.

◆ optiType

Enumerator
eLinEl 
eWins 
eRoca 
eHypEl 

Definition at line 60 of file ProcessVarOpti.h.

Function Documentation

◆ Determinant()

template<int DIM>
NekDouble Nektar::Utilities::Determinant ( NekDouble  jac[][DIM])
inline

Calculate determinant of input matrix.

Specialised versions of this function exist only for 2x2 and 3x3 matrices.

Parameters
jacInput matrix
Returns
Jacobian of jac.

Definition at line 54 of file Evaluator.hxx.

Referenced by Nektar::Utilities::NodeOpti::GetFunctional().

55 {
56  boost::ignore_unused(jac);
57  return 0.0;
58 }

◆ Determinant< 2 >()

template<>
NekDouble Nektar::Utilities::Determinant< 2 > ( NekDouble  jac[][2])
inline

Definition at line 60 of file Evaluator.hxx.

Referenced by InvTrans< 2 >().

61 {
62  return jac[0][0] * jac[1][1] - jac[0][1] * jac[1][0];
63 }

◆ Determinant< 3 >()

template<>
NekDouble Nektar::Utilities::Determinant< 3 > ( NekDouble  jac[][3])
inline

Definition at line 65 of file Evaluator.hxx.

Referenced by InvTrans< 3 >(), and Nektar::Utilities::NodeOpti::MinEigen().

66 {
67  return jac[0][0] * (jac[1][1] * jac[2][2] - jac[2][1] * jac[1][2]) -
68  jac[0][1] * (jac[1][0] * jac[2][2] - jac[1][2] * jac[2][0]) +
69  jac[0][2] * (jac[1][0] * jac[2][1] - jac[1][1] * jac[2][0]);
70 }

◆ EMatrix()

template<int DIM>
void Nektar::Utilities::EMatrix ( NekDouble  in[][DIM],
NekDouble  out[][DIM] 
)
inline

Calculate \( E = F^\top F - I \) tensor used in derivation of linear elasticity gradients.

Specialised versions of this function exist only for 2x2 and 3x3 matrices.

Parameters
inInput matrix \( F \)
outOutput matrix \( F^\top F - I \)

Definition at line 164 of file Evaluator.hxx.

165 {
166  boost::ignore_unused(in,out);
167 }

◆ EMatrix< 2 >()

template<>
void Nektar::Utilities::EMatrix< 2 > ( NekDouble  in[][2],
NekDouble  out[][2] 
)
inline

Definition at line 169 of file Evaluator.hxx.

170 {
171  out[0][0] = 0.5 * (in[0][0] * in[0][0] + in[1][0] * in[1][0] - 1.0);
172  out[1][0] = 0.5 * (in[0][0] * in[0][1] + in[1][0] * in[1][1]);
173  out[0][1] = 0.5 * (in[0][0] * in[0][1] + in[1][0] * in[1][1]);
174  out[1][1] = 0.5 * (in[1][1] * in[1][1] + in[0][1] * in[0][1] - 1.0);
175 }

◆ EMatrix< 3 >()

template<>
void Nektar::Utilities::EMatrix< 3 > ( NekDouble  in[][3],
NekDouble  out[][3] 
)
inline

Definition at line 177 of file Evaluator.hxx.

178 {
179  out[0][0] = 0.5 * (in[0][0] * in[0][0] + in[1][0] * in[1][0] +
180  in[2][0] * in[2][0] - 1.0);
181  out[1][0] = 0.5 * (in[0][0] * in[1][0] + in[1][0] * in[1][1] +
182  in[2][0] * in[2][1]);
183  out[0][1] = out[1][0];
184  out[2][0] = 0.5 * (in[0][0] * in[0][2] + in[1][0] * in[1][2] +
185  in[2][0] * in[2][2]);
186  out[0][2] = out[2][0];
187  out[1][1] = 0.5 * (in[0][1] * in[0][1] + in[1][1] * in[1][1] +
188  in[2][1] * in[2][1] - 1.0);
189  out[1][2] = 0.5 * (in[0][1] * in[0][2] + in[1][1] * in[1][2] +
190  in[2][1] * in[2][2]);
191  out[2][1] = out[1][2];
192  out[2][2] = 0.5 * (in[0][2] * in[0][2] + in[1][2] * in[1][2] +
193  in[2][2] * in[2][2] - 1.0);
194 }

◆ FrobeniusNorm()

template<int DIM>
NekDouble Nektar::Utilities::FrobeniusNorm ( NekDouble  inarray[][DIM])
inline

Calculate Frobenius norm \( \| A \|_f ^2 \) of a matrix \( A \).

Parameters
inarrayInput matrix \( A \)

Definition at line 238 of file Evaluator.hxx.

Referenced by Nektar::Utilities::NodeOpti::GetFunctional().

239 {
240  boost::ignore_unused(inarray);
241  return 0.0;
242 }

◆ FrobeniusNorm< 2 >()

template<>
NekDouble Nektar::Utilities::FrobeniusNorm< 2 > ( NekDouble  inarray[][2])
inline

Definition at line 245 of file Evaluator.hxx.

246 {
247  return inarray[0][0] * inarray[0][0]
248  + inarray[0][1] * inarray[0][1]
249  + inarray[1][0] * inarray[1][0]
250  + inarray[1][1] * inarray[1][1] ;
251 }

◆ FrobeniusNorm< 3 >()

template<>
NekDouble Nektar::Utilities::FrobeniusNorm< 3 > ( NekDouble  inarray[][3])
inline

Definition at line 254 of file Evaluator.hxx.

255 {
256  return inarray[0][0] * inarray[0][0]
257  + inarray[0][1] * inarray[0][1]
258  + inarray[0][2] * inarray[0][2]
259  + inarray[1][0] * inarray[1][0]
260  + inarray[1][1] * inarray[1][1]
261  + inarray[1][2] * inarray[1][2]
262  + inarray[2][0] * inarray[2][0]
263  + inarray[2][1] * inarray[2][1]
264  + inarray[2][2] * inarray[2][2] ;
265 }

◆ FrobProd()

template<int DIM>
NekDouble Nektar::Utilities::FrobProd ( NekDouble  in1[][DIM],
NekDouble  in2[][DIM] 
)
inline

Calculate Frobenius inner product of input matrices.

Definition at line 202 of file Evaluator.hxx.

204 {
205  boost::ignore_unused(in1,in2);
206  return 0.0;
207 }

◆ FrobProd< 2 >()

template<>
NekDouble Nektar::Utilities::FrobProd< 2 > ( NekDouble  in1[][2],
NekDouble  in2[][2] 
)
inline

Definition at line 210 of file Evaluator.hxx.

211 {
212  return in1[0][0] * in2[0][0]
213  + in1[0][1] * in2[0][1]
214  + in1[1][0] * in2[1][0]
215  + in1[1][1] * in2[1][1] ;
216 }

◆ FrobProd< 3 >()

template<>
NekDouble Nektar::Utilities::FrobProd< 3 > ( NekDouble  in1[][3],
NekDouble  in2[][3] 
)
inline

Definition at line 219 of file Evaluator.hxx.

220 {
221  return in1[0][0] * in2[0][0]
222  + in1[0][1] * in2[0][1]
223  + in1[0][2] * in2[0][2]
224  + in1[1][0] * in2[1][0]
225  + in1[1][1] * in2[1][1]
226  + in1[1][2] * in2[1][2]
227  + in1[2][0] * in2[2][0]
228  + in1[2][1] * in2[2][1]
229  + in1[2][2] * in2[2][2] ;
230 }

◆ GetNodeOptiFactory()

NodeOptiFactory & Nektar::Utilities::GetNodeOptiFactory ( )

Definition at line 51 of file NodeOpti.cpp.

Referenced by Nektar::Utilities::ProcessVarOpti::Analytics(), Nektar::Utilities::NodeOpti::CalcMinJac(), Nektar::Utilities::NodeOpti1D3D::Optimise(), Nektar::Utilities::NodeOpti2D2D::Optimise(), and Nektar::Utilities::ProcessVarOpti::Process().

52 {
53  static NodeOptiFactory asd;
54  return asd;
55 }
LibUtilities::NekFactory< int, NodeOpti, NodeSharedPtr, std::vector< ElUtilSharedPtr >, ResidualSharedPtr, std::map< LibUtilities::ShapeType, DerivUtilSharedPtr >, optiType > NodeOptiFactory
Definition: NodeOpti.h:140

◆ helper2d() [1/2]

int** Nektar::Utilities::helper2d ( int  lda,
int  arr[][2] 
)

Definition at line 61 of file ProcessBL.cpp.

Referenced by Nektar::Utilities::ProcessBL::BoundaryLayer3D().

62 {
63  int **ret = new int *[lda];
64  for (int i = 0; i < lda; ++i)
65  {
66  ret[i] = new int[2];
67  ret[i][0] = arr[i][0];
68  ret[i][1] = arr[i][1];
69  }
70  return ret;
71 }

◆ helper2d() [2/2]

int** Nektar::Utilities::helper2d ( int  lda,
int  arr[][4] 
)

Definition at line 73 of file ProcessBL.cpp.

74 {
75  int **ret = new int *[lda];
76  for (int i = 0; i < lda; ++i)
77  {
78  ret[i] = new int[4];
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];
83  }
84  return ret;
85 }

◆ hexTensorNodeOrdering()

std::vector<int> Nektar::Utilities::hexTensorNodeOrdering ( const std::vector< int > &  nodes,
int  n 
)

Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Nektar++ hexahedron.

For an example, consider a second order hexahedron. This routine will produce a permutation map that applies the following permutation:

3----13----2 6----7-----8
|\ |\ |\ |\
|15 24 | 14 |15 16 | 18
9 \ 20 11 \ 3 \ 4 5 \
| 7----19+---6 | 24---25+---26
|22 | 26 | 23| |12 | 13 | 14|
0---+-8----1 | 0---+-1----2 |
\ 17 25 \ 18 \ 21 22 \ 23
10 | 21 12| 9 | 10 11|
\| \| \| \|
4----16----5 18---19----20
Gmsh tensor-product

We assume that Gmsh uses a recursive ordering system, so that interior nodes are reordered by calling this function recursively.

Parameters
nodesThe integer IDs of the nodes to be reordered, in Gmsh format.
nThe number of nodes in one coordinate direction. If this is zero we assume no reordering needs to be done and return the identity permutation.
Returns
The nodes vector in tensor-product ordering.

Definition at line 539 of file InputGmsh.cpp.

References Nektar::StdRegions::eDir1BwdDir1_Dir2FwdDir2, Nektar::StdRegions::eDir1FwdDir1_Dir2FwdDir2, Nektar::StdRegions::eDir1FwdDir2_Dir2FwdDir1, and quadTensorNodeOrdering().

Referenced by Nektar::Utilities::InputGmsh::HexReordering().

540 {
541  int i, j, k;
542  std::vector<int> nodeList;
543 
544  nodeList.resize(nodes.size());
545  nodeList[0] = nodes[0];
546 
547  if (n == 1)
548  {
549  return nodeList;
550  }
551 
552  // Vertices: same order as Nektar++
553  nodeList[n - 1] = nodes[1];
554  nodeList[n*n -1] = nodes[2];
555  nodeList[n*(n-1)] = nodes[3];
556  nodeList[n*n*(n-1)] = nodes[4];
557  nodeList[n - 1 + n*n*(n-1)] = nodes[5];
558  nodeList[n*n -1 + n*n*(n-1)] = nodes[6];
559  nodeList[n*(n-1) + n*n*(n-1)] = nodes[7];
560 
561  if (n == 2)
562  {
563  return nodeList;
564  }
565 
566  int hexEdges[12][2] = {
567  { 0, 1 }, { n-1, n }, { n*n-1, -1 }, { n*(n-1), -n },
568  { 0, n*n }, { n-1, n*n }, { n*n - 1, n*n }, { n*(n-1), n*n },
569  { n*n*(n-1), 1 }, { n*n*(n-1) + n-1, n }, { n*n*n-1, -1 },
570  { n*n*(n-1) + n*(n-1), -n }
571  };
572  int hexFaces[6][3] = {
573  { 0, 1, n }, { 0, 1, n*n }, { n-1, n, n*n },
574  { n*(n-1), 1, n*n }, { 0, n, n*n }, { n*n*(n-1), 1, n }
575  };
576  int gmshToNekEdge[12] = {0, -3, 4, 1, 5, 2, 6, 7, 8, -11, 9, 10};
577 
578  // Edges
579  int offset = 8;
580  for (int i = 0; i < 12; ++i)
581  {
582  int e = abs(gmshToNekEdge[i]);
583 
584  if (gmshToNekEdge[i] >= 0)
585  {
586  for (int j = 1; j < n-1; ++j)
587  {
588  nodeList[hexEdges[e][0] + j*hexEdges[e][1]] = nodes[offset++];
589  }
590  }
591  else
592  {
593  for (int j = 1; j < n-1; ++j)
594  {
595  nodeList[hexEdges[e][0] + (n-j-1)*hexEdges[e][1]] = nodes[offset++];
596  }
597  }
598  }
599 
600  // Faces
601  int gmsh2NekFace[6] = {0, 1, 4, 2, 3, 5};
602 
603  // Map which defines orientation between Gmsh and Nektar++ faces.
604  StdRegions::Orientation faceOrient[6] = {
610  StdRegions::eDir1FwdDir1_Dir2FwdDir2};
611 
612  for (i = 0; i < 6; ++i)
613  {
614  int n2 = (n-2)*(n-2);
615  int face = gmsh2NekFace[i];
616  offset = 8 + 12 * (n-2) + i * n2;
617 
618  // Create a list of interior face nodes for this face only.
619  vector<int> faceNodes(n2);
620  for (j = 0; j < n2; ++j)
621  {
622  faceNodes[j] = nodes[offset + j];
623  }
624 
625  // Now get the reordering of this face, which puts Gmsh
626  // recursive ordering into Nektar++ row-by-row order.
627  faceNodes = quadTensorNodeOrdering(faceNodes, n-2);
628  vector<int> tmp(n2);
629 
630  // Finally reorient the face according to the geometry
631  // differences.
632  if (faceOrient[i] == StdRegions::eDir1FwdDir1_Dir2FwdDir2)
633  {
634  // Orientation is the same, just copy.
635  tmp = faceNodes;
636  }
637  else if (faceOrient[i] == StdRegions::eDir1FwdDir2_Dir2FwdDir1)
638  {
639  // Tranposed faces
640  for (j = 0; j < n-2; ++j)
641  {
642  for (k = 0; k < n-2; ++k)
643  {
644  tmp[j * (n-2) + k] = faceNodes[k * (n-2) + j];
645  }
646  }
647  }
648  else if (faceOrient[i] == StdRegions::eDir1BwdDir1_Dir2FwdDir2)
649  {
650  for (j = 0; j < n-2; ++j)
651  {
652  for (k = 0; k < n-2; ++k)
653  {
654  tmp[j * (n-2) + k] = faceNodes[j * (n-2) + (n - k - 3)];
655  }
656  }
657  }
658 
659  // Now put this into the right place in the output array
660  for (k = 1; k < n-1; ++k)
661  {
662  for (j = 1; j < n-1; ++j)
663  {
664  nodeList[hexFaces[face][0] + j*hexFaces[face][1] + k*hexFaces[face][2]]
665  = faceNodes[(k-1)*(n-2) + j-1];
666  }
667  }
668  }
669 
670  // Finally, recurse on interior volume
671  vector<int> intNodes, tmpInt;
672  for (int i = 8 + 12 * (n-2) + 6 * (n-2) * (n-2); i < n*n*n; ++i)
673  {
674  intNodes.push_back(nodes[i]);
675  }
676 
677  if (intNodes.size())
678  {
679  tmpInt = hexTensorNodeOrdering(intNodes, n-2);
680  for (int k = 1, cnt = 0; k < n - 1; ++k)
681  {
682  for (int j = 1; j < n - 1; ++j)
683  {
684  for (int i = 1; i < n - 1; ++i)
685  {
686  nodeList[i + j * n + k * n * n] = tmpInt[cnt++];
687  }
688  }
689  }
690  }
691 
692  return nodeList;
693 }
std::vector< int > quadTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a tensor product format suitable for the interior of a Nekt...
Definition: InputGmsh.cpp:92
std::vector< int > hexTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Ne...
Definition: InputGmsh.cpp:539

◆ InvTrans()

template<int DIM>
void Nektar::Utilities::InvTrans ( NekDouble  in[][DIM],
NekDouble  out[][DIM] 
)
inline

Calculate inverse transpose of input matrix.

Specialised versions of this function exist only for 2x2 and 3x3 matrices.

Parameters
inInput matrix \( A \)
outOutput matrix \( A^{-\top} \)

Definition at line 81 of file Evaluator.hxx.

82 {
83  boost::ignore_unused(in,out);
84 }

◆ InvTrans< 2 >()

template<>
void Nektar::Utilities::InvTrans< 2 > ( NekDouble  in[][2],
NekDouble  out[][2] 
)
inline

Definition at line 86 of file Evaluator.hxx.

References Determinant< 2 >().

87 {
88  NekDouble invDet = 1.0 / Determinant<2>(in);
89 
90  out[0][0] = in[1][1] * invDet;
91  out[1][0] = -in[0][1] * invDet;
92  out[0][1] = -in[1][0] * invDet;
93  out[1][1] = in[0][0] * invDet;
94 }
NekDouble Determinant< 2 >(NekDouble jac[][2])
Definition: Evaluator.hxx:60
double NekDouble

◆ InvTrans< 3 >()

template<>
void Nektar::Utilities::InvTrans< 3 > ( NekDouble  in[][3],
NekDouble  out[][3] 
)
inline

Definition at line 96 of file Evaluator.hxx.

References Determinant< 3 >().

97 {
98  NekDouble invdet = 1.0 / Determinant<3>(in);
99 
100  out[0][0] = (in[1][1] * in[2][2] - in[2][1] * in[1][2]) * invdet;
101  out[1][0] = -(in[0][1] * in[2][2] - in[0][2] * in[2][1]) * invdet;
102  out[2][0] = (in[0][1] * in[1][2] - in[0][2] * in[1][1]) * invdet;
103  out[0][1] = -(in[1][0] * in[2][2] - in[1][2] * in[2][0]) * invdet;
104  out[1][1] = (in[0][0] * in[2][2] - in[0][2] * in[2][0]) * invdet;
105  out[2][1] = -(in[0][0] * in[1][2] - in[1][0] * in[0][2]) * invdet;
106  out[0][2] = (in[1][0] * in[2][1] - in[2][0] * in[1][1]) * invdet;
107  out[1][2] = -(in[0][0] * in[2][1] - in[2][0] * in[0][1]) * invdet;
108  out[2][2] = (in[0][0] * in[1][1] - in[1][0] * in[0][1]) * invdet;
109 }
double NekDouble
NekDouble Determinant< 3 >(NekDouble jac[][3])
Definition: Evaluator.hxx:65

◆ operator==()

bool Nektar::Utilities::operator== ( NekMeshUtils::ElmtConfig const &  p1,
NekMeshUtils::ElmtConfig const &  p2 
)

Definition at line 57 of file OutputGmsh.h.

References Nektar::NekMeshUtils::ElmtConfig::m_e, Nektar::NekMeshUtils::ElmtConfig::m_faceNodes, Nektar::NekMeshUtils::ElmtConfig::m_order, and Nektar::NekMeshUtils::ElmtConfig::m_volumeNodes.

58 {
59  return p1.m_e == p2.m_e &&
60  p1.m_faceNodes == p2.m_faceNodes &&
61  p1.m_volumeNodes == p2.m_volumeNodes &&
62  p1.m_order == p2.m_order;
63 }

◆ PrismLineFaces() [1/2]

static void Nektar::Utilities::PrismLineFaces ( int  prismid,
map< int, int > &  facelist,
vector< vector< int > > &  FacesToPrisms,
vector< vector< int > > &  PrismsToFaces,
vector< bool > &  PrismDone 
)
static

Definition at line 420 of file InputStar.cpp.

Referenced by PrismLineFaces(), Nektar::Utilities::InputTec::ReadZone(), Nektar::Utilities::InputTec::ResetNodes(), Nektar::Utilities::InputStar::ResetNodes(), and Nektar::Utilities::InputStar::SetupElements().

425 {
426  if (PrismDone[prismid] == false)
427  {
428  PrismDone[prismid] = true;
429 
430  // Add faces0
431  int face = PrismToFaces[prismid][0];
432  facelist[face] = face;
433  for (int i = 0; i < FaceToPrisms[face].size(); ++i)
434  {
435  PrismLineFaces(FaceToPrisms[face][i],
436  facelist,
437  FaceToPrisms,
438  PrismToFaces,
439  PrismDone);
440  }
441 
442  // Add faces1
443  face = PrismToFaces[prismid][1];
444  facelist[face] = face;
445  for (int i = 0; i < FaceToPrisms[face].size(); ++i)
446  {
447  PrismLineFaces(FaceToPrisms[face][i],
448  facelist,
449  FaceToPrisms,
450  PrismToFaces,
451  PrismDone);
452  }
453  }
454 }
static void PrismLineFaces(int prismid, map< int, int > &facelist, vector< vector< int > > &FacesToPrisms, vector< vector< int > > &PrismsToFaces, vector< bool > &PrismDone)
Definition: InputStar.cpp:420

◆ PrismLineFaces() [2/2]

static void Nektar::Utilities::PrismLineFaces ( int  prismid,
map< int, int > &  facelist,
vector< vector< int > > &  FacesToPrisms,
vector< vector< int > > &  PrismsToFaces,
vector< bool > &  PrismDone 
)
static

Definition at line 634 of file InputStarTec.cpp.

References PrismLineFaces().

639 {
640  if (PrismDone[prismid] == false)
641  {
642  PrismDone[prismid] = true;
643 
644  // Add faces0
645  int face = PrismToFaces[prismid][0];
646  facelist[face] = face;
647  for (int i = 0; i < FaceToPrisms[face].size(); ++i)
648  {
649  PrismLineFaces(FaceToPrisms[face][i],
650  facelist,
651  FaceToPrisms,
652  PrismToFaces,
653  PrismDone);
654  }
655 
656  // Add faces1
657  face = PrismToFaces[prismid][1];
658  facelist[face] = face;
659  for (int i = 0; i < FaceToPrisms[face].size(); ++i)
660  {
661  PrismLineFaces(FaceToPrisms[face][i],
662  facelist,
663  FaceToPrisms,
664  PrismToFaces,
665  PrismDone);
666  }
667  }
668 }
static void PrismLineFaces(int prismid, map< int, int > &facelist, vector< vector< int > > &FacesToPrisms, vector< vector< int > > &PrismsToFaces, vector< bool > &PrismDone)

◆ prismTensorNodeOrdering()

std::vector<int> Nektar::Utilities::prismTensorNodeOrdering ( const std::vector< int > &  nodes,
int  n 
)

Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Nektar++ prism. This routine is specifically designed for interior Gmsh nodes only.

Prisms are a bit of a special case, in that interior nodes are heterogeneous in the number of points they use. As an example, for a second-order interior of a fourth-order prism, this routine calculates the mapping taking us

,6 ,8
.-' | \ .-' | \
,-3 | \ ,-5 | \
,-' | \ | \ ,-' | \ | \
2 | \7-------8 2 | \6-------7
| \ | ,-' \ ,-' | \ | ,-' \ ,-'
| \,5------,0' | \,3------,4'
|,-' \ ,-' |,-' \ ,-'
1-------4' 0-------1'
Gmsh tensor-product
Todo:
Make this routine work for higher orders. The Gmsh ordering seems a little different than other elements, therefore the functionality is (for now) hard-coded to orders less than 5.
Parameters
nodesThe integer IDs of the nodes to be reordered, in Gmsh format.
nThe number of nodes in one coordinate direction. If this is zero we assume no reordering needs to be done and return the identity permutation.
Returns
The nodes vector in tensor-product ordering.

Definition at line 463 of file InputGmsh.cpp.

References ASSERTL0.

Referenced by Nektar::Utilities::InputGmsh::PrismReordering().

464 {
465  std::vector<int> nodeList;
466 
467  if (n == 0)
468  {
469  return nodeList;
470  }
471 
472  nodeList.resize(nodes.size());
473 
474  if (n == 2)
475  {
476  nodeList[0] = nodes[1];
477  nodeList[1] = nodes[0];
478  return nodeList;
479  }
480 
481  // For some reason, this ordering is different. Whereas Gmsh usually orders
482  // vertices first, followed by edges, this ordering goes VVE-VVE-VVE for the
483  // three edges that contain edge-interior information, but also vertex
484  // orientation is not the same as the original Gmsh prism. The below is done
485  // by looking at the ordering by hand and is hence why we don't support
486  // order > 4 right now.
487  if (n == 3)
488  {
489  nodeList[0] = nodes[1];
490  nodeList[1] = nodes[4];
491  nodeList[2] = nodes[2];
492  nodeList[3] = nodes[5];
493  nodeList[4] = nodes[0];
494  nodeList[5] = nodes[3];
495  nodeList[6] = nodes[7];
496  nodeList[7] = nodes[8];
497  nodeList[8] = nodes[6];
498  }
499 
500  ASSERTL0(n < 4, "Prism Gmsh input and output is incomplete for orders "
501  "larger than 4");
502 
503  return nodeList;
504 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216

◆ quadTensorNodeOrdering()

std::vector<int> Nektar::Utilities::quadTensorNodeOrdering ( const std::vector< int > &  nodes,
int  n 
)

Reorder Gmsh nodes so that they appear in a tensor product format suitable for the interior of a Nektar++ quadrilateral.

For an example, consider a second order quadrilateral. This routine will produce a permutation map that applies the following permutation:

3---6---2 6---7---8
| | | |
7 8 5 ---> 3 4 5
| | | |
0---4---1 0---1---2
Gmsh tensor-product

We assume that Gmsh uses a recursive ordering system, so that interior nodes are reordered by calling this function recursively.

Parameters
nodesThe integer IDs of the nodes to be reordered, in Gmsh format.
nThe number of nodes in one coordinate direction. If this is zero we assume no reordering needs to be done and return the identity permutation.
Returns
The nodes vector in tensor-product ordering.

Definition at line 92 of file InputGmsh.cpp.

References CellMLToNektar.pycml::copy().

Referenced by Nektar::Utilities::InputGmsh::HexReordering(), hexTensorNodeOrdering(), Nektar::Utilities::InputGmsh::PrismReordering(), and Nektar::Utilities::InputGmsh::QuadReordering().

93 {
94  std::vector<int> nodeList;
95 
96  // Triangle
97  nodeList.resize(nodes.size());
98 
99  // Vertices and edges
100  nodeList[0] = nodes[0];
101  if (n > 1)
102  {
103  nodeList[n - 1] = nodes[1];
104  nodeList[n * n - 1] = nodes[2];
105  nodeList[n * (n - 1)] = nodes[3];
106  }
107  for (int i = 1; i < n - 1; ++i)
108  {
109  nodeList[i] = nodes[4 + i - 1];
110  }
111  for (int i = 1; i < n - 1; ++i)
112  {
113  nodeList[n * n - 1 - i] = nodes[4 + 2 * (n - 2) + i - 1];
114  }
115 
116  // Interior (recursion)
117  if (n > 2)
118  {
119  // Reorder interior nodes
120  std::vector<int> interior((n - 2) * (n - 2));
121  std::copy(
122  nodes.begin() + 4 + 4 * (n - 2), nodes.end(), interior.begin());
123  interior = quadTensorNodeOrdering(interior, n - 2);
124 
125  // Copy into full node list
126  for (int j = 1; j < n - 1; ++j)
127  {
128  nodeList[j * n] = nodes[4 + 3 * (n - 2) + n - 2 - j];
129  for (int i = 1; i < n - 1; ++i)
130  {
131  nodeList[j * n + i] = interior[(j - 1) * (n - 2) + (i - 1)];
132  }
133  nodeList[(j + 1) * n - 1] = nodes[4 + (n - 2) + j - 1];
134  }
135  }
136 
137  return nodeList;
138 }
std::vector< int > quadTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a tensor product format suitable for the interior of a Nekt...
Definition: InputGmsh.cpp:92
def copy(self)
Definition: pycml.py:2663

◆ ScalarProd()

template<int DIM>
NekDouble Nektar::Utilities::ScalarProd ( NekDouble(&)  in1[DIM],
NekDouble(&)  in2[DIM] 
)
inline

Calculate Scalar product of input vectors.

Definition at line 133 of file Evaluator.hxx.

134 {
135  boost::ignore_unused(in1,in2);
136  return 0.0;
137 }

◆ ScalarProd< 2 >()

template<>
NekDouble Nektar::Utilities::ScalarProd< 2 > ( NekDouble(&)  in1[2],
NekDouble(&)  in2[2] 
)
inline

Definition at line 140 of file Evaluator.hxx.

141 {
142  return in1[0] * in2[0]
143  + in1[1] * in2[1];
144 }

◆ ScalarProd< 3 >()

template<>
NekDouble Nektar::Utilities::ScalarProd< 3 > ( NekDouble(&)  in1[3],
NekDouble(&)  in2[3] 
)
inline

Definition at line 146 of file Evaluator.hxx.

147 {
148  return in1[0] * in2[0]
149  + in1[1] * in2[1]
150  + in1[2] * in2[2];
151 }

◆ TestElmts()

template<typename T >
void Nektar::Utilities::TestElmts ( const std::map< int, std::shared_ptr< T > > &  geomMap,
SpatialDomains::MeshGraphSharedPtr graph,
LibUtilities::Interpreter strEval,
int  exprId 
)

Definition at line 89 of file OutputNekpp.cpp.

References ASSERTL0, and Nektar::LibUtilities::Interpreter::Evaluate().

Referenced by Nektar::Utilities::OutputNekpp::Process().

94 {
95  boost::ignore_unused(graph);
96 
97  for (auto &geomIt : geomMap)
98  {
99  SpatialDomains::GeometrySharedPtr geom = geomIt.second;
100  geom->Setup();
101  geom->FillGeom();
102 
103  if (exprId != -1)
104  {
105  int nq = geom->GetXmap()->GetTotPoints();
106  int dim = geom->GetCoordim();
107 
108  Array<OneD, Array<OneD, NekDouble>> coords(3);
109 
110  for (int i = 0; i < 3; ++i)
111  {
112  coords[i] = Array<OneD, NekDouble>(nq, 0.0);
113  }
114 
115  for (int i = 0; i < dim; ++i)
116  {
117  geom->GetXmap()->BwdTrans(geom->GetCoeffs(i), coords[i]);
118  }
119 
120  for (int i = 0; i < nq; ++i)
121  {
122  NekDouble output = strEval.Evaluate(
123  exprId, coords[0][i], coords[1][i], coords[2][i], 0.0);
124  ASSERTL0(output == 1.0, "Output mesh failed coordinate test");
125  }
126 
127  // Also evaluate at mid-point to test for deformed vs. regular
128  // elements.
129  Array<OneD, NekDouble> eta(dim, 0.0), evalPt(3, 0.0);
130  for (int i = 0; i < dim; ++i)
131  {
132  evalPt[i] = geom->GetXmap()->PhysEvaluate(eta, coords[i]);
133  }
134 
135  NekDouble output = strEval.Evaluate(
136  exprId, evalPt[0], evalPt[1], evalPt[2], 0.0);
137  ASSERTL0(output == 1.0,
138  "Output mesh failed coordinate midpoint test");
139  }
140  }
141 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
std::shared_ptr< Geometry > GeometrySharedPtr
Definition: Geometry.h:53
double NekDouble

◆ tetTensorNodeOrdering()

std::vector<int> Nektar::Utilities::tetTensorNodeOrdering ( const std::vector< int > &  nodes,
int  n 
)

Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Nektar++ tetrahedron.

For an example, consider a second order tetrahedron. This routine will produce a permutation map that applies the following permutation:

2 5
,/|`\ ,/|`\
,/ | `\ ,/ | `\
,6 '. `5 ,3 '. `4
,/ 8 `\ ,/ 8 `\
,/ | `\ ,/ | `\
0--------4--'.--------1 0--------1--'.--------2
`\. | ,/ `\. | ,/
`\. | ,9 `\. | ,7
`7. '. ,/ `6. '. ,/
`\. |/ `\. |/
`3 `9
Gmsh tensor-product

We assume that Gmsh uses a recursive ordering system, so that interior nodes are reordered by calling this function recursively.

Parameters
nodesThe integer IDs of the nodes to be reordered, in Gmsh format.
nThe number of nodes in one coordinate direction. If this is zero we assume no reordering needs to be done and return the identity permutation.
Returns
The nodes vector in tensor-product ordering.

Definition at line 284 of file InputGmsh.cpp.

References Nektar::NekMeshUtils::HOTriangle< T >::Align(), Nektar::NekMeshUtils::HOTriangle< T >::surfVerts, and triTensorNodeOrdering().

Referenced by Nektar::Utilities::InputGmsh::TetReordering().

285 {
286  std::vector<int> nodeList;
287  int nTri = n*(n+1)/2;
288  int nTet = n*(n+1)*(n+2)/6;
289 
290  nodeList.resize(nodes.size());
291  nodeList[0] = nodes[0];
292 
293  if (n == 1)
294  {
295  return nodeList;
296  }
297 
298  // Vertices
299  nodeList[n - 1] = nodes[1];
300  nodeList[nTri - 1] = nodes[2];
301  nodeList[nTet - 1] = nodes[3];
302 
303  if (n == 2)
304  {
305  return nodeList;
306  }
307 
308  // Set up a map that takes (a,b,c) -> m to help us figure out where things
309  // are inside the tetrahedron.
310  std::map<Mode, int, cmpop> tmp;
311 
312  for (int k = 0, cnt = 0; k < n; ++k)
313  {
314  for (int j = 0; j < n - k; ++j)
315  {
316  for (int i = 0; i < n - k - j; ++i)
317  {
318  tmp[Mode(i,j,k)] = cnt++;
319  }
320  }
321  }
322 
323  // Edges
324  for (int i = 1; i < n-1; ++i)
325  {
326  int eI = i-1;
327  nodeList[tmp[Mode(i,0,0)]] = nodes[4 + eI];
328  nodeList[tmp[Mode(n-1-i,i,0)]] = nodes[4 + (n-2) + eI];
329  nodeList[tmp[Mode(0,n-1-i,0)]] = nodes[4 + 2*(n-2) + eI];
330  nodeList[tmp[Mode(0,0,n-1-i)]] = nodes[4 + 3*(n-2) + eI];
331  nodeList[tmp[Mode(0,i,n-1-i)]] = nodes[4 + 4*(n-2) + eI];
332  nodeList[tmp[Mode(i,0,n-1-i)]] = nodes[4 + 5*(n-2) + eI];
333  }
334 
335  if (n == 3)
336  {
337  return nodeList;
338  }
339 
340  // For faces, we use the triTensorNodeOrdering routine to make our lives
341  // slightly easier.
342  int nFacePts = (n-3)*(n-2)/2;
343 
344  // Grab face points and reorder into a tensor-product type format
345  vector<vector<int> > tmpNodes(4);
346  int offset = 4 + 6*(n-2);
347 
348  for (int i = 0; i < 4; ++i)
349  {
350  tmpNodes[i].resize(nFacePts);
351  for (int j = 0; j < nFacePts; ++j)
352  {
353  tmpNodes[i][j] = nodes[offset++];
354  }
355  tmpNodes[i] = triTensorNodeOrdering(tmpNodes[i], n-3);
356  }
357 
358  if (n > 4)
359  {
360  // Now align faces
361  vector<int> triVertId(3), toAlign(3);
362  triVertId[0] = 0;
363  triVertId[1] = 1;
364  triVertId[2] = 2;
365 
366  // Faces 0,2: triangle verts {0,2,1} --> {0,1,2}
367  HOTriangle<int> hoTri(triVertId, tmpNodes[0]);
368  toAlign[0] = 0;
369  toAlign[1] = 2;
370  toAlign[2] = 1;
371 
372  hoTri.Align(toAlign);
373  tmpNodes[0] = hoTri.surfVerts;
374 
375  hoTri.surfVerts = tmpNodes[2];
376  hoTri.Align(toAlign);
377  tmpNodes[2] = hoTri.surfVerts;
378 
379  // Face 3: triangle verts {1,2,0} --> {0,1,2}
380  toAlign[0] = 1;
381  toAlign[1] = 2;
382  toAlign[2] = 0;
383 
384  hoTri.surfVerts = tmpNodes[3];
385  hoTri.Align(toAlign);
386  tmpNodes[3] = hoTri.surfVerts;
387  }
388 
389  // Now apply faces. Note that faces 3 and 2 are swapped between Gmsh and
390  // Nektar++ order.
391  for (int j = 1, cnt = 0; j < n-2; ++j)
392  {
393  for (int i = 1; i < n-j-1; ++i, ++cnt)
394  {
395  nodeList[tmp[Mode(i,j,0)]] = tmpNodes[0][cnt];
396  nodeList[tmp[Mode(i,0,j)]] = tmpNodes[1][cnt];
397  nodeList[tmp[Mode(n-1-i-j,i,j)]] = tmpNodes[3][cnt];
398  nodeList[tmp[Mode(0,i,j)]] = tmpNodes[2][cnt];
399  }
400  }
401 
402  if (n == 4)
403  {
404  return nodeList;
405  }
406 
407  // Finally, recurse on interior volume
408  vector<int> intNodes, tmpInt;
409  for (int i = offset; i < nTet; ++i)
410  {
411  intNodes.push_back(nodes[i]);
412  }
413  tmpInt = tetTensorNodeOrdering(intNodes, n-4);
414 
415  for (int k = 1, cnt = 0; k < n - 2; ++k)
416  {
417  for (int j = 1; j < n - k - 1; ++j)
418  {
419  for (int i = 1; i < n - k - j - 1; ++i)
420  {
421  nodeList[tmp[Mode(i,j,k)]] = tmpInt[cnt++];
422  }
423  }
424  }
425 
426  return nodeList;
427 }
std::vector< int > triTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Ne...
Definition: InputGmsh.cpp:169
std::tuple< int, int, int > Mode
Definition: InputGmsh.cpp:220
A lightweight struct for dealing with high-order triangle alignment.
Definition: HOAlignment.h:49
std::vector< int > tetTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Ne...
Definition: InputGmsh.cpp:284

◆ triTensorNodeOrdering()

std::vector<int> Nektar::Utilities::triTensorNodeOrdering ( const std::vector< int > &  nodes,
int  n 
)

Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Nektar++ triangle.

For an example, consider a third-order triangle. This routine will produce a permutation map that applies the following permutation:

2 9
| \ | \
7 6 7 7
| \ | \
8 9 5 4 5 6
| \ | \
0---3---4---1 0---1---2---3
Gmsh tensor-product

We assume that Gmsh uses a recursive ordering system, so that interior nodes are reordered by calling this function recursively.

Parameters
nodesThe integer IDs of the nodes to be reordered, in Gmsh format.
nThe number of nodes in one coordinate direction. If this is zero we assume no reordering needs to be done and return the identity permutation.
Returns
The nodes vector in tensor-product ordering.

Definition at line 169 of file InputGmsh.cpp.

References CellMLToNektar.pycml::copy().

Referenced by Nektar::Utilities::InputGmsh::PrismReordering(), Nektar::Utilities::InputGmsh::TetReordering(), tetTensorNodeOrdering(), and Nektar::Utilities::InputGmsh::TriReordering().

170 {
171  std::vector<int> nodeList;
172  int cnt2;
173 
174  nodeList.resize(nodes.size());
175 
176  // Vertices
177  nodeList[0] = nodes[0];
178  if (n > 1)
179  {
180  nodeList[n - 1] = nodes[1];
181  nodeList[n * (n + 1) / 2 - 1] = nodes[2];
182  }
183 
184  // Edges
185  int cnt = n;
186  for (int i = 1; i < n - 1; ++i)
187  {
188  nodeList[i] = nodes[3 + i - 1];
189  nodeList[cnt] = nodes[3 + 3 * (n - 2) - i];
190  nodeList[cnt + n - i - 1] = nodes[3 + (n - 2) + i - 1];
191  cnt += n - i;
192  }
193 
194  // Interior (recursion)
195  if (n > 3)
196  {
197  // Reorder interior nodes
198  std::vector<int> interior((n - 3) * (n - 2) / 2);
199  std::copy(
200  nodes.begin() + 3 + 3 * (n - 2), nodes.end(), interior.begin());
201  interior = triTensorNodeOrdering(interior, n - 3);
202 
203  // Copy into full node list
204  cnt = n;
205  cnt2 = 0;
206  for (int j = 1; j < n - 2; ++j)
207  {
208  for (int i = 0; i < n - j - 2; ++i)
209  {
210  nodeList[cnt + i + 1] = interior[cnt2 + i];
211  }
212  cnt += n - j;
213  cnt2 += n - 2 - j;
214  }
215  }
216 
217  return nodeList;
218 }
std::vector< int > triTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Ne...
Definition: InputGmsh.cpp:169
def copy(self)
Definition: pycml.py:2663

Variable Documentation

◆ mtx

std::mutex Nektar::Utilities::mtx

◆ mtx2

std::mutex Nektar::Utilities::mtx2

Definition at line 48 of file ElUtil.cpp.

◆ prismU1

const NekDouble Nektar::Utilities::prismU1[6] = {-1.0, 1.0, 1.0,-1.0,-1.0,-1.0}

Definition at line 54 of file ProcessProjectCAD.cpp.

◆ prismV1

const NekDouble Nektar::Utilities::prismV1[6] = {-1.0,-1.0, 1.0, 1.0,-1.0, 1.0}

Definition at line 55 of file ProcessProjectCAD.cpp.

◆ prismW1

const NekDouble Nektar::Utilities::prismW1[6] = {-1.0,-1.0,-1.0,-1.0, 1.0, 1.0}

Definition at line 56 of file ProcessProjectCAD.cpp.