Commit 5aa2c58b authored by Dave Moxey's avatar Dave Moxey
Browse files

Merge branch 'feature/ann_remove' into 'master'

Feature/ann_remove

Removes the dependency on the external library in favor of using boost::geometry. This may be noticeable slower in tree construction but has many more features and doesnt require another third party dependency, meaning that the massive speed up to the spherigon and isocontour routines can be provided in the default versions. 

The new version of the mesh generation routines dont require ann either.

See merge request !703
parents e52b1536 6676be85
......@@ -67,6 +67,7 @@ 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)
**FieldConvert:**
- Move all modules to a new library, FieldUtils, to support post-processing
......
......@@ -218,7 +218,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()
......@@ -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);
};
}
}
......
......@@ -66,26 +66,37 @@ using namespace std;
* calling this routine. Ideally, this should be called only when the
* percentage is increased by an integer.
*/
inline void PrintProgressbar(const int position, const int goal, const string message)
inline int PrintProgressbar(const int position, const int goal, const string message,
int lastprogress = -1)
{
std::cout.unsetf ( std::ios::floatfield );
if (ISTTY)
{
// carriage return
cout << "\r";
cout << message << ": ";
float progress = position / float(goal);
cout << setw(3) << ceil(100 * progress) << "% [";
for (int j = 0; j < ceil(progress * 49); j++)
int numeq = ceil(progress *49);
if(lastprogress == numeq)
{
cout << "=";
return numeq;
}
for (int j = ceil(progress * 49); j < 49; j++)
else
{
cout << " ";
// carriage return
cout << "\r";
cout << message << ": ";
cout << setw(3) << ceil(100 * progress) << "% [";
for (int j = 0; j < numeq; j++)
{
cout << "=";
}
for (int j = numeq; j < 49; j++)
{
cout << " ";
}
cout << "]" << flush;
return numeq;
}
cout << "]" << flush;
}
else
{
......@@ -94,6 +105,7 @@ inline void PrintProgressbar(const int position, const int goal, const string me
{
cout << "." << flush;
}
return -1;
}
}
......
......@@ -37,7 +37,7 @@
#include <NekMeshUtils/BLMeshing/BLMesh.h>
#include <NekMeshUtils/CADSystem/CADSurf.h>
#include <ANN/ANN.h>
//#include <ANN/ANN.h>