You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							343 lines
						
					
					
						
							13 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							343 lines
						
					
					
						
							13 KiB
						
					
					
				
								/* -*- c++ -*- (enables emacs c++ mode) */
							 | 
						|
								/*===========================================================================
							 | 
						|
								 
							 | 
						|
								 Copyright (C) 2002-2012 Yves Renard
							 | 
						|
								 
							 | 
						|
								 This file is a part of GETFEM++
							 | 
						|
								 
							 | 
						|
								 Getfem++  is  free software;  you  can  redistribute  it  and/or modify it
							 | 
						|
								 under  the  terms  of the  GNU  Lesser General Public License as published
							 | 
						|
								 by  the  Free Software Foundation;  either version 3 of the License,  or
							 | 
						|
								 (at your option) any later version along with the GCC Runtime Library
							 | 
						|
								 Exception either version 3.1 or (at your option) any later version.
							 | 
						|
								 This program  is  distributed  in  the  hope  that it will be useful,  but
							 | 
						|
								 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
							 | 
						|
								 or  FITNESS  FOR  A PARTICULAR PURPOSE.  See the GNU Lesser General Public
							 | 
						|
								 License and GCC Runtime Library Exception for more details.
							 | 
						|
								 You  should  have received a copy of the GNU Lesser General Public License
							 | 
						|
								 along  with  this program;  if not, write to the Free Software Foundation,
							 | 
						|
								 Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
							 | 
						|
								 
							 | 
						|
								 As a special exception, you  may use  this file  as it is a part of a free
							 | 
						|
								 software  library  without  restriction.  Specifically,  if   other  files
							 | 
						|
								 instantiate  templates  or  use macros or inline functions from this file,
							 | 
						|
								 or  you compile this  file  and  link  it  with other files  to produce an
							 | 
						|
								 executable, this file  does  not  by itself cause the resulting executable
							 | 
						|
								 to be covered  by the GNU Lesser General Public License.  This   exception
							 | 
						|
								 does not  however  invalidate  any  other  reasons why the executable file
							 | 
						|
								 might be covered by the GNU Lesser General Public License.
							 | 
						|
								 
							 | 
						|
								===========================================================================*/
							 | 
						|
								
							 | 
						|
								/** @file gmm_except.h 
							 | 
						|
								    @author Yves Renard <Yves.Renard@insa-lyon.fr>
							 | 
						|
								    @author Julien Pommier <Julien.Pommier@insa-toulouse.fr>
							 | 
						|
								    @date September 01, 2002.
							 | 
						|
								    @brief Definition of basic exceptions.
							 | 
						|
								*/
							 | 
						|
								
							 | 
						|
								#ifndef GMM_EXCEPT_H__
							 | 
						|
								#define GMM_EXCEPT_H__
							 | 
						|
								
							 | 
						|
								#include "gmm_std.h"
							 | 
						|
								
							 | 
						|
								namespace gmm {
							 | 
						|
								
							 | 
						|
								/* *********************************************************************** */
							 | 
						|
								/*	Getfem++ generic errors.                     			   */
							 | 
						|
								/* *********************************************************************** */
							 | 
						|
								
							 | 
						|
								  class gmm_error: public std::logic_error {
							 | 
						|
								  public:
							 | 
						|
								    gmm_error(const std::string& what_arg): std::logic_error (what_arg) {}
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								#ifdef GETFEM_HAVE_PRETTY_FUNCTION
							 | 
						|
								#  define GMM_PRETTY_FUNCTION __PRETTY_FUNCTION__
							 | 
						|
								#else 
							 | 
						|
								#  define GMM_PRETTY_FUNCTION ""
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  // Errors : GMM_THROW should not be used on its own.
							 | 
						|
								  //          GMM_ASSERT1 : Non-maskable errors. Typically for in/ouput and
							 | 
						|
								  //               when the test do not significantly reduces the performance.
							 | 
						|
								  //          GMM_ASSERT2 : All tests which are potentially performance
							 | 
						|
								  //               consuming. Not hidden by default. Hidden when NDEBUG is
							 | 
						|
								  //               defined.
							 | 
						|
								  //          GMM_ASSERT3 : For internal checks. Hidden by default. Active
							 | 
						|
								  //               only when DEBUG_MODE is defined.
							 | 
						|
								// __EXCEPTIONS is defined by gcc, _CPPUNWIND is defined by visual c++
							 | 
						|
								#if defined(__EXCEPTIONS) || defined(_CPPUNWIND)
							 | 
						|
								  inline void short_error_throw(const char *file, int line, const char *func,
							 | 
						|
												const char *errormsg) {
							 | 
						|
								    std::stringstream msg;
							 | 
						|
								    msg << "Error in " << file << ", line " << line << " " << func
							 | 
						|
									<< ": \n" << errormsg << std::ends;
							 | 
						|
								    throw gmm::gmm_error(msg.str());	
							 | 
						|
								  }
							 | 
						|
								# define GMM_THROW_(type, errormsg) {					\
							 | 
						|
								    std::stringstream msg;						\
							 | 
						|
								    msg << "Error in " << __FILE__ << ", line "				\
							 | 
						|
									<< __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n"		\
							 | 
						|
									<< errormsg << std::ends;						\
							 | 
						|
								    throw (type)(msg.str());						\
							 | 
						|
								  }
							 | 
						|
								#else
							 | 
						|
								#ifndef _MSC_VER
							 | 
						|
								# define abort_no_return() ::abort()
							 | 
						|
								#else
							 | 
						|
								// apparently ::abort() on windows is not declared with __declspec(noreturn) so the compiler spits a lot of warnings when abort is used.
							 | 
						|
								# define abort_no_return() { assert("GMM ABORT"==0); throw "GMM ABORT"; }
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  inline void short_error_throw(const char *file, int line, const char *func,
							 | 
						|
												const char *errormsg) {
							 | 
						|
								    std::stringstream msg;
							 | 
						|
								    msg << "Error in " << file << ", line " << line << " " << func
							 | 
						|
									<< ": \n" << errormsg << std::ends;
							 | 
						|
								    std::cerr << msg.str() << std::endl;
							 | 
						|
								    abort_no_return();	
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								# define GMM_THROW_(type, errormsg) {					\
							 | 
						|
								    std::stringstream msg;						\
							 | 
						|
								    msg << "Error in " << __FILE__ << ", line "				\
							 | 
						|
									<< __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n"		\
							 | 
						|
									<< errormsg;						\
							 | 
						|
								    std::cerr << msg.str() << std::endl;                                \
							 | 
						|
								    abort_no_return();							\
							 | 
						|
								  }
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								# define GMM_ASSERT1(test, errormsg)		        		\
							 | 
						|
								  { if (!(test)) GMM_THROW_(gmm::gmm_error, errormsg); }
							 | 
						|
								
							 | 
						|
								  // inline void GMM_THROW() IS_DEPRECATED;
							 | 
						|
								  inline void GMM_THROW() {}
							 | 
						|
								#define GMM_THROW(a, b) { GMM_THROW_(a,b); gmm::GMM_THROW(); }
							 | 
						|
								
							 | 
						|
								#if defined(NDEBUG)
							 | 
						|
								# define GMM_ASSERT2(test, errormsg) {}
							 | 
						|
								# define GMM_ASSERT3(test, errormsg) {}
							 | 
						|
								#elif !defined(GMM_FULL_NDEBUG)
							 | 
						|
								# define GMM_ASSERT2(test, errormsg)				        \
							 | 
						|
								  { if (!(test)) gmm::short_error_throw(__FILE__, __LINE__,		\
							 | 
						|
												   GMM_PRETTY_FUNCTION, errormsg); }
							 | 
						|
								# define GMM_ASSERT3(test, errormsg)				        \
							 | 
						|
								  { if (!(test)) gmm::short_error_throw(__FILE__, __LINE__,		\
							 | 
						|
												   GMM_PRETTY_FUNCTION, errormsg); }
							 | 
						|
								#else
							 | 
						|
								# define GMM_ASSERT2(test, errormsg)          				\
							 | 
						|
								  { if (!(test)) gmm::short_error_throw(__FILE__, __LINE__,		\
							 | 
						|
												   GMM_PRETTY_FUNCTION, errormsg); }
							 | 
						|
								# define GMM_ASSERT3(test, errormsg)
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								/* *********************************************************************** */
							 | 
						|
								/*	Getfem++ warnings.                         			   */
							 | 
						|
								/* *********************************************************************** */
							 | 
						|
								
							 | 
						|
								  // This allows to dynamically hide warnings
							 | 
						|
								  struct warning_level {
							 | 
						|
								    static int level(int l = -2)
							 | 
						|
								    { static int level_ = 3; return (l != -2) ? (level_ = l) : level_; }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  inline void set_warning_level(int l) { warning_level::level(std::max(0,l)); }
							 | 
						|
								  inline int  get_warning_level(void)  { return warning_level::level(-2); }
							 | 
						|
								
							 | 
						|
								  // This allow not too compile some Warnings
							 | 
						|
								#ifndef GMM_WARNING_LEVEL
							 | 
						|
								# define GMM_WARNING_LEVEL 4
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  // Warning levels : 0 always printed
							 | 
						|
								  //                  1 very important : specify a possible error in the code.
							 | 
						|
								  //                  2 important : specify a default of optimization for inst.
							 | 
						|
								  //                  3 remark
							 | 
						|
								  //                  4 ignored by default.
							 | 
						|
								
							 | 
						|
								#define GMM_WARNING_MSG(level_, thestr)  {			       \
							 | 
						|
								      std::stringstream msg;                                           \
							 | 
						|
								      msg << "Level " << level_ << " Warning in " << __FILE__ << ", line " \
							 | 
						|
								          << __LINE__ << ": " << thestr;		       \
							 | 
						|
								       std::cerr << msg.str() << std::endl;                            \
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								#define GMM_WARNING0(thestr) GMM_WARNING_MSG(0, thestr)
							 | 
						|
								
							 | 
						|
								#if GMM_WARNING_LEVEL > 0
							 | 
						|
								# define GMM_WARNING1(thestr)                                           \
							 | 
						|
								  { if (1 <= gmm::warning_level::level()) GMM_WARNING_MSG(1, thestr) }
							 | 
						|
								#else
							 | 
						|
								# define GMM_WARNING1(thestr) {}
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								#if GMM_WARNING_LEVEL > 1
							 | 
						|
								# define GMM_WARNING2(thestr)                                           \
							 | 
						|
								  { if (2 <= gmm::warning_level::level()) GMM_WARNING_MSG(2, thestr) } 
							 | 
						|
								#else
							 | 
						|
								# define GMM_WARNING1(thestr) {}
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								#if GMM_WARNING_LEVEL > 2
							 | 
						|
								# define GMM_WARNING3(thestr)                                           \
							 | 
						|
								  { if (3 <= gmm::warning_level::level()) GMM_WARNING_MSG(3, thestr) } 
							 | 
						|
								#else
							 | 
						|
								# define GMM_WARNING1(thestr) {}
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								#if GMM_WARNING_LEVEL > 3
							 | 
						|
								# define GMM_WARNING4(thestr)                                           \
							 | 
						|
								  { if (4 <= gmm::warning_level::level()) GMM_WARNING_MSG(4, thestr) } 
							 | 
						|
								#else
							 | 
						|
								# define GMM_WARNING1(thestr) {}
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								/* *********************************************************************** */
							 | 
						|
								/*	Getfem++ traces.                         			   */
							 | 
						|
								/* *********************************************************************** */
							 | 
						|
								
							 | 
						|
								  // This allows to dynamically hide traces
							 | 
						|
								  struct traces_level {
							 | 
						|
								    static int level(int l = -2)
							 | 
						|
								    { static int level_ = 3; return (l != -2) ? (level_ = l) : level_; }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  inline void set_traces_level(int l) { traces_level::level(std::max(0,l)); }
							 | 
						|
								
							 | 
						|
								  // This allow not too compile some Warnings
							 | 
						|
								#ifndef GMM_TRACES_LEVEL
							 | 
						|
								# define GMM_TRACES_LEVEL 3
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  // Traces levels : 0 always printed
							 | 
						|
								  //                 1 Susceptible to occur once in a program.
							 | 
						|
								  //                 2 Susceptible to occur occasionnaly in a program (10).
							 | 
						|
								  //                 3 Susceptible to occur often (100).
							 | 
						|
								  //                 4 Susceptible to occur very often (>1000).
							 | 
						|
								
							 | 
						|
								#define GMM_TRACE_MSG_MPI     // for Parallelized version
							 | 
						|
								#define GMM_TRACE_MSG(level_, thestr)  {			       \
							 | 
						|
								    GMM_TRACE_MSG_MPI {						       \
							 | 
						|
								      std::stringstream msg;                                           \
							 | 
						|
								      msg << "Trace " << level_ << " in " << __FILE__ << ", line "     \
							 | 
						|
								          << __LINE__ << ": " << thestr;        		       \
							 | 
						|
								      std::cout << msg.str() << std::endl;			       \
							 | 
						|
								    }                                                                  \
							 | 
						|
								  }        
							 | 
						|
								
							 | 
						|
								#define GMM_TRACE0(thestr) GMM_TRACE_MSG(0, thestr)
							 | 
						|
								
							 | 
						|
								#if GMM_TRACES_LEVEL > 0
							 | 
						|
								# define GMM_TRACE1(thestr)						\
							 | 
						|
								  { if (1 <= gmm::traces_level::level()) GMM_TRACE_MSG(1, thestr) }
							 | 
						|
								#else
							 | 
						|
								# define GMM_TRACE1(thestr) {}
							 | 
						|
								#endif
							 | 
						|
								  
							 | 
						|
								#if GMM_TRACES_LEVEL > 1
							 | 
						|
								# define GMM_TRACE2(thestr)						\
							 | 
						|
								  { if (2 <= gmm::traces_level::level()) GMM_TRACE_MSG(2, thestr) } 
							 | 
						|
								#else
							 | 
						|
								# define GMM_TRACE2(thestr) {}
							 | 
						|
								#endif
							 | 
						|
								  
							 | 
						|
								#if GMM_TRACES_LEVEL > 2
							 | 
						|
								# define GMM_TRACE3(thestr)						\
							 | 
						|
								  { if (3 <= gmm::traces_level::level()) GMM_TRACE_MSG(3, thestr) } 
							 | 
						|
								#else
							 | 
						|
								# define GMM_TRACE3(thestr) {}
							 | 
						|
								#endif
							 | 
						|
								  
							 | 
						|
								#if GMM_TRACES_LEVEL > 3
							 | 
						|
								# define GMM_TRACE4(thestr)						\
							 | 
						|
								  { if (4 <= gmm::traces_level::level()) GMM_TRACE_MSG(4, thestr) } 
							 | 
						|
								#else
							 | 
						|
								# define GMM_TRACE4(thestr) {}
							 | 
						|
								#endif
							 | 
						|
								  
							 | 
						|
								  
							 | 
						|
								  /* ********************************************************************* */
							 | 
						|
								  /*    Definitions for compatibility with old versions.        	   */
							 | 
						|
								  /* ********************************************************************* */ 
							 | 
						|
								  
							 | 
						|
								  using std::invalid_argument;
							 | 
						|
								  
							 | 
						|
								  struct dimension_error : public std::logic_error
							 | 
						|
								  { dimension_error(const std::string& w): std::logic_error(w) {} };
							 | 
						|
								  struct file_not_found_error : public std::logic_error
							 | 
						|
								  { file_not_found_error(const std::string& w): std::logic_error (w) {} };
							 | 
						|
								  struct internal_error : public std::logic_error
							 | 
						|
								  { internal_error(const std::string& w): std::logic_error(w) {} };
							 | 
						|
								  struct failure_error : public std::logic_error
							 | 
						|
								  { failure_error(const std::string& w): std::logic_error (w) {} };
							 | 
						|
								  struct not_linear_error : public std::logic_error
							 | 
						|
								  { not_linear_error(const std::string& w): std::logic_error (w) {} };
							 | 
						|
								  struct to_be_done_error : public std::logic_error
							 | 
						|
								  { to_be_done_error(const std::string& w): std::logic_error (w) {} };
							 | 
						|
								
							 | 
						|
								#define GMM_STANDARD_CATCH_ERROR   catch(std::logic_error e)	\
							 | 
						|
								    {								\
							 | 
						|
								      std::cerr << "============================================\n";	\
							 | 
						|
								      std::cerr << "|      An error has been detected !!!      |\n";	\
							 | 
						|
								      std::cerr << "============================================\n";	\
							 | 
						|
								      std::cerr << e.what() << std::endl << std::endl;				\
							 | 
						|
								      exit(1);							\
							 | 
						|
								    }								\
							 | 
						|
								  catch(std::runtime_error e)					\
							 | 
						|
								    {								\
							 | 
						|
								      std::cerr << "============================================\n";	\
							 | 
						|
								      std::cerr << "|      An error has been detected !!!      |\n";	\
							 | 
						|
								      std::cerr << "============================================\n";	\
							 | 
						|
								      std::cerr << e.what() << std::endl << std::endl;				\
							 | 
						|
								      exit(1);							\
							 | 
						|
								    }								\
							 | 
						|
								  catch(std::bad_alloc) {					\
							 | 
						|
								    std::cerr << "============================================\n";	\
							 | 
						|
								    std::cerr << "|  A bad allocation has been detected !!!  |\n";	\
							 | 
						|
								    std::cerr << "============================================\n";	\
							 | 
						|
								    exit(1);							\
							 | 
						|
								  }								\
							 | 
						|
								  catch(std::bad_typeid) {					\
							 | 
						|
								    std::cerr << "============================================\n";	\
							 | 
						|
								    std::cerr << "|  A bad typeid     has been detected !!!  |\n";	\
							 | 
						|
								    std::cerr << "============================================\n";	\
							 | 
						|
								    exit(1);							\
							 | 
						|
								  }								\
							 | 
						|
								  catch(std::bad_exception) {					\
							 | 
						|
								    std::cerr << "============================================\n";	\
							 | 
						|
								    std::cerr << "|  A bad exception  has been detected !!!  |\n";	\
							 | 
						|
								    std::cerr << "============================================\n";	\
							 | 
						|
								    exit(1);							\
							 | 
						|
								  }								\
							 | 
						|
								  catch(std::bad_cast) {					\
							 | 
						|
								    std::cerr << "============================================\n";	\
							 | 
						|
								    std::cerr << "|    A bad cast  has been detected !!!     |\n";	\
							 | 
						|
								    std::cerr << "============================================\n";	\
							 | 
						|
								    exit(1);							\
							 | 
						|
								  }								\
							 | 
						|
								  catch(...) {							\
							 | 
						|
								    std::cerr << "============================================\n";	\
							 | 
						|
								    std::cerr << "|  An unknown error has been detected !!!  |\n";	\
							 | 
						|
								    std::cerr << "============================================\n";	\
							 | 
						|
								    exit(1);							\
							 | 
						|
								  }
							 | 
						|
								  //   catch(ios_base::failure) { 
							 | 
						|
								  //     std::cerr << "============================================\n";
							 | 
						|
								  //     std::cerr << "| A ios_base::failure has been detected !!!|\n";
							 | 
						|
								  //     std::cerr << "============================================\n";
							 | 
						|
								  //     exit(1);
							 | 
						|
								  //   } 
							 | 
						|
								
							 | 
						|
								#if defined(__GNUC__) && (__GNUC__ > 3)
							 | 
						|
								# define GMM_SET_EXCEPTION_DEBUG				\
							 | 
						|
								  std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
							 | 
						|
								#else
							 | 
						|
								# define GMM_SET_EXCEPTION_DEBUG
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								#endif /* GMM_EXCEPT_H__ */
							 |