Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Public Member Functions | Static Public Attributes | Protected Member Functions | Private Member Functions | Static Private Attributes | List of all members
Nektar::SpatialDomains::TetGeom Class Reference

#include <TetGeom.h>

Inheritance diagram for Nektar::SpatialDomains::TetGeom:
Inheritance graph
[legend]
Collaboration diagram for Nektar::SpatialDomains::TetGeom:
Collaboration graph
[legend]

Public Member Functions

 TetGeom ()
 TetGeom (const TriGeomSharedPtr faces[])
 ~TetGeom ()
- Public Member Functions inherited from Nektar::LibUtilities::GraphVertexObject
 GraphVertexObject ()
 GraphVertexObject (const GraphVertexID id)
int getid ()
void setid (const GraphVertexID id)
virtual ~GraphVertexObject ()
- Public Member Functions inherited from Nektar::SpatialDomains::Geometry3D
 Geometry3D ()
 Geometry3D (const int coordim)
virtual ~Geometry3D ()
int GetEid (int i) const
 Return the ID of edge i in this element.
const Geometry1DSharedPtr GetEdge (int i) const
Geometry2DSharedPtr GetFace (int i)
 Return face i in this element.
int GetDir (const int faceidx, const int facedir) const
 Returns the element coordinate direction corresponding to a given face coordinate direction.
- Public Member Functions inherited from Nektar::SpatialDomains::Geometry
 Geometry ()
 Geometry (int coordim)
virtual ~Geometry ()
bool IsElmtConnected (int gvo_id, int locid) const
void AddElmtConnected (int gvo_id, int locid)
int NumElmtConnected () const
int GetCoordim () const
void SetCoordim (int coordim)
GeomFactorsSharedPtr GetGeomFactors ()
GeomFactorsSharedPtr GetRefGeomFactors (const Array< OneD, const LibUtilities::BasisSharedPtr > &tbasis)
GeomFactorsSharedPtr GetMetricInfo ()
LibUtilities::ShapeType GetShapeType (void)
int GetGlobalID (void)
void SetGlobalID (int globalid)
int GetVid (int i) const
int GetFid (int i) const
int GetTid (int i) const
int GetNumVerts () const
PointGeomSharedPtr GetVertex (int i) const
StdRegions::Orientation GetEorient (const int i) const
StdRegions::Orientation GetPorient (const int i) const
StdRegions::Orientation GetForient (const int i) const
int GetNumEdges () const
int GetNumFaces () const
int GetShapeDim () const
StdRegions::StdExpansionSharedPtr GetXmap () const
const Array< OneD, const
NekDouble > & 
GetCoeffs (const int i) const
bool ContainsPoint (const Array< OneD, const NekDouble > &gloCoord, NekDouble tol=0.0)
bool ContainsPoint (const Array< OneD, const NekDouble > &gloCoord, Array< OneD, NekDouble > &locCoord, NekDouble tol)
bool ContainsPoint (const Array< OneD, const NekDouble > &gloCoord, Array< OneD, NekDouble > &locCoord, NekDouble tol, NekDouble &resid)
int GetVertexEdgeMap (int i, int j) const
int GetVertexFaceMap (int i, int j) const
 return the id of the $j^{th}$ face attached to the $ i^{th}$ vertex
int GetEdgeFaceMap (int i, int j) const
void FillGeom ()
 Put all quadrature information into face/edge structure and backward transform.
NekDouble GetLocCoords (const Array< OneD, const NekDouble > &coords, Array< OneD, NekDouble > &Lcoords)
NekDouble GetCoord (const int i, const Array< OneD, const NekDouble > &Lcoord)
 Given local collapsed coordinate Lcoord return the value of physical coordinate in direction i.
void SetOwnData ()
const LibUtilities::BasisSharedPtr GetBasis (const int i)
 Return the j-th basis of the i-th co-ordinate dimension.
const LibUtilities::PointsKeyVector GetPointsKeys ()

Static Public Attributes

static const int kNverts = 4
static const int kNedges = 6
static const int kNqfaces = 0
static const int kNtfaces = 4
static const int kNfaces = kNqfaces + kNtfaces
static const std::string XMLElementType

Protected Member Functions

virtual NekDouble v_GetLocCoords (const Array< OneD, const NekDouble > &coords, Array< OneD, NekDouble > &Lcoords)
 Get Local cartesian points.
virtual bool v_ContainsPoint (const Array< OneD, const NekDouble > &gloCoord, NekDouble tol=0.0)
 Determines if a point specified in global coordinates is located within this tetrahedral geometry.
virtual bool v_ContainsPoint (const Array< OneD, const NekDouble > &gloCoord, Array< OneD, NekDouble > &locCoord, NekDouble tol)
virtual bool v_ContainsPoint (const Array< OneD, const NekDouble > &gloCoord, Array< OneD, NekDouble > &locCoord, NekDouble tol, NekDouble &resid)
 Determines if a point specified in global coordinates is located within this tetrahedral geometry and return local caretsian coordinates.
