Commit 0fe0983b authored by Michael Turner's avatar Michael Turner
Browse files

try catch in mcf input, also remove duplicate error messaging

parent bf40c447
......@@ -35,11 +35,11 @@
#ifndef ERRORUTIL_HPP
#define ERRORUTIL_HPP
#include <iostream>
#include <stdexcept>
#include <LibUtilities/LibUtilitiesDeclspec.h>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
#include <LibUtilities/LibUtilitiesDeclspec.h>
#include <iostream>
#include <stdexcept>
#if defined(NEKTAR_USE_MPI)
#include <mpi.h>
......@@ -51,97 +51,101 @@
namespace ErrorUtil
{
static boost::optional<std::ostream&> outStream;
static boost::optional<std::ostream &> outStream;
inline static void SetErrorStream(std::ostream& o)
{
outStream = o;
}
inline static bool HasCustomErrorStream()
{
return outStream ? true : false;
}
inline static void SetErrorStream(std::ostream &o)
{
outStream = o;
}
enum ErrType
{
efatal,
ewarning
};
inline static bool HasCustomErrorStream()
{
return outStream ? true : false;
}
class NekError : public std::runtime_error
{
public:
NekError(const std::string& message) : std::runtime_error(message) {}
};
inline static void Error(ErrType type, const char *routine, int lineNumber, const char *msg, unsigned int level, bool DoComm = false)
enum ErrType
{
efatal,
ewarning
};
class NekError : public std::runtime_error
{
public:
NekError(const std::string &message) : std::runtime_error(message)
{
// The user of outStream is primarily for the unit tests.
// The unit tests often generate errors on purpose to make sure
// invalid usage is flagged appropriately. Printing the error
// messages to cerr made the unit test output hard to parse.
std::string baseMsg = std::string("Level ") +
boost::lexical_cast<std::string>(level) +
std::string(" assertion violation\n") +
}
};
inline static void Error(ErrType type, const char *routine, int lineNumber,
const char *msg, unsigned int level,
bool DoComm = false)
{
// The user of outStream is primarily for the unit tests.
// The unit tests often generate errors on purpose to make sure
// invalid usage is flagged appropriately. Printing the error
// messages to cerr made the unit test output hard to parse.
std::string baseMsg =
std::string("Level ") + boost::lexical_cast<std::string>(level) +
std::string(" assertion violation\n") +
#if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
std::string("Where : ") + boost::lexical_cast<std::string>(routine) + std::string("[") + boost::lexical_cast<std::string>(lineNumber) + std::string("]\n") + std::string("Message : ") +
std::string("Where : ") + boost::lexical_cast<std::string>(routine) +
std::string("[") + boost::lexical_cast<std::string>(lineNumber) +
std::string("]\n") + std::string("Message : ") +
#endif
msg;
msg;
// Default rank is zero. If MPI used and initialised, populate with
// the correct rank. Messages are only printed on rank zero.
int rank = 0;
// Default rank is zero. If MPI used and initialised, populate with
// the correct rank. Messages are only printed on rank zero.
int rank = 0;
#if defined(NEKTAR_USE_MPI)
int flag = 0;
if(DoComm)
int flag = 0;
if (DoComm)
{
MPI_Initialized(&flag);
if (flag)
{
MPI_Initialized(&flag);
if(flag)
{
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
}
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
}
}
#endif
std::string btMessage("");
std::string btMessage("");
#if defined(NEKTAR_FULLDEBUG)
#ifndef _WIN32
void *btArray[40];
int btSize;
char **btStrings;
void *btArray[40];
int btSize;
char **btStrings;
btSize = backtrace(btArray, 40);
btStrings = backtrace_symbols(btArray, btSize);
btSize = backtrace(btArray, 40);
btStrings = backtrace_symbols(btArray, btSize);
for (int i = 0 ; i < btSize ; ++i)
{
btMessage += std::string(btStrings[i]) + "\n";
}
free(btStrings);
for (int i = 0; i < btSize; ++i)
{
btMessage += std::string(btStrings[i]) + "\n";
}
free(btStrings);
#endif
#endif
switch (type)
{
switch (type)
{
case efatal:
if (!rank)
{
if (outStream)
{
(*outStream) << btMessage;
(*outStream) << "Fatal : " << baseMsg << std::endl;
}
else
{
std::cerr << btMessage;
std::cerr << std::endl << "Fatal : " << baseMsg
<< std::endl;
std::cerr << std::endl
<< "Fatal : " << baseMsg << std::endl;
}
}
#if defined(NEKTAR_USE_MPI)
if(DoComm)
if (DoComm)
{
if (flag)
{
......@@ -156,30 +160,30 @@ namespace ErrorUtil
{
if (outStream)
{
(*outStream) << btMessage;
(*outStream) << "Warning: " << baseMsg << std::endl;
}
else
{
std::cerr << btMessage;
std::cerr << "Warning: " << baseMsg << std::endl;
}
}
break;
default:
std::cerr << "Unknown warning type: " << baseMsg << std::endl;
}
}
}
inline static void Error(ErrType type, const char *routine, int lineNumber, const std::string& msg, unsigned int level)
{
Error(type, routine, lineNumber, msg.c_str(), level);
}
inline static void Error(ErrType type, const char *routine, int lineNumber,
const std::string &msg, unsigned int level)
{
Error(type, routine, lineNumber, msg.c_str(), level);
}
inline static void Error(ErrType type, const char *routine, int lineNumber, const char *msg)
{
Error(type, routine, lineNumber, msg, 0);
}
inline static void Error(ErrType type, const char *routine, int lineNumber,
const char *msg)
{
Error(type, routine, lineNumber, msg, 0);
}
} // end of namespace
/// Assert Level 0 -- Fundamental assert which
......@@ -188,68 +192,63 @@ namespace ErrorUtil
/// considered code critical, even under
/// optimized compilation.
#define NEKERROR(type, msg) \
ErrorUtil::Error(type, __FILE__, __LINE__, msg, 0);
#define NEKERROR(type, msg) ErrorUtil::Error(type, __FILE__, __LINE__, msg, 0);
#define ROOTONLY_NEKERROR(type, msg) \
ErrorUtil::Error(type, __FILE__, __LINE__, msg, 0,true);
#define ROOTONLY_NEKERROR(type, msg) \
ErrorUtil::Error(type, __FILE__, __LINE__, msg, 0, true);
#define ASSERTL0(condition,msg) \
if(!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 0); \
}
#define WARNINGL0(condition,msg) \
if(!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 0); \
}
#define ASSERTL0(condition, msg) \
if (!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 0); \
}
#define WARNINGL0(condition, msg) \
if (!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 0); \
}
/// Assert Level 1 -- Debugging which is used whether in FULLDEBUG or
/// DEBUG compilation mode. This level assert is designed for aiding
/// in standard debug (-g) mode
#if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
#define ASSERTL1(condition,msg) \
if(!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 1); \
}
#define WARNINGL1(condition,msg) \
if(!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 1); \
}
#else //defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
#define ASSERTL1(condition,msg)
#define WARNINGL1(condition,msg)
#endif //defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
#define ASSERTL1(condition, msg) \
if (!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 1); \
}
#define WARNINGL1(condition, msg) \
if (!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 1); \
}
#else // defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
#define ASSERTL1(condition, msg)
#define WARNINGL1(condition, msg)
#endif // defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
/// Assert Level 2 -- Debugging which is used FULLDEBUG compilation
/// mode. This level assert is designed to provide addition safety
/// checks within the code (such as bounds checking, etc.).
#ifdef NEKTAR_FULLDEBUG
#define ASSERTL2(condition,msg) \
if(!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 2); \
}
#define WARNINGL2(condition,msg) \
if(!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 2); \
}
#else //NEKTAR_FULLDEBUG
#define ASSERTL2(condition,msg)
#define WARNINGL2(condition,msg)
#endif //NEKTAR_FULLDEBUG
#define ASSERTL2(condition, msg) \
if (!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 2); \
}
#define WARNINGL2(condition, msg) \
if (!(condition)) \
{ \
ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 2); \
}
#endif //ERRORUTIL_HPP
#else // NEKTAR_FULLDEBUG
#define ASSERTL2(condition, msg)
#define WARNINGL2(condition, msg)
#endif // NEKTAR_FULLDEBUG
#endif // ERRORUTIL_HPP
......@@ -120,10 +120,10 @@ void InputMCF::ParseFile(string nm)
}
set<string> refinement;
if(pSession->DefinesElement("NEKTAR/MESHING/REFINEMENT"))
if (pSession->DefinesElement("NEKTAR/MESHING/REFINEMENT"))
{
TiXmlElement *refine = mcf->FirstChildElement("REFINEMENT");
TiXmlElement *L = refine->FirstChildElement("LINE");
TiXmlElement *L = refine->FirstChildElement("LINE");
while (L)
{
......@@ -151,7 +151,7 @@ void InputMCF::ParseFile(string nm)
}
}
map<string,string>::iterator it;
map<string, string>::iterator it;
it = information.find("CADFile");
ASSERTL0(it != information.end(), "no cadfile defined");
......@@ -160,18 +160,17 @@ void InputMCF::ParseFile(string nm)
it = information.find("MeshType");
ASSERTL0(it != information.end(), "no meshtype defined");
m_makeBL = it->second == "3DBndLayer";
m_2D = it->second == "2D";
m_2D = it->second == "2D";
if (it->second == "2DBndLayer")
{
m_makeBL = true;
m_2D = true;
m_2D = true;
}
if(!m_makeBL && !m_2D)
if (!m_makeBL && !m_2D)
{
ASSERTL0(it->second == "3D", "unsure on MeshType")
}
it = parameters.find("MinDelta");
ASSERTL0(it != parameters.end(), "no mindelta defined");
m_minDelta = it->second;
......@@ -198,18 +197,18 @@ void InputMCF::ParseFile(string nm)
ASSERTL0(it != parameters.end(), "no BndLayerthick defined");
m_blthick = it->second;
it = parameters.find("BndLayerLayers");
it = parameters.find("BndLayerLayers");
m_splitBL = it != parameters.end();
if(m_splitBL)
if (m_splitBL)
{
m_bllayers = it->second;
it = parameters.find("BndLayerProgression");
m_blprog = it != parameters.end() ? it->second : "2.0";
it = parameters.find("BndLayerProgression");
m_blprog = it != parameters.end() ? it->second : "2.0";
}
}
m_naca = false;
if(m_2D && m_cadfile.find('.') == std::string::npos)
if (m_2D && m_cadfile.find('.') == std::string::npos)
{
m_naca = true;
......@@ -242,16 +241,16 @@ void InputMCF::ParseFile(string nm)
m_varopti = sit != boolparameters.end();
m_refine = refinement.size() > 0;
if(m_refine)
if (m_refine)
{
stringstream ss;
for(sit = refinement.begin(); sit != refinement.end(); sit++)
for (sit = refinement.begin(); sit != refinement.end(); sit++)
{
ss << *sit;
ss << ":";
}
m_refinement = ss.str();
m_refinement.erase(m_refinement.end()-1);
m_refinement.erase(m_refinement.end() - 1);
}
}
......@@ -263,105 +262,205 @@ void InputMCF::Process()
m_mesh->m_spaceDim = 3;
m_mesh->m_nummode = boost::lexical_cast<int>(m_order) + 1;
vector<ModuleSharedPtr> mods;
ModuleSharedPtr module;
////**** CAD ****////
mods.push_back(GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "loadcad"), m_mesh));
mods.back()->RegisterConfig("filename", m_cadfile);
module = GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "loadcad"), m_mesh);
module->RegisterConfig("filename", m_cadfile);
if(m_2D)
if (m_2D)
{
mods.back()->RegisterConfig("2D","");
module->RegisterConfig("2D", "");
}
if(m_naca)
if (m_naca)
{
mods.back()->RegisterConfig("NACA",m_nacadomain);
module->RegisterConfig("NACA", m_nacadomain);
}
////**** Octree ****////
mods.push_back(GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "loadoctree"), m_mesh));
mods.back()->RegisterConfig("mindel", m_minDelta);
mods.back()->RegisterConfig("maxdel", m_maxDelta);
mods.back()->RegisterConfig("eps", m_eps);
module->SetDefaults();
module->Process();
////**** OCTREE ****////
module = GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "loadoctree"), m_mesh);
module->RegisterConfig("mindel", m_minDelta);
module->RegisterConfig("maxdel", m_maxDelta);
module->RegisterConfig("eps", m_eps);
if (m_refine)
{
mods.back()->RegisterConfig("refinement", m_refinement);
module->RegisterConfig("refinement", m_refinement);
}
if (m_woct)
{
mods.back()->RegisterConfig("writeoctree", "");
module->RegisterConfig("writeoctree", "");
}
if(m_2D)
module->SetDefaults();
module->Process();
////**** LINEAR MESHING ****////
if (m_2D)
{
m_mesh->m_expDim = 2;
m_mesh->m_expDim = 2;
m_mesh->m_spaceDim = 2;
mods.push_back(GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "2dgenerator"), m_mesh));
module = GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "2dgenerator"), m_mesh);
if (m_makeBL)
{
mods.back()->RegisterConfig("blcurves", m_blsurfs);
mods.back()->RegisterConfig("blthick", m_blthick);
module->RegisterConfig("blcurves", m_blsurfs);
module->RegisterConfig("blthick", m_blthick);
}
try
{
module->SetDefaults();
module->Process();
}
catch (runtime_error &e)
{
cout << "2D linear mesh generator failed with message:" << endl;
cout << e.what() << endl;
cout << "No mesh file has been created" << endl;
abort();
}
}
else
{
////**** SurfaceMesh ****////
mods.push_back(GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "surfacemesh"), m_mesh));
module = GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "surfacemesh"), m_mesh);
try
{
module->SetDefaults();
module->Process();
}
catch (runtime_error &e)
{
cout << "Surface meshing has failed with message:" << endl;
cout << e.what() << endl;
cout << "Any surfaces which were succsessfully meshed will be "
"dumped as a manifold mesh"
<< endl;
m_mesh->m_expDim = 2;
ProcessVertices();
ProcessEdges();
ProcessFaces();
ProcessElements();
ProcessComposites();
return;
}
////**** VolumeMesh ****////
mods.push_back(GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "volumemesh"), m_mesh));
if(m_makeBL)
module = GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "volumemesh"), m_mesh);
if (m_makeBL)
{
module->RegisterConfig("blsurfs", m_blsurfs);
module->RegisterConfig("blthick", m_blthick);
module->RegisterConfig("bllayers", m_bllayers);
module->RegisterConfig("blprog", m_blprog);
}
try
{
module->SetDefaults();
module->Process();
}
catch (runtime_error &e)
{
mods.back()->RegisterConfig("blsurfs",m_blsurfs);
mods.back()->RegisterConfig("blthick",m_blthick);
mods.back()->RegisterConfig("bllayers",m_bllayers);
mods.back()->RegisterConfig("blprog",m_blprog);
cout << "Volume meshing has failed with message:" << endl;
cout << e.what() << endl;
cout << "The linear surface mesh be dumped as a manifold mesh"
<< endl;
m_mesh->m_expDim = 2;
m_mesh->m_element[3].clear();
ProcessVertices();
ProcessEdges();
ProcessFaces();
ProcessElements();
ProcessComposites();
return;
}
}
////**** HOSurface ****////
mods.push_back(GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "hosurface"), m_mesh));
module = GetModuleFactory().CreateInstance(
ModuleKey(eProcessModule, "hosurface"), m_mesh);
if (m_surfopti)
{
mods.back()->RegisterConfig("opti", "");
module->RegisterConfig("opti", "");
}
try
{
module->SetDefaults();
module->Process();
}
catch (runtime_error &e)
{
cout << "High-order surface meshing has failed with message:" << endl;
cout << e.what() << endl;
cout << "The mesh will be written as normal but the incomplete surface "
"will remain faceted"
<< endl;
return;
}
////*** VARIATIONAL OPTIMISATION ****////
if(m_varopti)
if (m_varopti)
{
unsigned int np = boost::thread::physical_concurrency();
if(m_mesh->m_verbose)
if (m_mesh->m_verbose)
{