Commit 3e801554 authored by Chris Cantwell's avatar Chris Cantwell

Merge branch 'master' into feature/NewHOBCs

Conflicts:
	CHANGELOG.md
parents 5b8fc3f3 f57dfa9d
......@@ -31,6 +31,9 @@ v4.4.0
file (!678)
- Extend ExtractDataToCoeffs to support interpolation between basis types for
quads and hexahedra (!682)
- Enabled MUMPS support in PETSc if a Fortran compiler was found and added 3D
support to the Helmholtz smoother used e.g. in FieldConverts C0Projection
module (!714)
**ADRSolver:**
- Add a projection equation system for C^0 projections (!675)
......@@ -44,12 +47,14 @@ v4.4.0
**IncNavierStokesSolver:**
- Add ability to simulate additional scalar fields (!624)
- Improve performance when using homogeneous dealiasing (!622)
- Fix linearised advection for full 3D cases (!708)
- Added a weak pressure formulation following Guermond & Shen (!713)
- Added a convective like outflow boundary condition from Dong (!713)
**FieldConvert:**
- Allow equi-spaced output for 1D and 2DH1D fields (!613)
- Update quality metric to include scaled Jacobian output (!695)
- Allow multiple XML files to be specified in InterpField module (!705)
**NekMesh:**
- Modify curve module to allow for spline input (!628)
......@@ -69,6 +74,10 @@ v4.4.0
- Add option to `linearise` to use element quality (!690)
- Add flag to `insertsurface` process for non-conforming geometries (!700)
- Bug fix to get two meshgen regression tests working (!700)
- Remove libANN in deference to boost::geometry (!703)
- 2D to 3D mesh extrusion module (!715)
- Add a mesh extract option to the linearise module to visualise the result
(!712)
**FieldConvert:**
- Move all modules to a new library, FieldUtils, to support post-processing
......@@ -83,6 +92,7 @@ v4.3.5
- Fix bug in DG with hybrid meshes (!694)
- Fix issue with parallel output (!699)
- Fix performance issue with iterative full solver (!693)
- Enforced precision on history point output (!706)
**Documentation**
- Update build instructions in user guide for Windows (!692)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.7)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8)
SET(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build,
options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release
RelWithDebInfo MinSizeRel.")
PROJECT(Nektar++)
PROJECT(Nektar++ C CXX)
INCLUDE(CheckLanguage)
CHECK_LANGUAGE(Fortran)
IF(CMAKE_Fortran_COMPILER)
ENABLE_LANGUAGE(Fortran)
ELSE()
MESSAGE(STATUS "No Fortran support")
ENDIF()
# Helps organize projects in IDEs.
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
......@@ -218,7 +228,6 @@ INCLUDE (ThirdPartyQT4)
INCLUDE (ThirdPartySMV)
INCLUDE (ThirdPartyOCE)
INCLUDE (ThirdPartyTetGen)
INCLUDE (ThirdPartyANN)
INCLUDE (ThirdPartyCCM)
INCLUDE (Doxygen)
......
########################################################################
#
# ThirdParty configuration for Nektar++
#
# libann partitioner
#
########################################################################
IF (NOT WIN32)
OPTION(NEKTAR_USE_ANN
"Use ANN routines for performing Approximate Nearest Neighbour searches." OFF)
ENDIF(NOT WIN32)
IF( NEKTAR_USE_MESHGEN )
SET(NEKTAR_USE_ANN ON CACHE BOOL "" FORCE)
ENDIF()
IF (NEKTAR_USE_ANN)
# First search for system ANN installs. Hint /opt/local for MacPorts and
# /usr/local/opt/ann for Homebrew.
FIND_LIBRARY(ANN_LIBRARY NAMES ANN
PATHS /opt/local/lib /usr/local/opt/ann/lib $ENV{ANN_ROOT}/lib)
FIND_PATH (ANN_INCLUDE_DIR ANN.h
PATHS /opt/local/include /usr/local/opt/ann/include $ENV{ANN_ROOT}/include
PATH_SUFFIXES ANN)
GET_FILENAME_COMPONENT(ANN_LIBRARY_PATH ${ANN_LIBRARY} PATH)
IF (ANN_LIBRARY AND ANN_INCLUDE_DIR)
SET(BUILD_ANN OFF)
ELSE()
SET(BUILD_ANN ON)
ENDIF ()
OPTION(THIRDPARTY_BUILD_ANN "Build ANN library from ThirdParty" ${BUILD_ANN})
IF (THIRDPARTY_BUILD_ANN)
# Note that ANN is compiled in the source-tree, so we unpack the
# source code in the ThirdParty builds directory.
SET(ANN_DIR ${TPBUILD}/ann-1.1.2)
SET(ANN_SRC ${ANN_DIR}/src)
IF (APPLE)
SET(ANN_CFLAGS "-O3 -fPIC")
SET(ANN_MAKELIB "libtool -static -o")
ELSE ()
SET(ANN_CFLAGS "-O3 -fPIC")
SET(ANN_MAKELIB "ar ruv")
ENDIF ()
INCLUDE(ExternalProject)
EXTERNALPROJECT_ADD(
ann-1.1.2
PREFIX ${TPSRC}
URL ${TPURL}/ann_1.1.2.tar.gz
URL_MD5 "9f99653b76798ecb1cfadc88950c4707"
STAMP_DIR ${TPBUILD}/stamp
DOWNLOAD_DIR ${TPSRC}
SOURCE_DIR ${TPBUILD}/ann-1.1.2
BINARY_DIR ${TPBUILD}/ann-1.1.2
TMP_DIR ${TPBUILD}/ann-1.1.2-tmp
INSTALL_DIR ${TPDIST}
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E remove -f ${ANN_DIR}/Makefile
BUILD_COMMAND cd src
COMMAND $(MAKE) -C ${ANN_SRC} targets
"ANNLIB = libANN.a"
"C++ = ${CMAKE_CXX_COMPILER}"
"CFLAGS = ${ANN_CFLAGS}"
"MAKELIB = ${ANN_MAKELIB}"
"RANLIB = true"
INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${TPDIST}/lib
COMMAND ${CMAKE_COMMAND} -E copy ${ANN_DIR}/lib/libANN.a
${TPDIST}/lib
COMMAND ${CMAKE_COMMAND} -E copy_directory ${ANN_DIR}/include
${TPDIST}/include
)
SET(ANN_LIBRARY ANN CACHE FILEPATH
"ANN library" FORCE)
SET(ANN_INCLUDE_DIR ${TPDIST}/include CACHE FILEPATH
"ANN include directory" FORCE)
LINK_DIRECTORIES(${TPDIST}/lib)
MESSAGE(STATUS "Build ANN: ${TPDIST}/lib/lib${ANN_LIBRARY}.a")
SET(ANN_CONFIG_INCLUDE_DIR ${TPINC})
ELSE (THIRDPARTY_BUILD_ANN)
ADD_CUSTOM_TARGET(ann-1.1.2 ALL)
MESSAGE(STATUS "Found ANN: ${ANN_LIBRARY}")
SET(ANN_CONFIG_INCLUDE_DIR ${ANN_INCLUDE_DIR})
ENDIF (THIRDPARTY_BUILD_ANN)
INCLUDE_DIRECTORIES(${ANN_INCLUDE_DIR})
MARK_AS_ADVANCED(ANN_LIBRARY)
MARK_AS_ADVANCED(ANN_INCLUDE_DIR)
ENDIF()
......@@ -30,16 +30,30 @@ IF (NEKTAR_USE_PETSC)
SET(PETSC_C_COMPILER "${CMAKE_C_COMPILER}")
SET(PETSC_CXX_COMPILER "${CMAKE_CXX_COMPILER}")
SET(PETSC_Fortran_COMPILER "${CMAKE_Fortran_COMPILER}")
IF (NEKTAR_USE_MPI)
IF (NOT MPI_BUILTIN)
SET(PETSC_C_COMPILER "${MPI_C_COMPILER}")
SET(PETSC_CXX_COMPILER "${MPI_CXX_COMPILER}")
SET(PETSC_Fortran_COMPILER "${MPI_Fortran_COMPILER}")
ENDIF (NOT MPI_BUILTIN)
ELSE (NEKTAR_USE_MPI)
SET(PETSC_NO_MPI "--with-mpi=0")
ENDIF (NEKTAR_USE_MPI)
IF(CMAKE_Fortran_COMPILER)
IF(NEKTAR_USE_MPI AND NOT MPI_Fortran_COMPILER)
MESSAGE(ERROR "MPI_Fortran_COMPILER not set")
ENDIF()
# we use a MUMPS build in ordering here, in the future it might make
# sense to hook it up with metis/scotch since this MIGHT be faster
SET(PETSC_MUMPS --download-scalapack --download-mumps)
ELSE()
MESSAGE(WARNING "No Fortran support. Building PETSc without MUMPS support")
SET(PETSC_Fortran_COMPILER "0")
ENDIF()
EXTERNALPROJECT_ADD(
petsc-3.7.2
PREFIX ${TPSRC}
......@@ -52,17 +66,21 @@ IF (NEKTAR_USE_PETSC)
URL http://www.nektar.info/thirdparty/petsc-lite-3.7.2.tar.gz
URL_MD5 "26c2ff8eaaa9e49aea063f839f5daa7e"
CONFIGURE_COMMAND
OMPI_FC=${CMAKE_Fortran_COMPILER}
OMPI_CC=${CMAKE_C_COMPILER}
OMPI_CXX=${CMAKE_CXX_COMPILER}
${PYTHON_EXECUTABLE} ./configure
./configure
--with-fc=${PETSC_Fortran_COMPILER}
--with-cc=${PETSC_C_COMPILER}
--with-cxx=${PETSC_CXX_COMPILER}
--with-shared-libraries=1
--with-pic=1
--with-x=0
--with-ssl=0
--prefix=${TPDIST}
--with-petsc-arch=c-opt
--with-fc=0
${PETSC_MUMPS}
${PETSC_NO_MPI}
BUILD_COMMAND MAKEFLAGS= make)
......
......@@ -632,6 +632,20 @@ match the interior domain:
This module should be added to the module chain for any complex if the user
suspects there may be a mesh issue. The module will print a warning if there is.
\subsection{2D mesh extrusion}
This module allows a 2D mesh, quads, triangles or both, to be extruded in the
$z$ direction to make a simple 3D mesh made of prisms and hexahedra. It is also
capable of extruding the high-order curvature within the 2D mesh. The module
requires two parameters:
\begin{lstlisting}[style=BashInputStyle]
NekMesh -m extrude:layers=n:length=l 2D.xml 3D.xml
\end{lstlisting}
length which determines how long the $z$ extrusion will be and layers, the
number of elements in the $z$ direction.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......
......@@ -90,7 +90,7 @@ void ProcessInterpField::Process(po::variables_map &vm)
std::vector<std::string> files;
// set up session file for from field
files.push_back(m_config["fromxml"].as<string>());
ParseUtils::GenerateOrderedStringVector(m_config["fromxml"].as<string>().c_str(), files);
m_fromField->m_session =
LibUtilities::SessionReader::CreateInstance(0, 0, files);
......
......@@ -445,8 +445,8 @@ void ProcessInterpPoints::Process(po::variables_map &vm)
FieldSharedPtr fromField = boost::shared_ptr<Field>(new Field());
std::vector<std::string> files;
ParseUtils::GenerateOrderedStringVector(m_config["fromxml"].as<string>().c_str(), files);
// set up session file for from field
files.push_back(m_config["fromxml"].as<string>());
fromField->m_session =
LibUtilities::SessionReader::CreateInstance(0, 0, files);
......
......@@ -39,186 +39,197 @@
#include "../Module.h"
#include "ProcessEquiSpacedOutput.h"
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/index/rtree.hpp>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
namespace Nektar
{
namespace FieldUtils
{
const NekDouble SQ_PNT_TOL=1e-6;
class Iso
{
public:
void condense(void);
void globalcondense(vector<boost::shared_ptr<Iso> > &iso, bool verbose);
void separate_regions(vector<boost::shared_ptr<Iso> > &iso,
int minsize,
bool verbose);
void smooth(int n_iter, NekDouble lambda, NekDouble mu);
int get_nvert(void)
{
return m_nvert;
}
void set_nvert(int n)
{
m_nvert = n;
}
int get_ntris(void)
{
return m_ntris;
}
void set_ntris(int n)
{
m_ntris = n;
}
void set_fields(const int loc,
const Array<OneD, Array<OneD, NekDouble> > &intfields,
const int j)
{
m_x[loc] = intfields[0][j];
m_y[loc] = intfields[1][j];
m_z[loc] = intfields[2][j];
for (int i = 0; i < intfields.num_elements() - 3; ++i)
public:
void Condense(void);
void GlobalCondense(vector<boost::shared_ptr<Iso> > &iso, bool verbose);
void SeparateRegions(vector<boost::shared_ptr<Iso> > &iso, int minsize, bool verbose);
void Smooth(int n_iter, NekDouble lambda, NekDouble mu);
int GetNVert(void)
{
m_fields[i][loc] = intfields[i + 3][j];
return m_nvert;
}
}
NekDouble get_fields(const int i, const int j)
{
return m_fields[i][j];
}
void set_x(int loc, NekDouble val)
{
m_x[loc] = val;
}
void set_y(int loc, NekDouble val)
{
m_y[loc] = val;
}
void set_z(int loc, NekDouble val)
{
m_z[loc] = val;
}
NekDouble get_x(int loc)
{
return m_x[loc];
}
NekDouble get_y(int loc)
{
return m_y[loc];
}
NekDouble get_z(int loc)
{
return m_z[loc];
}
int get_vid(int i)
{
return m_vid[i];
}
void resize_vid(int nconn)
{
m_vid = Array<OneD, int>(nconn);
}
void set_vid(int i, int j)
{
m_vid[i] = j;
}
void resize_fields(int size)
{
if (size > m_x.size()) // add 1000 element to vectors
void SetNVert(int n)
{
m_x.resize(size + 100);
m_y.resize(size + 100);
m_z.resize(size + 100);
;
for (int i = 0; i < m_fields.size(); ++i)
m_nvert = n;
}
int GetNTris(void)
{
return m_ntris;
}
void SetNTris(int n)
{
m_ntris = n;
}
void SetFields(const int loc,
const Array<OneD,Array<OneD, NekDouble> > &intfields,
const int j)
{
m_x[loc] = intfields[0][j];
m_y[loc] = intfields[1][j];
m_z[loc] = intfields[2][j];
for(int i = 0; i < intfields.num_elements()-3; ++i)
{
m_fields[i].resize(size + 1000);
m_fields[i][loc] = intfields[i+3][j];
}
}
m_nvert = size;
}
Iso(int nfields)
{
m_condensed = false;
m_nvert = 0;
m_fields.resize(nfields);
// set up initial vectors to be 10000 long
m_x.resize(10000);
m_y.resize(10000);
m_z.resize(10000);
for (int i = 0; i < m_fields.size(); ++i)
NekDouble GetFields(const int i, const int j)
{
return m_fields[i][j];
}
void SetX(int loc, NekDouble val)
{
m_fields[i].resize(10000);
m_x[loc] = val;
}
};
~Iso(void)
{
}
private:
bool m_condensed;
int m_nvert; // number of vertices
int m_ntris; // number of triangles introduced.
vector<NekDouble> m_x;
vector<NekDouble> m_y;
vector<NekDouble> m_z;
vector<vector<NekDouble> > m_fields;
Array<OneD, int> m_vid; // used when condensing field
void SetY(int loc, NekDouble val)
{
m_y[loc] = val;
}
void SetZ(int loc, NekDouble val)
{
m_z[loc] = val;
}
NekDouble GetX(int loc)
{
return m_x[loc];
}
NekDouble GetY(int loc)
{
return m_y[loc];
}
NekDouble GetZ(int loc)
{
return m_z[loc];
}
int GetVId(int i)
{
return m_vid[i];
}
void ResizeVId(int nconn)
{
m_vid = Array<OneD, int>(nconn);
}
void SetVId(int i, int j)
{
m_vid[i] = j;
}
void ResizeFields(int size)
{
if(size > m_x.size()) // add 1000 element to vectors
{
m_x.resize(size+100);
m_y.resize(size+100);
m_z.resize(size+100);;
for(int i = 0; i < m_fields.size(); ++i)
{
m_fields[i].resize(size+1000);
}
}
m_nvert = size;
}
Iso(int nfields)
{
m_condensed = false;
m_nvert = 0;
m_fields.resize(nfields);
// set up initial vectors to be 10000 long
m_x.resize(10000);
m_y.resize(10000);
m_z.resize(10000);
for(int i = 0; i < m_fields.size(); ++i)
{
m_fields[i].resize(10000);
}
};
~Iso(void)
{
}
private:
bool m_condensed;
int m_nvert; // number of vertices
int m_ntris; // number of triangles introduced.
vector<NekDouble> m_x;
vector<NekDouble> m_y;
vector<NekDouble> m_z;
vector<vector<NekDouble> > m_fields;
Array<OneD, int> m_vid; // used when condensing field
};
typedef boost::shared_ptr<Iso> IsoSharedPtr;
class IsoVertex
{
public:
friend class Iso;
IsoVertex(void)
{
m_id = -1;
m_x = m_y = m_z = -99999;
}
~IsoVertex(){};
int get_iso_id()
{
return m_iso_id;
}
int get_iso_vert_id()
{
return m_iso_vert_id;
}
friend bool operator==(const IsoVertex &x, const IsoVertex &y);
friend bool operator!=(const IsoVertex &x, const IsoVertex &y);
private:
int m_id;
int m_iso_id;
int m_iso_vert_id;
NekDouble m_x, m_y, m_z;
vector<NekDouble> m_fields;
public:
friend class Iso;
IsoVertex (void)
{
m_id = -1;
m_x = m_y = m_z = -99999;
}
~IsoVertex(){};
int get_iso_id()
{
return m_iso_id;
}
int get_iso_vert_id()
{
return m_iso_vert_id;
}
friend bool operator == (const IsoVertex& x, const IsoVertex& y);
friend bool operator != (const IsoVertex& x, const IsoVertex& y);
private:
int m_id;
int m_iso_id;
int m_iso_vert_id;
NekDouble m_x, m_y, m_z;
vector<NekDouble > m_fields;
};
/**
......@@ -226,33 +237,32 @@ private:
*/
class ProcessIsoContour : public ProcessEquiSpacedOutput
{
public:
/// Creates an instance of this class
static boost::shared_ptr<Module> create(FieldSharedPtr f)
{
return MemoryManager<ProcessIsoContour>::AllocateSharedPtr(f);
}
static ModuleKey className;
ProcessIsoContour(FieldSharedPtr f);
virtual ~ProcessIsoContour();
/// Write mesh to output file.
virtual void Process(po::variables_map &vm);
virtual std::string GetModuleName()
{
return "ProcessIsoContour";
}
protected:
ProcessIsoContour(){};
void ResetFieldPts(vector<IsoSharedPtr> &iso);
void SetupIsoFromFieldPts(vector<IsoSharedPtr> &isovec);
private:
vector<IsoSharedPtr> ExtractContour(const int fieldid, const NekDouble val);
public:
/// Creates an instance of this class
static boost::shared_ptr<Module> create(FieldSharedPtr f)
{
return MemoryManager<ProcessIsoContour>::AllocateSharedPtr(f);
}
static ModuleKey className;
ProcessIsoContour(FieldSharedPtr f);
virtual ~ProcessIsoContour();
/// Write mesh to output file.
virtual void Process(po::variables_map &vm);
protected:
ProcessIsoContour(){};
void ResetFieldPts(vector<IsoSharedPtr> &iso);
void SetupIsoFromFieldPts(vector<IsoSharedPtr> &isovec);
private:
vector<IsoSharedPtr> ExtractContour(
const int fieldid,
const NekDouble val);
};
}
}
......
......@@ -85,6 +85,7 @@ enum FieldIOType {
eHDF5
};
/**
* @brief Determine file type of given input file.
*
......@@ -234,7 +235,8 @@ FieldIOSharedPtr FieldIO::CreateForFile(
void Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap)
const FieldMetaDataMap &fieldinfomap,
const bool backup)
{
#ifdef NEKTAR_USE_MPI
int size;
......@@ -256,7 +258,7 @@ void Write(const std::string &outFile,
#endif
CommSharedPtr c = GetCommFactory().CreateInstance("Serial", 0, 0);
FieldIOSharedPtr f = GetFieldIOFactory().CreateInstance("Xml", c, false);
f->Write(outFile, fielddefs, fielddata, fieldinfomap);
f->Write(outFile, fielddefs, fielddata, fieldinfomap