virtual int v_GetNumVerts () const
virtual int v_GetNumEdges () const
virtual int v_GetNumFaces () const
virtual int v_GetVertexEdgeMap (const int i, const int j) const
virtual int v_GetVertexFaceMap (const int i, const int j) const
virtual int v_GetEdgeFaceMap (const int i, const int j) const
virtual int v_GetDir (const int faceidx, const int facedir) const
- Protected Member Functions inherited from Nektar::SpatialDomains::Geometry3D
void NewtonIterationForLocCoord (const Array< OneD, const NekDouble > &coords, const Array< OneD, const NekDouble > &ptsx, const Array< OneD, const NekDouble > &ptsy, const Array< OneD, const NekDouble > &ptsz, Array< OneD, NekDouble > &Lcoords, NekDouble &resid)
virtual void v_FillGeom ()
 Put all quadrature information into face/edge structure and backward transform.
virtual NekDouble v_GetCoord (const int i, const Array< OneD, const NekDouble > &Lcoord)
 Given local collapsed coordinate Lcoord return the value of physical coordinate in direction i.
virtual void v_GenGeomFactors ()
virtual int v_GetShapeDim () const
 Return the dimension of this element.
virtual int v_GetVid (int i) const
 Return the vertex ID of vertex i.
virtual PointGeomSharedPtr v_GetVertex (int i) const
 Return vertex i in this element.
virtual const SegGeomSharedPtr v_GetEdge (int i) const
 Return edge i of this element.
virtual StdRegions::Orientation v_GetEorient (const int i) const
 Return the orientation of edge i in this element.
virtual int v_GetEid (int i) const
 Return the ID of edge i in this element.
virtual const Geometry2DSharedPtr v_GetFace (int i) const
 Return face i in this element.
virtual StdRegions::Orientation v_GetForient (const int i) const
 Return the orientation of face i in this element.
virtual int v_GetFid (int i) const
 Return the ID of face i in this element.
virtual int v_GetEid () const
 Return the ID of this element.
virtual int v_WhichEdge (SegGeomSharedPtr edge)
 Return the local ID of a given edge.
virtual int v_WhichFace (Geometry2DSharedPtr face)
 Return the local ID of a given face.
virtual const
LibUtilities::BasisSharedPtr 
v_GetBasis (const int i)
 Return the j-th basis of the i-th co-ordinate dimension.
virtual void v_AddElmtConnected (int gvo_id, int locid)
virtual bool v_IsElmtConnected (int gvo_id, int locid) const
virtual int v_NumElmtConnected () const
virtual void v_SetOwnData ()
- Protected Member Functions inherited from Nektar::SpatialDomains::Geometry
void GenGeomFactors ()
virtual StdRegions::Orientation v_GetPorient (const int i) const
virtual
StdRegions::StdExpansionSharedPtr 
v_GetXmap () const
virtual int v_GetCoordim () const
void SetUpCoeffs (const int nCoeffs)

Private Member Functions

void SetUpLocalEdges ()
void SetUpLocalVertices ()
void SetUpEdgeOrientation ()
void SetUpFaceOrientation ()

Static Private Attributes

static const unsigned int VertexEdgeConnectivity [4][3]
static const unsigned int VertexFaceConnectivity [4][3]
static const unsigned int EdgeFaceConnectivity [6][2]

Additional Inherited Members

- Static Protected Member Functions inherited from Nektar::SpatialDomains::Geometry
static GeomFactorsSharedPtr ValidateRegGeomFactor (GeomFactorsSharedPtr geomFactor)
- Protected Attributes inherited from Nektar::LibUtilities::GraphVertexObject
GraphVertexID m_id
- Protected Attributes inherited from Nektar::SpatialDomains::Geometry3D
PointGeomVector m_verts
SegGeomVector m_edges
Geometry2DVector m_faces
std::vector
< StdRegions::Orientation
m_eorient
std::vector
< StdRegions::Orientation
m_forient
std::list< CompToElmtm_elmtmap
bool m_owndata
int m_eid
bool m_ownverts
- Static Protected Attributes inherited from Nektar::SpatialDomains::Geometry
static GeomFactorsVector m_regGeomFactorsManager

Detailed Description

Definition at line 48 of file TetGeom.h.

Constructor & Destructor Documentation

Nektar::SpatialDomains::TetGeom::TetGeom ( )
Nektar::SpatialDomains::TetGeom::TetGeom ( const TriGeomSharedPtr  faces[])

Copy the face shared pointers

Set up orientation vectors with correct amount of elements.

Determine necessary order for standard region.

Definition at line 58 of file TetGeom.cpp.

References Nektar::LibUtilities::eGaussLobattoLegendre, Nektar::LibUtilities::eGaussRadauMAlpha1Beta0, Nektar::LibUtilities::eGaussRadauMAlpha2Beta0, Nektar::LibUtilities::eModified_A, Nektar::LibUtilities::eModified_B, Nektar::LibUtilities::eModified_C, Nektar::LibUtilities::eTetrahedron, Nektar::SpatialDomains::Geometry::GetXmap(), kNedges, kNfaces, Nektar::SpatialDomains::Geometry3D::m_eorient, Nektar::SpatialDomains::Geometry3D::m_faces, Nektar::SpatialDomains::Geometry3D::m_forient, Nektar::SpatialDomains::Geometry::m_shapeType, Nektar::SpatialDomains::Geometry::m_xmap, Nektar::SpatialDomains::Geometry::SetUpCoeffs(), SetUpEdgeOrientation(), SetUpFaceOrientation(), SetUpLocalEdges(), and SetUpLocalVertices().

