Commit c9fdad4b authored by Chris Cantwell's avatar Chris Cantwell

Merge branch 'feature/MeshConvertFullStarInput' into 'master'

Feature/mesh convert full star input

@ccantwel This has been through buildbot.I would recommend Dave and Michael do the review?

See merge request !474
parents 1a7f902b d16deb9f
......@@ -177,6 +177,7 @@ INCLUDE (ThirdPartyPETSc)
INCLUDE (ThirdPartyVTK)
INCLUDE (ThirdPartyQT4)
INCLUDE (ThirdPartySMV)
INCLUDE (ThirdPartyCCM)
INCLUDE (Doxygen)
......
########################################################################
#
# ThirdParty configuration for Nektar++
#
# Star CCM i/o
#
########################################################################
OPTION(NEKTAR_USE_CCM
"CCM star i/o library is available." OFF)
IF( NEKTAR_USE_CCM )
FIND_LIBRARY(CCMIO_LIBRARY NAMES "ccmio" "adf" PATHS /usr/local/lib ${Nektar++_TP_LIBRARY_DIRS})
IF( CCMIO_LIBRARY )
MESSAGE(STATUS "Found Ccmio: ${CCMIO_LIBRARY}")
MARK_AS_ADVANCED(CCMIO_LIBRARY)
ADD_DEFINITIONS(-DNEKTAR_USE_CCM)
FIND_PATH (CCMIO_INCLUDE_DIR ccmio.h)
ELSE()
MESSAGE(FATAL_ERROR "Cound not find ccmio library")
ENDIF()
ENDIF( NEKTAR_USE_CCM )
......@@ -517,10 +517,22 @@ Components of the \nekpp package can be selected using the following options:
Enabled compilation of the 'X' solver.
\end{itemize}
A number of ThirdParty libraries are required by \nekpp. There are also
optional libraries which provide additional functionality. These can be selected
using the following options:
A number of ThirdParty libraries are required by \nekpp. There are
also optional libraries which provide additional functionality. These
can be selected using the following options:
\begin{itemize}
\item \inlsh{NEKTAR\_USE\_ACCELERATE\_FRAMEWORK}
Use the Mac Osx accelerate framework for BLAS and LAPACK
methods. This option should only be required under in a Mac OSX
environment.
\item \inlsh{NEKTAR\_USE\_ARPACK}
Build \nekpp with support for ARPACK. This provides routines used for
linear stability analyses. Alternative Arnoldi algorithms are also
implemented directly in \nekpp.
\item \inlsh{NEKTAR\_USE\_BLAS\_LAPACK} (Required)
Enables the use of Basic Linear Algebra Subroutines libraries for linear
......@@ -532,34 +544,37 @@ using the following options:
This may not be the implementation offering the highest performance for your
architecture, but it is the most likely to work without problem.
\item \inlsh{NEKTAR\_USE\_OPENBLAS}
\item \inlsh{NEKTAR\_USE\_CCM}
Use OpenBLAS for the BLAS library. OpenBLAS is based on the Goto BLAS
implementation and generally offers better performance than a non-optimised
system BLAS. However, the library must be installed on the system.
Use the ccmio library provided with the Star-CCM package for
reading ccm files. This option is required as part of MeshConvert
if you wish to convert a Star-CCM mesh into the Nektar format. It
is possible to read a Tecplot plt file from Star-CCM but this
output currently needs to be converted to ascii format using the
Tecplot package.
\item \inlsh{NEKTAR\_USE\_FFTW}
Build \nekpp with support for FFTW for performing Fast Fourier Transforms
(FFTs). This is used only when using domains with homogeneous coordinate
directions.
\item \inlsh{NEKTAR\_USE\_MKL}
Use the Intel MKL library. This is typically available on cluster
environments and should offer performance tuned for the specific cluster
environment.
\item \inlsh{NEKTAR\_USE\_MPI} (Recommended)
Build Nektar++ with MPI parallelisation. This allows solvers to be run in
serial or parallel.
\item \inlsh{NEKTAR\_USE\_FFTW}
Build \nekpp with support for FFTW for performing Fast Fourier Transforms
(FFTs). This is used only when using domains with homogeneous coordinate
directions.
\item \inlsh{NEKTAR\_USE\_ARPACK}
\item \inlsh{NEKTAR\_USE\_OPENBLAS}
Build \nekpp with support for ARPACK. This provides routines used for
linear stability analyses. Alternative Arnoldi algorithms are also
implemented directly in \nekpp.
Use OpenBLAS for the BLAS library. OpenBLAS is based on the Goto BLAS
implementation and generally offers better performance than a non-optimised
system BLAS. However, the library must be installed on the system.
\item \inlsh{NEKTAR\_USE\_VTK}
......
......@@ -213,7 +213,8 @@ where it exists. The table below indicates support currently implemented.
Nektar++ & \texttt{xml} & \cmark & Fully supported. \\
PLY & \texttt{ply} & \xmark & Reads only the ASCII format.. \\
Semtex & \texttt{sem} & \cmark & Reads elements and boundary conditions. In order to read high-order information, run \inltt{meshpr session.sem > session.msh} and place in the same directory as the session file.\\
Star-CCM+ & \texttt{dat} & \xmark & Reads mesh only, only support for quads and triangles (2D) and hexes, prisms, tetrahedra (3D).\\
Star-CCM+ & \texttt{dat} & \xmark & Star outputs plt file which currently needs to be coverted to ascii using Tecplot. Reads mesh only, only support for quads and triangles (2D) and hexes, prisms, tetrahedra (3D).\\
Star-CCM+ & \texttt{ccm} & \xmark & Reads start ccm format. Reads mesh only, only support for quads and triangles (2D) and hexes, prisms, tetrahedra (3D). Requires NEKTAR\_USE\_CCM option to be activated in cmake and then requires ccmio library to be compiled by user. \\
VTK & \texttt{vtk} & \xmark & Experimental support. Only ASCII triangular data is supported. \\
\bottomrule
\end{tabularx}
......@@ -291,6 +292,15 @@ use the \inltt{extract} boolean parameter:
MeshConvert -m jac:extract Mesh.xml MeshWithNegativeElements.xml
\end{lstlisting}
To turn off curvature associated with negative jacobians one can try to use the \inltt{removecurveifsingular} boolean parameter:
\begin{lstlisting}[style=BashInputStyle]
MeshConvert -m jac:removecurveifsingular Mesh.xml output.xml
\end{lstlisting}
This option will remove the high order curvature on prismatic faces
with singular jacobians. This does not guarantee a non-singular mesh
since it is possible for neighbouring element then to have singular
jacobians. Multiple calls to the module might help with this scenario.
\subsubsection{Spherigon patches}
Where high-order information is not available (e.g. when using meshes from
......
......@@ -1151,6 +1151,48 @@ namespace Nektar
zscale = expEvaluator.Evaluate(expr_id);
}
NekDouble xmove,ymove,zmove;
// check to see if any moving parameters are in
// attributes and determine these values
//LibUtilities::ExpressionEvaluator expEvaluator;
const char *xmov = element->Attribute("XMOVE");
if(!xmov)
{
xmove = 0.0;
}
else
{
std::string xmovstr = xmov;
int expr_id = expEvaluator.DefineFunction("",xmovstr);
xmove = expEvaluator.Evaluate(expr_id);
}
const char *ymov = element->Attribute("YMOVE");
if(!ymov)
{
ymove = 0.0;
}
else
{
std::string ymovstr = ymov;
int expr_id = expEvaluator.DefineFunction("",ymovstr);
ymove = expEvaluator.Evaluate(expr_id);
}
const char *zmov = element->Attribute("ZMOVE");
if(!zmov)
{
zmove = 0.0;
}
else
{
std::string zmovstr = zmov;
int expr_id = expEvaluator.DefineFunction("",zmovstr);
zmove = expEvaluator.Evaluate(expr_id);
}
int err;
/// Look for elements in CURVE block.
......@@ -1233,9 +1275,10 @@ namespace Nektar
{
elementDataStrm >> xval >> yval >> zval;
xval *= xscale;
yval *= yscale;
zval *= zscale;
xval = xval*xscale + xmove;
yval = yval*yscale + ymove;
zval = zval*zscale + zmove;
// Need to check it here because we may not be
// good after the read indicating that there
// was nothing to read.
......
......@@ -45,6 +45,12 @@ SET(MeshConvertSources
ProcessTetSplit.cpp
)
IF (NEKTAR_USE_CCM)
SET(MeshConvertHeaders ${MeshConvertHeaders} InputStar.h)
SET(MeshConvertSources ${MeshConvertSources} InputStar.cpp)
ENDIF (NEKTAR_USE_CCM)
IF (NEKTAR_USE_VTK)
SET(MeshConvertHeaders ${MeshConvertHeaders} InputVtk.h OutputVtk.h)
SET(MeshConvertSources ${MeshConvertSources} InputVtk.cpp OutputVtk.cpp)
......@@ -52,6 +58,14 @@ ENDIF (NEKTAR_USE_VTK)
ADD_UTILITIES_EXECUTABLE(MeshConvert util ${MeshConvertSources} ${MeshConvertHeaders})
IF (NEKTAR_USE_CCM)
TARGET_LINK_LIBRARIES(MeshConvert ccmio adf)
SET_TARGET_PROPERTIES(MeshConvert PROPERTIES
IMPORTED_LOCATION ${CCMIO_LIBRARY_PATH}/libccmio.a)
INCLUDE_DIRECTORIES(MeshConvert ${CCMIO_INCLUDE_DIR})
LINK_DIRECTORIES(${CCMIO_LIBRARY_PATH})
ENDIF (NEKTAR_USE_CCM)
IF (NEKTAR_USE_VTK)
IF (VTK_MAJOR_VERSION LESS 6)
TARGET_LINK_LIBRARIES(MeshConvert vtkCommon vtkIO vtkGraphics)
......@@ -60,6 +74,7 @@ IF (NEKTAR_USE_VTK)
ENDIF ()
ENDIF (NEKTAR_USE_VTK)
# Gmsh tests
ADD_NEKTAR_TEST (Gmsh/CubeAllElements)
ADD_NEKTAR_TEST (Gmsh/CubeHex)
......
......@@ -102,7 +102,15 @@ namespace Nektar
stringstream s(line);
string word;
s >> word;
if (word == "element")
if(word == "format")
{
s >> word;
if(word != "ascii")
{
ASSERTL0(false,"InputPly file currently only set up to read ascii formatted ply files");
}
}
else if (word == "element")
{
s >> word;
if (word == "vertex")
......@@ -200,7 +208,7 @@ namespace Nektar
}
}
}
}
}
}
}
This diff is collapsed.
////////////////////////////////////////////////////////////////////////////////
//
// File: InputStarTec.h
//
// For more information, please see: http://www.nektar.info/
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Tecplot (ascii .dat) converter.
//
////////////////////////////////////////////////////////////////////////////////
#ifndef UTILITIES_PREPROCESSING_MESHCONVERT_INPUTSTAR
#define UTILITIES_PREPROCESSING_MESHCONVERT_INPUTSTAR
#include "Module.h"
#include "MeshElements.h"
#include "ccmio.h"
namespace Nektar
{
namespace Utilities
{
/// Converter for VTK files.
class InputStar : public InputModule
{
public:
/// Creates an instance of this class
static ModuleSharedPtr create(MeshSharedPtr m) {
return MemoryManager<InputStar>::AllocateSharedPtr(m);
}
static ModuleKey className;
InputStar(MeshSharedPtr m);
virtual ~InputStar();
/// Populate and validate required data structures.
virtual void Process();
void ReadZone(int &nComposite);
protected:
void GenElement3D(vector<NodeSharedPtr> &Nodes,
int i, vector<int> &ElementFaces,
map<int, vector<int> >&FaceNodes,
int ncomposite,
bool DoOrient);
void GenElement2D(vector<NodeSharedPtr> &Nodes,
int i,
vector<int> &FaceNodes,
int ncomposite);
Array<OneD, int> SortEdgeNodes(vector<NodeSharedPtr> &Nodes,
vector<int> &FaceNodes);
Array<OneD, int> SortFaceNodes(vector<NodeSharedPtr> &Nodes,
vector<int> &ElementFaces,
map<int, vector<int> >&FaceNodes);
void ResetNodes(vector<NodeSharedPtr> &Nodes,
Array<OneD, vector<int> > &ElementFaces,
map<int, vector<int> > &FaceNodes);
private:
CCMIOError m_ccmErr; //Star CCM error flag
CCMIOID m_ccmTopology; //Star CCM mesh topology
CCMIOID m_ccmProcessor;
map<int,string> m_faceLabels; // label from CCM into composite
void InitCCM(void);
void ReadNodes( std::vector<NodeSharedPtr> &Nodes);
void ReadInternalFaces(map<int, vector<int> > &FacesNodes,
Array<OneD, vector<int> > &ElementFaces);
void ReadBoundaryFaces(vector< vector<int> > &BndElementFaces,
map<int, vector<int> > &FacesNodes,
Array<OneD, vector<int> > &ElementFaces,
vector<string> &facelabels);
void SetupElements(void);
};
}
}
#endif
......@@ -425,7 +425,7 @@ namespace Nektar
}
void PrismLineFaces(int prismid, map<int, int> &facelist,
static void PrismLineFaces(int prismid, map<int, int> &facelist,
vector<vector<int> > &FacesToPrisms,
vector<vector<int> > &PrismsToFaces,
vector<bool> &PrismDone);
......@@ -644,7 +644,7 @@ namespace Nektar
void PrismLineFaces(int prismid, map<int, int> &facelist,
static void PrismLineFaces(int prismid, map<int, int> &facelist,
vector<vector<int> > &FaceToPrisms,
vector<vector<int> > &PrismToFaces,
vector<bool> &PrismDone)
......
......@@ -1220,30 +1220,66 @@ namespace Nektar
// point.
sort(m_vertex.begin(), m_vertex.end());
// Calculate a.(b x c) to determine tet volume; if negative,
// reverse order of non-degenerate points to correctly orientate
// the tet.
double ax = m_vertex[1]->m_x-m_vertex[0]->m_x;
double ay = m_vertex[1]->m_y-m_vertex[0]->m_y;
double az = m_vertex[1]->m_z-m_vertex[0]->m_z;
double bx = m_vertex[2]->m_x-m_vertex[0]->m_x;
double by = m_vertex[2]->m_y-m_vertex[0]->m_y;
double bz = m_vertex[2]->m_z-m_vertex[0]->m_z;
double cx = m_vertex[3]->m_x-m_vertex[0]->m_x;
double cy = m_vertex[3]->m_y-m_vertex[0]->m_y;
double cz = m_vertex[3]->m_z-m_vertex[0]->m_z;
double vol = cx*(ay*bz-az*by)+cy*(az*bx-ax*bz)+cz*(ax*by-ay*bx);
vol /= 6.0;
if (fabs(vol) <= 1e-10)
// Calculate a.(b x c) if negative, reverse order of
// non-degenerate points to correctly orientate the tet.
NekDouble ax = m_vertex[1]->m_x-m_vertex[0]->m_x;
NekDouble ay = m_vertex[1]->m_y-m_vertex[0]->m_y;
NekDouble az = m_vertex[1]->m_z-m_vertex[0]->m_z;
NekDouble bx = m_vertex[2]->m_x-m_vertex[0]->m_x;
NekDouble by = m_vertex[2]->m_y-m_vertex[0]->m_y;
NekDouble bz = m_vertex[2]->m_z-m_vertex[0]->m_z;
NekDouble cx = m_vertex[3]->m_x-m_vertex[0]->m_x;
NekDouble cy = m_vertex[3]->m_y-m_vertex[0]->m_y;
NekDouble cz = m_vertex[3]->m_z-m_vertex[0]->m_z;
NekDouble nx = (ay*bz-az*by);
NekDouble ny = (az*bx-ax*bz);
NekDouble nz = (ax*by-ay*bx);
NekDouble nmag = sqrt(nx*nx+ny*ny+nz*nz);
nx /= nmag; ny /= nmag; nz /= nmag;
// distance of top vertex from base
NekDouble dist = cx*nx+cy*ny+cz*nz;
if (fabs(dist) <= 1e-4)
{
cerr << "Warning: degenerate tetrahedron, volume = " << vol << endl;
cerr << "Warning: degenerate tetrahedron, 3rd vertex is = " << dist <<" from face" << endl;
}
if (vol < 0)
if (dist < 0)
{
swap(m_vertex[0], m_vertex[1]);
}
nx = (ay*cz-az*cy);
ny = (az*cx-ax*cz);
nz = (ax*cy-ay*cx);
nmag = sqrt(nx*nx+ny*ny+nz*nz);
nx /= nmag; ny /= nmag; nz /= nmag;
// distance of top vertex from base
dist = bx*nx+by*ny+bz*nz;
if (fabs(dist) <= 1e-4)
{
cerr << "Warning: degenerate tetrahedron, 2nd vertex is = " << dist <<" from face" << endl;
}
nx = (by*cz-bz*cy);
ny = (bz*cx-bx*cz);
nz = (bx*cy-by*cx);
nmag = sqrt(nx*nx+ny*ny+nz*nz);
nx /= nmag; ny /= nmag; nz /= nmag;
// distance of top vertex from base
dist = ax*nx+ay*ny+az*nz;
if (fabs(dist) <= 1e-4)
{
cerr << "Warning: degenerate tetrahedron, 1st vertex is = " << dist <<" from face" << endl;
}
TetOrientSet::iterator it;
......@@ -1499,16 +1535,24 @@ namespace Nektar
faceVertices.push_back(m_vertex[face_ids[j][k]]);
NodeSharedPtr a = m_vertex[face_ids[j][k]];
NodeSharedPtr b = m_vertex[face_ids[j][(k+1) % nEdge]];
for (unsigned int i = 0; i < m_edge.size(); ++i)
unsigned int i;
for (i = 0; i < m_edge.size(); ++i)
{
if ((m_edge[i]->m_n1 == a && m_edge[i]->m_n2 == b) ||
(m_edge[i]->m_n1 == b && m_edge[i]->m_n2 == a))
if ((m_edge[i]->m_n1->m_id == a->m_id
&& m_edge[i]->m_n2->m_id == b->m_id) ||
(m_edge[i]->m_n1->m_id == b->m_id
&& m_edge[i]->m_n2->m_id == a->m_id))
{
faceEdges.push_back(m_edge[i]);
face_edges[j][k] = i;
break;
}
}
if(i == m_edge.size())
{
face_edges[j][k] = -1;
}
}
if (m_conf.m_faceNodes)
......@@ -1544,14 +1588,23 @@ namespace Nektar
// Re-order edge array to be consistent with Nektar++ ordering.
vector<EdgeSharedPtr> tmp(9);
ASSERTL1(face_edges[0][0] != -1,"face_edges[0][0] == -1");
tmp[0] = m_edge[face_edges[0][0]];
ASSERTL1(face_edges[0][1] != -1,"face_edges[0][1] == -1");
tmp[1] = m_edge[face_edges[0][1]];
ASSERTL1(face_edges[0][2] != -1,"face_edges[0][2] == -1");
tmp[2] = m_edge[face_edges[0][2]];
ASSERTL1(face_edges[0][3] != -1,"face_edges[0][3] == -1");
tmp[3] = m_edge[face_edges[0][3]];
ASSERTL1(face_edges[1][2] != -1,"face_edges[1][2] == -1");
tmp[4] = m_edge[face_edges[1][2]];
ASSERTL1(face_edges[1][1] != -1,"face_edges[1][1] == -1");
tmp[5] = m_edge[face_edges[1][1]];
ASSERTL1(face_edges[2][1] != -1,"face_edges[2][1] == -1");
tmp[6] = m_edge[face_edges[2][1]];
ASSERTL1(face_edges[3][2] != -1,"face_edges[3][2] == -1");
tmp[7] = m_edge[face_edges[3][2]];
ASSERTL1(face_edges[4][2] != -1,"face_edges[4][2] == -1");
tmp[8] = m_edge[face_edges[4][2]];
m_edge = tmp;
}
......
......@@ -1051,6 +1051,8 @@ namespace Nektar
unsigned int m_id;
/// Element type tag.
std::string m_tag;
/// boundary label
std::string m_label;
/// Determines whether items can be reordered.
bool m_reorder;
/// List of elements in this composite.
......@@ -1128,6 +1130,9 @@ namespace Nektar
/// Set of all pairs of element ID and edge/face number on which to
/// apply spherigon surface smoothing.
set<pair<int,int> > m_spherigonSurfs;
/// List of face labels for composite annotation
map<int,string> m_faceLabels;
/// Returns the total number of elements in the mesh with
/// dimension expDim.
unsigned int GetNumElements();
......@@ -1136,6 +1141,7 @@ namespace Nektar
unsigned int GetNumBndryElements();
/// Returns the total number of entities in the mesh.
unsigned int GetNumEntities();
};
/// Shared pointer to a mesh.
typedef boost::shared_ptr<Mesh> MeshSharedPtr;
......
......@@ -362,6 +362,11 @@ namespace Nektar
pair<CompositeMap::iterator, bool> testIns;
tmp->m_id = tagid;
tmp->m_tag = elmt[i]->GetTag();
if(m_mesh->m_faceLabels.count(tmp->m_id) != 0)
{
tmp->m_label = m_mesh->m_faceLabels[tmp->m_id];
}
testIns = m_mesh->m_composite.insert(
pair<unsigned int, CompositeSharedPtr>(tagid,tmp));
it = testIns.first;
......
......@@ -136,7 +136,8 @@ namespace Nektar
/// Description of the configuration option.
string desc;
};
/**
* Abstract base class for mesh converter modules. Each subclass
* implements the Process() function, which in some way alters the
......
......@@ -396,6 +396,10 @@ namespace Nektar
doSort = doSort && it->second->m_reorder;
comp_tag->SetAttribute("ID", it->second->m_id);
if(it->second->m_label.size())
{
comp_tag->SetAttribute("LABEL", it->second->m_label);
}
comp_tag->LinkEndChild(
new TiXmlText(it->second->GetXmlString(doSort)));
verTag->LinkEndChild(comp_tag);
......
......@@ -257,8 +257,8 @@ namespace Nektar
splitEdge[LibUtilities::eHexahedron][5] = splitHex0Edge;
map<LibUtilities::ShapeType, map<int, bool> > revPoints;
revPoints[LibUtilities::ePrism][1] = false;
revPoints[LibUtilities::ePrism][3] = true;
revPoints[LibUtilities::ePrism][1] = true;
revPoints[LibUtilities::ePrism][3] = false;
revPoints[LibUtilities::eHexahedron][0] = true;
revPoints[LibUtilities::eHexahedron][5] = false;
......
......@@ -55,6 +55,8 @@ namespace Nektar
{
m_config["extract"] = ConfigOption(
true, "0", "Extract non-valid elements from mesh.");