:
Geometry3D(faces[0]->GetEdge(0)->GetVertex(0)->GetCoordim())
{
/// Copy the face shared pointers
m_faces.insert(m_faces.begin(), faces, faces+TetGeom::kNfaces);
/// Set up orientation vectors with correct amount of elements.
m_eorient.resize(kNedges);
m_forient.resize(kNfaces);
/// Determine necessary order for standard region.
vector<int> tmp;
tmp.push_back(faces[0]->GetXmap()->GetEdgeNcoeffs(0));
int order0 = *max_element(tmp.begin(), tmp.end());
tmp.clear();
tmp.push_back(faces[0]->GetXmap()->GetEdgeNumPoints(0));
int points0 = *max_element(tmp.begin(), tmp.end());
tmp.clear();
tmp.push_back(order0);
tmp.push_back(faces[0]->GetXmap()->GetEdgeNcoeffs(1));
tmp.push_back(faces[0]->GetXmap()->GetEdgeNcoeffs(2));
int order1 = *max_element(tmp.begin(), tmp.end());
tmp.clear();
tmp.push_back(points0);
tmp.push_back(faces[0]->GetXmap()->GetEdgeNumPoints(1));
tmp.push_back(faces[0]->GetXmap()->GetEdgeNumPoints(2));
int points1 = *max_element(tmp.begin(), tmp.end());
tmp.clear();
tmp.push_back(order0);
tmp.push_back(order1);
tmp.push_back(faces[1]->GetXmap()->GetEdgeNcoeffs(1));
tmp.push_back(faces[1]->GetXmap()->GetEdgeNcoeffs(2));
tmp.push_back(faces[3]->GetXmap()->GetEdgeNcoeffs(1));
int order2 = *max_element(tmp.begin(), tmp.end());
tmp.clear();
tmp.push_back(points0);
tmp.push_back(points1);
tmp.push_back(faces[1]->GetXmap()->GetEdgeNumPoints(1));
tmp.push_back(faces[1]->GetXmap()->GetEdgeNumPoints(2));
tmp.push_back(faces[3]->GetXmap()->GetEdgeNumPoints(1));
int points2 = *max_element(tmp.begin(), tmp.end());
const LibUtilities::BasisKey A(
LibUtilities::PointsKey(points0,LibUtilities::eGaussLobattoLegendre));
const LibUtilities::BasisKey B(
LibUtilities::PointsKey(points1,LibUtilities::eGaussRadauMAlpha1Beta0));
const LibUtilities::BasisKey C(
LibUtilities::PointsKey(points2,LibUtilities::eGaussRadauMAlpha2Beta0));
m_xmap = MemoryManager<StdRegions::StdTetExp>::AllocateSharedPtr(A,B,C);
SetUpCoeffs(m_xmap->GetNcoeffs());
}
Nektar::SpatialDomains::TetGeom::~TetGeom ( )

Definition at line 126 of file TetGeom.cpp.

{
}

Member Function Documentation

void Nektar::SpatialDomains::TetGeom::SetUpEdgeOrientation ( )
private

Definition at line 527 of file TetGeom.cpp.

References ASSERTL0, Nektar::StdRegions::eBackwards, Nektar::StdRegions::eForwards, Nektar::SpatialDomains::Geometry::GetVid(), kNedges, Nektar::SpatialDomains::Geometry3D::m_edges, Nektar::SpatialDomains::Geometry3D::m_eorient, and Nektar::SpatialDomains::Geometry3D::m_verts.

Referenced by TetGeom().

{
// This 2D array holds the local id's of all the vertices
// for every edge. For every edge, they are ordered to what we
// define as being Forwards
const unsigned int edgeVerts[kNedges][2] =
{ {0,1},
{1,2},
{0,2},
{0,3},
{1,3},
{2,3} };
int i;
for(i = 0; i < kNedges; i++)
{
if( m_edges[i]->GetVid(0) == m_verts[ edgeVerts[i][0] ]->GetVid() )
{
}
else if( m_edges[i]->GetVid(0) == m_verts[ edgeVerts[i][1] ]->GetVid() )
{
}
else
{
ASSERTL0(false,"Could not find matching vertex for the edge");
}
}
};
void Nektar::SpatialDomains::TetGeom::SetUpFaceOrientation ( )
private

Definition at line 559 of file TetGeom.cpp.

References ASSERTL0, ASSERTL1, Nektar::SpatialDomains::Geometry::GetVertex(), Nektar::SpatialDomains::Geometry::GetVid(), Nektar::NekConstants::kNekZeroTol, kNfaces, kNqfaces, kNtfaces, kNverts, Nektar::SpatialDomains::Geometry::m_coordim, Nektar::SpatialDomains::Geometry3D::m_faces, Nektar::SpatialDomains::Geometry3D::m_forient, and Nektar::SpatialDomains::Geometry3D::m_verts.

Referenced by TetGeom().

{
int f,i;
// These arrays represent the vector of the A and B
// coordinate of the local elemental coordinate system
// where A corresponds with the coordinate direction xi_i
// with the lowest index i (for that particular face)
// Coordinate 'B' then corresponds to the other local
// coordinate (i.e. with the highest index)
Array<OneD,NekDouble> elementAaxis(m_coordim);
Array<OneD,NekDouble> elementBaxis(m_coordim);
// These arrays correspond to the local coordinate
// system of the face itself (i.e. the Geometry2D)
// faceAaxis correspond to the xi_0 axis
// faceBaxis correspond to the xi_1 axis
Array<OneD,NekDouble> faceAaxis(m_coordim);
Array<OneD,NekDouble> faceBaxis(m_coordim);
// This is the base vertex of the face (i.e. the Geometry2D)
// This corresponds to thevertex with local ID 0 of the
// Geometry2D
unsigned int baseVertex;
// The lenght of the vectors above
NekDouble elementAaxis_length;
NekDouble elementBaxis_length;
NekDouble faceAaxis_length;
NekDouble faceBaxis_length;
// This 2D array holds the local id's of all the vertices
// for every face. For every face, they are ordered in such
// a way that the implementation below allows a unified approach
// for all faces.
const unsigned int faceVerts[kNfaces][TriGeom::kNverts] =
{ {0,1,2} ,
{0,1,3} ,
{1,2,3} ,
{0,2,3} };
NekDouble dotproduct1 = 0.0;
NekDouble dotproduct2 = 0.0;
unsigned int orientation;
// Loop over all the faces to set up the orientation
for(f = 0; f < kNqfaces + kNtfaces; f++)
{
// initialisation
elementAaxis_length = 0.0;
elementBaxis_length = 0.0;
faceAaxis_length = 0.0;
faceBaxis_length = 0.0;
dotproduct1 = 0.0;
dotproduct2 = 0.0;
baseVertex = m_faces[f]->GetVid(0);
// We are going to construct the vectors representing the A and B axis
// of every face. These vectors will be constructed as a vector-representation
// of the edges of the face. However, for both coordinate directions, we can
// represent the vectors by two different edges. That's why we need to make sure that
// we pick the edge to which the baseVertex of the Geometry2D-representation of the face
// belongs...
// Compute the length of edges on a base-face
if( baseVertex == m_verts[ faceVerts[f][0] ]->GetVid() )
{
for(i = 0; i < m_coordim; i++)
{
elementAaxis[i] = (*m_verts[ faceVerts[f][1] ])[i] - (*m_verts[ faceVerts[f][0] ])[i];
elementBaxis[i] = (*m_verts[ faceVerts[f][2] ])[i] - (*m_verts[ faceVerts[f][0] ])[i];
}
}
else if( baseVertex == m_verts[ faceVerts[f][1] ]->GetVid() )
{
for(i = 0; i < m_coordim; i++)
{
elementAaxis[i] = (*m_verts[ faceVerts[f][1] ])[i] - (*m_verts[ faceVerts[f][0] ])[i];
elementBaxis[i] = (*m_verts[ faceVerts[f][2] ])[i] - (*m_verts[ faceVerts[f][1] ])[i];
}
}
else if( baseVertex == m_verts[ faceVerts[f][2] ]->GetVid() )
{
for(i = 0; i < m_coordim; i++)
{
elementAaxis[i] = (*m_verts[ faceVerts[f][1] ])[i] - (*m_verts[ faceVerts[f][2] ])[i];
elementBaxis[i] = (*m_verts[ faceVerts[f][2] ])[i] - (*m_verts[ faceVerts[f][0] ])[i];
}
}
else
{
ASSERTL0(false, "Could not find matching vertex for the face");
}
// Now, construct the edge-vectors of the local coordinates of
// the Geometry2D-representation of the face
for(i = 0; i < m_coordim; i++)
{
faceAaxis[i] = (*m_faces[f]->GetVertex(1))[i] - (*m_faces[f]->GetVertex(0))[i];
faceBaxis[i] = (*m_faces[f]->GetVertex(2))[i] - (*m_faces[f]->GetVertex(0))[i];
elementAaxis_length += pow(elementAaxis[i],2);
elementBaxis_length += pow(elementBaxis[i],2);
faceAaxis_length += pow(faceAaxis[i],2);
faceBaxis_length += pow(faceBaxis[i],2);
}
elementAaxis_length = sqrt(elementAaxis_length);
elementBaxis_length = sqrt(elementBaxis_length);
faceAaxis_length = sqrt(faceAaxis_length);
faceBaxis_length = sqrt(faceBaxis_length);
// Calculate the inner product of both the A-axis
// (i.e. Elemental A axis and face A axis)
for(i = 0 ; i < m_coordim; i++)
{
dotproduct1 += elementAaxis[i]*faceAaxis[i];
}
orientation = 0;
// if the innerproduct is equal to the (absolute value of the ) products of the lengths
// of both vectors, then, the coordinate systems will NOT be transposed
if( fabs(elementAaxis_length*faceAaxis_length - fabs(dotproduct1)) < NekConstants::kNekZeroTol )
{
// if the inner product is negative, both A-axis point
// in reverse direction
if(dotproduct1 < 0.0)
{
orientation += 2;
}
// calculate the inner product of both B-axis
for(i = 0 ; i < m_coordim; i++)
{
dotproduct2 += elementBaxis[i]*faceBaxis[i];
}
// check that both these axis are indeed parallel
ASSERTL1(fabs(elementBaxis_length*faceBaxis_length - fabs(dotproduct2)) <
"These vectors should be parallel");
// if the inner product is negative, both B-axis point
// in reverse direction
if( dotproduct2 < 0.0 )
{
orientation++;
}
}
// The coordinate systems are transposed
else
{
orientation = 4;
// Calculate the inner product between the elemental A-axis
// and the B-axis of the face (which are now the corresponding axis)
dotproduct1 = 0.0;
for(i = 0 ; i < m_coordim; i++)
{
dotproduct1 += elementAaxis[i]*faceBaxis[i];
}
// check that both these axis are indeed parallel
ASSERTL1(fabs(elementAaxis_length*faceBaxis_length - fabs(dotproduct1)) <
"These vectors should be parallel");
// if the result is negative, both axis point in reverse
// directions
if(dotproduct1 < 0.0)
{
orientation += 2;
}
// Do the same for the other two corresponding axis
dotproduct2 = 0.0;
for(i = 0 ; i < m_coordim; i++)
{
dotproduct2 += elementBaxis[i]*faceAaxis[i];
}
// check that both these axis are indeed parallel
ASSERTL1(fabs(elementBaxis_length*faceAaxis_length - fabs(dotproduct2)) <
"These vectors should be parallel");
if( dotproduct2 < 0.0 )
{
orientation++;
}
}
orientation = orientation + 5;
// Fill the m_forient array
m_forient[f] = (StdRegions::Orientation) orientation;
}
}
void Nektar::SpatialDomains::TetGeom::SetUpLocalEdges ( )
private

Definition at line 341 of file TetGeom.cpp.

References ASSERTL0, Nektar::SpatialDomains::Geometry3D::GetEdge(), Nektar::SpatialDomains::Geometry3D::GetEid(), Nektar::SpatialDomains::Geometry::GetFid(), Nektar::SpatialDomains::Geometry3D::m_edges, and Nektar::SpatialDomains::Geometry3D::m_faces.

Referenced by TetGeom().

{
// find edge 0
int i,j;
unsigned int check;
// First set up the 3 bottom edges
if(m_faces[0]->GetEid(0) != m_faces[1]->GetEid(0))
{
std::ostringstream errstrm;
errstrm << "Local edge 0 (eid=" << m_faces[0]->GetEid(0);
errstrm << ") on face " << m_faces[0]->GetFid();
errstrm << " must be the same as local edge 0 (eid="<<m_faces[1]->GetEid(0);
errstrm << ") on face " << m_faces[1]->GetFid();
ASSERTL0(false, errstrm.str());
}
int faceConnected;
for(faceConnected = 1; faceConnected < 4 ; faceConnected++)
{
check = 0;
for(i = 0; i < 3; i++)
{
if( (m_faces[0])->GetEid(i) == (m_faces[faceConnected])->GetEid(0) )
{
edge = boost::dynamic_pointer_cast<SegGeom>((m_faces[0])->GetEdge(i));
m_edges.push_back(edge);
check++;
}
}
if( check < 1 )
{
std::ostringstream errstrm;
errstrm << "Face 0 does not share an edge with first edge of adjacent face. Faces ";
errstrm << (m_faces[0])->GetFid() << ", " << (m_faces[faceConnected])->GetFid();
ASSERTL0(false, errstrm.str());
}
else if( check > 1)
{
std::ostringstream errstrm;
errstrm << "Connected faces share more than one edge. Faces ";
errstrm << (m_faces[0])->GetFid() << ", " << (m_faces[faceConnected])->GetFid();
ASSERTL0(false, errstrm.str());
}
}
// Then, set up the 3 vertical edges
check = 0;
for(i = 0; i < 3; i++) //Set up the vertical edge :face(1) and face(3)
{
for(j = 0; j < 3; j++)
{
if( (m_faces[1])->GetEid(i) == (m_faces[3])->GetEid(j) )
{
edge = boost::dynamic_pointer_cast<SegGeom>((m_faces[1])->GetEdge(i));
m_edges.push_back(edge);
check++;
}
}
}
if( check < 1 )
{
std::ostringstream errstrm;
errstrm << "Connected faces do not share an edge. Faces ";
errstrm << (m_faces[1])->GetFid() << ", " << (m_faces[3])->GetFid();
ASSERTL0(false, errstrm.str());
}
else if( check > 1)
{
std::ostringstream errstrm;
errstrm << "Connected faces share more than one edge. Faces ";
errstrm << (m_faces[1])->GetFid() << ", " << (m_faces[3])->GetFid();
ASSERTL0(false, errstrm.str());
}
// Set up vertical edges: face(1) through face(3)
for(faceConnected = 1; faceConnected < 3 ; faceConnected++)
{
check = 0;
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
if( (m_faces[faceConnected])->GetEid(i) == (m_faces[faceConnected+1])->GetEid(j) )
{
edge = boost::dynamic_pointer_cast<SegGeom>((m_faces[faceConnected])->GetEdge(i));
m_edges.push_back(edge);
check++;
}
}
}
if( check < 1 )
{
std::ostringstream errstrm;
errstrm << "Connected faces do not share an edge. Faces ";
errstrm << (m_faces[faceConnected])->GetFid() << ", " << (m_faces[faceConnected+1])->GetFid();
ASSERTL0(false, errstrm.str());
}
else if( check > 1)
{
std::ostringstream errstrm;
errstrm << "Connected faces share more than one edge. Faces ";
errstrm << (m_faces[faceConnected])->GetFid() << ", " << (m_faces[faceConnected+1])->GetFid();
ASSERTL0(false, errstrm.str());
}
}
};
void Nektar::SpatialDomains::TetGeom::SetUpLocalVertices ( )
private

Definition at line 455 of file TetGeom.cpp.

References ASSERTL0, Nektar::SpatialDomains::Geometry::GetVertex(), Nektar::SpatialDomains::Geometry::GetVid(), Nektar::SpatialDomains::Geometry3D::m_edges, and Nektar::SpatialDomains::Geometry3D::m_verts.

Referenced by TetGeom().

{
// Set up the first 2 vertices (i.e. vertex 0,1)
if( ( m_edges[0]->GetVid(0) == m_edges[1]->GetVid(0) ) ||
( m_edges[0]->GetVid(0) == m_edges[1]->GetVid(1) ) )
{
m_verts.push_back(m_edges[0]->GetVertex(1));
m_verts.push_back(m_edges[0]->GetVertex(0));
}
else if( ( m_edges[0]->GetVid(1) == m_edges[1]->GetVid(0) ) ||
( m_edges[0]->GetVid(1) == m_edges[1]->GetVid(1) ) )
{
m_verts.push_back(m_edges[0]->GetVertex(0));
m_verts.push_back(m_edges[0]->GetVertex(1));
}
else
{
std::ostringstream errstrm;
errstrm << "Connected edges do not share a vertex. Edges ";
errstrm << m_edges[0]->GetEid() << ", " << m_edges[1]->GetEid();
ASSERTL0(false, errstrm.str());
}
// set up the other bottom vertices (i.e. vertex 2)
for(int i = 1; i < 2; i++)
{
if( m_edges[i]->GetVid(0) == m_verts[i]->GetVid() )
{
m_verts.push_back(m_edges[i]->GetVertex(1));
}
else if( m_edges[i]->GetVid(1) == m_verts[i]->GetVid() )
{
m_verts.push_back(m_edges[i]->GetVertex(0));
}
else
{
std::ostringstream errstrm;
errstrm << "Connected edges do not share a vertex. Edges ";
errstrm << m_edges[i]->GetEid() << ", " << m_edges[i-1]->GetEid();
ASSERTL0(false, errstrm.str());
}
}
// set up top vertex
if (m_edges[3]->GetVid(0) == m_verts[0]->GetVid())
{
m_verts.push_back(m_edges[3]->GetVertex(1));
}
else {
m_verts.push_back(m_edges[3]->GetVertex(0));
}
// Check the other edges match up.
int check = 0;
for (int i = 4; i < 6; ++i)
{
if( (m_edges[i]->GetVid(0) == m_verts[i-3]->GetVid()
&& m_edges[i]->GetVid(1) == m_verts[3]->GetVid())
||(m_edges[i]->GetVid(1) == m_verts[i-3]->GetVid()
&& m_edges[i]->GetVid(0) == m_verts[3]->GetVid()))
{
check++;
}
}
if (check != 2) {
std::ostringstream errstrm;
errstrm << "Connected edges do not share a vertex. Edges ";
errstrm << m_edges[3]->GetEid() << ", " << m_edges[2]->GetEid();
ASSERTL0(false, errstrm.str());
}
};
bool Nektar::SpatialDomains::TetGeom::v_ContainsPoint ( const Array< OneD, const NekDouble > &  gloCoord,
NekDouble  tol = 0.0 
)
protectedvirtual

Determines if a point specified in global coordinates is located within this tetrahedral geometry.

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 135 of file TetGeom.cpp.

References Nektar::SpatialDomains::Geometry::GetCoordim().

Referenced by v_ContainsPoint().

{
Array<OneD,NekDouble> locCoord(GetCoordim(),0.0);
return v_ContainsPoint(gloCoord,locCoord,tol);
}
bool Nektar::SpatialDomains::TetGeom::v_ContainsPoint ( const Array< OneD, const NekDouble > &  gloCoord,
Array< OneD, NekDouble > &  locCoord,
NekDouble  tol 
)
protectedvirtual

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 142 of file TetGeom.cpp.

References v_ContainsPoint().

{
NekDouble resid;
return v_ContainsPoint(gloCoord,locCoord,tol,resid);
}
bool Nektar::SpatialDomains::TetGeom::v_ContainsPoint ( const Array< OneD, const NekDouble > &  gloCoord,
Array< OneD, NekDouble > &  locCoord,
NekDouble  tol,
NekDouble resid 
)
protectedvirtual

Determines if a point specified in global coordinates is located within this tetrahedral geometry and return local caretsian coordinates.

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 154 of file TetGeom.cpp.

References ASSERTL1, Nektar::SpatialDomains::eRegular, Nektar::SpatialDomains::Geometry::GetMetricInfo(), Nektar::SpatialDomains::Geometry::m_coeffs, Nektar::SpatialDomains::Geometry::m_xmap, npts, Nektar::SpatialDomains::Geometry3D::v_FillGeom(), v_GetLocCoords(), Vmath::Vmax(), and Vmath::Vmin().

{
// Validation checks
ASSERTL1(gloCoord.num_elements() == 3,
"Three dimensional geometry expects three coordinates.");
// find min, max point and check if within twice this
// distance other false this is advisable since
// GetLocCoord is expensive for non regular elements.
if(GetMetricInfo()->GetGtype() != eRegular)
{
int i;
Array<OneD, NekDouble> mincoord(3), maxcoord(3);
NekDouble diff = 0.0;
const int npts = m_xmap->GetTotPoints();
Array<OneD, NekDouble> pts(npts);
for(i = 0; i < 3; ++i)
{
m_xmap->BwdTrans(m_coeffs[i], pts);
mincoord[i] = Vmath::Vmin(pts.num_elements(),pts,1);
maxcoord[i] = Vmath::Vmax(pts.num_elements(),pts,1);
diff = max(maxcoord[i] - mincoord[i],diff);
}
for(i = 0; i < 3; ++i)
{
if((gloCoord[i] < mincoord[i] - 0.2*diff)||
(gloCoord[i] > maxcoord[i] + 0.2*diff))
{
return false;
}
}
}
// Convert to the local (eta) coordinates.
resid = v_GetLocCoords(gloCoord, locCoord);
// Check local coordinate is within cartesian bounds.
if (locCoord[0] >= -(1+tol) && locCoord[1] >= -(1+tol) &&
locCoord[2] >= -(1+tol) &&
locCoord[0] + locCoord[1] + locCoord[2] <= -1+tol)
{
return true;
}
return false;
}
int Nektar::SpatialDomains::TetGeom::v_GetDir ( const int  faceidx,
const int  facedir 
) const
protectedvirtual

Implements Nektar::SpatialDomains::Geometry3D.

Definition at line 310 of file TetGeom.cpp.

{
if (faceidx == 0)
{
return facedir;
}
else if (faceidx == 1)
{
return 2 * facedir;
}
else
{
return 1 + facedir;
}
}
int Nektar::SpatialDomains::TetGeom::v_GetEdgeFaceMap ( const int  i,
const int  j 
) const
protectedvirtual

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 336 of file TetGeom.cpp.

References EdgeFaceConnectivity.

{
return EdgeFaceConnectivity[i][j];
}
NekDouble Nektar::SpatialDomains::TetGeom::v_GetLocCoords ( const Array< OneD, const NekDouble > &  coords,
Array< OneD, NekDouble > &  Lcoords 
)
protectedvirtual

Get Local cartesian points.

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 213 of file TetGeom.cpp.

References Nektar::SpatialDomains::PointGeom::dot(), Nektar::SpatialDomains::eRegular, Nektar::SpatialDomains::Geometry::GetMetricInfo(), Vmath::Imin(), Nektar::SpatialDomains::Geometry::m_coeffs, Nektar::SpatialDomains::Geometry::m_coordim, Nektar::SpatialDomains::Geometry3D::m_verts, Nektar::SpatialDomains::Geometry::m_xmap, Nektar::SpatialDomains::PointGeom::Mult(), Nektar::SpatialDomains::Geometry3D::NewtonIterationForLocCoord(), npts, Vmath::Sadd(), Nektar::SpatialDomains::PointGeom::Sub(), Nektar::SpatialDomains::Geometry3D::v_FillGeom(), Vmath::Vmul(), and Vmath::Vvtvp().

Referenced by v_ContainsPoint().

{
NekDouble resid = 0.0;
// calculate local coordinates (eta) for coord
if(GetMetricInfo()->GetGtype() == eRegular)
{
// Point inside tetrahedron
PointGeom r(m_coordim, 0, coords[0], coords[1], coords[2]);
// Edges
PointGeom er0, e10, e20, e30;
er0.Sub(r,*m_verts[0]);
e10.Sub(*m_verts[1],*m_verts[0]);
e20.Sub(*m_verts[2],*m_verts[0]);
e30.Sub(*m_verts[3],*m_verts[0]);
// Cross products (Normal times area)
PointGeom cp1020, cp2030, cp3010;
cp1020.Mult(e10,e20);
cp2030.Mult(e20,e30);
cp3010.Mult(e30,e10);
// Barycentric coordinates (relative volume)
NekDouble V = e30.dot(cp1020); // Tet Volume = {(e30)dot(e10)x(e20)}/6
NekDouble beta = er0.dot(cp2030) / V; // volume1 = {(er0)dot(e20)x(e30)}/6
NekDouble gamma = er0.dot(cp3010) / V; // volume1 = {(er0)dot(e30)x(e10)}/6
NekDouble delta = er0.dot(cp1020) / V; // volume1 = {(er0)dot(e10)x(e20)}/6
// Make tet bigger
Lcoords[0] = 2.0*beta - 1.0;
Lcoords[1] = 2.0*gamma - 1.0;
Lcoords[2] = 2.0*delta - 1.0;
}
else
{
// Determine nearest point of coords to values in m_xmap
int npts = m_xmap->GetTotPoints();
Array<OneD, NekDouble> ptsx(npts), ptsy(npts), ptsz(npts);
Array<OneD, NekDouble> tmp1(npts), tmp2(npts);
m_xmap->BwdTrans(m_coeffs[0], ptsx);
m_xmap->BwdTrans(m_coeffs[1], ptsy);
m_xmap->BwdTrans(m_coeffs[2], ptsz);
const Array<OneD, const NekDouble> za = m_xmap->GetPoints(0);
const Array<OneD, const NekDouble> zb = m_xmap->GetPoints(1);
const Array<OneD, const NekDouble> zc = m_xmap->GetPoints(2);
//guess the first local coords based on nearest point
Vmath::Sadd(npts, -coords[0], ptsx,1,tmp1,1);
Vmath::Vmul (npts, tmp1,1,tmp1,1,tmp1,1);
Vmath::Sadd(npts, -coords[1], ptsy,1,tmp2,1);
Vmath::Vvtvp(npts, tmp2,1,tmp2,1,tmp1,1,tmp1,1);
Vmath::Sadd(npts, -coords[2], ptsz,1,tmp2,1);
Vmath::Vvtvp(npts, tmp2,1,tmp2,1,tmp1,1,tmp1,1);
int min_i = Vmath::Imin(npts,tmp1,1);
// Get collapsed coordinate
int qa = za.num_elements(), qb = zb.num_elements();
Lcoords[2] = zc[min_i/(qa*qb)];
min_i = min_i%(qa*qb);
Lcoords[1] = zb[min_i/qa];
Lcoords[0] = za[min_i%qa];
// recover cartesian coordinate from collapsed coordinate.
Lcoords[1] = (1.0+Lcoords[0])*(1.0-Lcoords[2])/2 -1.0;
Lcoords[0] = (1.0+Lcoords[0])*(-Lcoords[1]-Lcoords[2])/2 -1.0;
// Perform newton iteration to find local coordinates
NewtonIterationForLocCoord(coords, ptsx, ptsy, ptsz, Lcoords,resid);
}
return resid;
}
int Nektar::SpatialDomains::TetGeom::v_GetNumEdges ( ) const
protectedvirtual

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 300 of file TetGeom.cpp.

{
return 6;
}
int Nektar::SpatialDomains::TetGeom::v_GetNumFaces ( ) const
protectedvirtual

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 305 of file TetGeom.cpp.

{
return 4;
}
int Nektar::SpatialDomains::TetGeom::v_GetNumVerts ( ) const
protectedvirtual

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 295 of file TetGeom.cpp.

{
return 4;
}
int Nektar::SpatialDomains::TetGeom::v_GetVertexEdgeMap ( const int  i,
const int  j 
) const
protectedvirtual

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 326 of file TetGeom.cpp.

References VertexEdgeConnectivity.

{
return VertexEdgeConnectivity[i][j];
}
int Nektar::SpatialDomains::TetGeom::v_GetVertexFaceMap ( const int  i,
const int  j 
) const
protectedvirtual

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 331 of file TetGeom.cpp.

References VertexFaceConnectivity.

{
return VertexFaceConnectivity[i][j];
}

Member Data Documentation

const unsigned int Nektar::SpatialDomains::TetGeom::EdgeFaceConnectivity
staticprivate
Initial value:
{
{0,1},{0,2},{0,3},{1,3},{1,2},{2,3}}

Definition at line 99 of file TetGeom.h.

Referenced by v_GetEdgeFaceMap().

const int Nektar::SpatialDomains::TetGeom::kNedges = 6
static

Definition at line 57 of file TetGeom.h.

Referenced by SetUpEdgeOrientation(), and TetGeom().

const int Nektar::SpatialDomains::TetGeom::kNfaces = kNqfaces + kNtfaces
static

Definition at line 60 of file TetGeom.h.

Referenced by Nektar::SpatialDomains::MeshGraph3D::ReadElements(), SetUpFaceOrientation(), and TetGeom().

const int Nektar::SpatialDomains::TetGeom::kNqfaces = 0
static

Definition at line 58 of file TetGeom.h.

Referenced by Nektar::SpatialDomains::MeshGraph3D::ReadElements(), and SetUpFaceOrientation().

const int Nektar::SpatialDomains::TetGeom::kNtfaces = 4
static

Definition at line 59 of file TetGeom.h.

Referenced by Nektar::SpatialDomains::MeshGraph3D::ReadElements(), and SetUpFaceOrientation().

const int Nektar::SpatialDomains::TetGeom::kNverts = 4
static

Definition at line 56 of file TetGeom.h.

Referenced by SetUpFaceOrientation().

const unsigned int Nektar::SpatialDomains::TetGeom::VertexEdgeConnectivity
staticprivate
Initial value:
{
{0,2,3},{0,1,4},{1,2,5},{3,4,5}}

Definition at line 97 of file TetGeom.h.

Referenced by v_GetVertexEdgeMap().

const unsigned int Nektar::SpatialDomains::TetGeom::VertexFaceConnectivity
staticprivate
Initial value:
{
{0,1,3},{0,1,2},{0,2,3},{1,2,3}}

Definition at line 98 of file TetGeom.h.

Referenced by v_GetVertexFaceMap().

const std::string Nektar::SpatialDomains::TetGeom::XMLElementType
static

Definition at line 61 of file TetGeom.h.